Skip to main content

TEEC_ReleaseSharedMemory

Function TEEC_ReleaseSharedMemory 

Source
#[unsafe(no_mangle)]
pub extern "C" fn TEEC_ReleaseSharedMemory( shm: *mut TEEC_SharedMemory, )
Expand description

TEEC_ReleaseSharedMemory() - 释放或取消注册共享内存。

@param sharedMem 要释放或取消注册的共享内存指针。

Examples found in repository?
examples/cc-teec.rs (line 283)
251fn memref_whole_input_output(session: &mut Client_Session) -> Result<()> {
252    let input_data = vec![1u8, 2, 3, 4, 5, 6, 7, 8];
253    let output_size = 8;
254
255    // 分配输入共享内存
256    let mut input_shm =
257        allocate_shared_memory(session.context_mut(), input_data.len(), raw::TEEC_MEM_INPUT)?;
258    copy_to_shm(&input_data, &input_shm);
259
260    // 分配输出共享内存
261    let mut output_shm =
262        allocate_shared_memory(session.context_mut(), output_size, raw::TEEC_MEM_OUTPUT)?;
263
264    // 创建操作:参数0为INPUT,参数1为OUTPUT
265    // SAFETY: `TEEC_Operation` 是 POD 类型,零初始化是有效的。
266    let mut op: raw::TEEC_Operation = unsafe { mem::zeroed() };
267    op.paramTypes = raw::TEEC_PARAM_TYPES(
268        raw::TEEC_MEMREF_WHOLE,
269        raw::TEEC_MEMREF_WHOLE,
270        raw::TEEC_NONE,
271        raw::TEEC_NONE,
272    );
273    op.params[0].memref.parent = &mut input_shm as *mut _;
274    op.params[0].memref.size = input_data.len();
275    op.params[1].memref.parent = &mut output_shm as *mut _;
276    op.params[1].memref.size = output_size;
277
278    session.invoke_command(Command::MemrefWholeInputOutput.into(), &mut op)?;
279
280    let output_data = read_from_shm(&output_shm, output_size);
281    println!("  WHOLE_INPUT+OUTPUT: {:?} → {:?}", input_data, output_data);
282
283    TEEC_ReleaseSharedMemory(&mut input_shm);
284    TEEC_ReleaseSharedMemory(&mut output_shm);
285
286    Ok(())
287}
288
289// MEMREF WHOLE INOUT 演示(使用 AllocateSharedMemory)
290fn memref_whole_inout_allocated(session: &mut Client_Session) -> Result<()> {
291    let mut data = vec![1u8, 2, 3, 4, 5, 6, 7, 8];
292    let original = data.clone();
293    let flags = raw::TEEC_MEM_INPUT | raw::TEEC_MEM_OUTPUT;
294    let mut shm = allocate_shared_memory(session.context_mut(), data.len(), flags)?;
295
296    copy_to_shm(&data, &shm);
297
298    let mut op = create_memref_operation(&mut shm, data.len());
299
300    session.invoke_command(Command::MemrefWholeInout.into(), &mut op)?;
301
302    copy_from_shm(&shm, &mut data);
303
304    println!("  WHOLE_INOUT (Alloc): {:?} → {:?}", original, data);
305
306    TEEC_ReleaseSharedMemory(&mut shm);
307
308    Ok(())
309}
310
311// MEMREF WHOLE INOUT 演示(使用 RegisterSharedMemory)
312fn memref_whole_inout_registered(session: &mut Client_Session) -> Result<()> {
313    let mut data = vec![1u8, 2, 3, 4, 5, 6, 7, 8];
314    let original = data.clone();
315    let flags = raw::TEEC_MEM_INPUT | raw::TEEC_MEM_OUTPUT;
316
317    // 注册栈上分配的缓冲区为共享内存
318    let mut shm = register_shared_memory(
319        session.context_mut(),
320        data.as_mut_ptr() as *mut c_void,
321        data.len(),
322        flags,
323    )?;
324
325    let mut op = create_memref_operation(&mut shm, data.len());
326    session.invoke_command(Command::MemrefWholeInout.into(), &mut op)?;
327
328    // RegisterSharedMemory 直接操作 CA 的栈内存,TA 修改后数据应自动可见
329    // 但通过 vsock-manager 通信时,数据经过序列化/反序列化,需要手动同步
330    copy_from_shm(&shm, &mut data);
331
332    println!("  WHOLE_INOUT (Register): {:?} → {:?}", original, data);
333
334    TEEC_ReleaseSharedMemory(&mut shm);
335
336    Ok(())
337}
338
339fn memref_whole(session: &mut Client_Session) -> Result<()> {
340    println!("\nMEMREF WHOLE 参数类型");
341    memref_whole_input_output(session)?;
342    memref_whole_inout_allocated(session)?;
343    memref_whole_inout_registered(session)?;
344    Ok(())
345}
346
347fn allocate_shared_memory(
348    ctx: &mut raw::TEEC_Context,
349    size: usize,
350    flags: u32,
351) -> Result<raw::TEEC_SharedMemory> {
352    // SAFETY: `TEEC_SharedMemory` 是 POD 类型,零初始化是有效的。
353    let mut shm: raw::TEEC_SharedMemory = unsafe { mem::zeroed() };
354    shm.size = size;
355    shm.flags = flags;
356
357    let res = TEEC_AllocateSharedMemory(ctx, &mut shm);
358    if res != raw::TEEC_SUCCESS {
359        return Err(Error::from_raw_os_error(res as i32));
360    }
361
362    Ok(shm)
363}
364
365// 注册已有的内存块为共享内存
366fn register_shared_memory(
367    ctx: &mut raw::TEEC_Context,
368    buffer: *mut c_void,
369    size: usize,
370    flags: u32,
371) -> Result<raw::TEEC_SharedMemory> {
372    // SAFETY: `TEEC_SharedMemory` 是 POD 类型,零初始化是有效的。
373    let mut shm: raw::TEEC_SharedMemory = unsafe { mem::zeroed() };
374    shm.buffer = buffer;
375    shm.size = size;
376    shm.flags = flags;
377
378    let res = TEEC_RegisterSharedMemory(ctx, &mut shm);
379    if res != raw::TEEC_SUCCESS {
380        return Err(Error::from_raw_os_error(res as i32));
381    }
382
383    Ok(shm)
384}
385
386// 复制数据到共享内存
387fn copy_to_shm(data: &[u8], shm: &raw::TEEC_SharedMemory) {
388    // SAFETY:
389    // - `data.as_ptr()` 对读取 `data.len()` 字节有效(来自 slice 保证)
390    // - `shm.buffer` 对写入有效(由 TEEC_AllocateSharedMemory 分配或注册)
391    // - 源和目标不重叠(不同的内存区域)
392    unsafe {
393        ptr::copy_nonoverlapping(data.as_ptr(), shm.buffer as *mut u8, data.len());
394    }
395}
396
397// 从共享内存复制数据到缓冲区
398fn copy_from_shm(shm: &raw::TEEC_SharedMemory, data: &mut [u8]) {
399    // SAFETY:
400    // - `shm.buffer` 对读取有效(已分配/注册的共享内存)
401    // - `data.as_mut_ptr()` 对写入 `data.len()` 字节有效(来自可变 slice)
402    // - 源和目标不重叠
403    unsafe {
404        ptr::copy_nonoverlapping(shm.buffer as *const u8, data.as_mut_ptr(), data.len());
405    }
406}
407
408// 从共享内存读取数据
409fn read_from_shm(shm: &raw::TEEC_SharedMemory, size: usize) -> Vec<u8> {
410    let mut data = vec![0u8; size];
411    // SAFETY:
412    // - `shm.buffer` 对读取 `size` 字节有效(共享内存保证)
413    // - `data.as_mut_ptr()` 对写入有效(新分配的 Vec)
414    // - 源和目标不重叠
415    unsafe {
416        ptr::copy_nonoverlapping(shm.buffer as *const u8, data.as_mut_ptr(), size);
417    }
418    data
419}
420
421// 从共享内存指定偏移量读取数据
422fn read_from_shm_offset(shm: &raw::TEEC_SharedMemory, offset: usize, size: usize) -> Vec<u8> {
423    let mut data = vec![0u8; size];
424    // SAFETY:
425    // - `(shm.buffer as *const u8).add(offset)` 在边界内(调用者确保 offset + size <= shm.size)
426    // - `data.as_mut_ptr()` 对写入有效(新分配的 Vec)
427    // - 源和目标不重叠
428    unsafe {
429        ptr::copy_nonoverlapping(
430            (shm.buffer as *const u8).add(offset),
431            data.as_mut_ptr(),
432            size,
433        );
434    }
435    data
436}
437
438// 复制数据到共享内存指定偏移量
439fn copy_to_shm_offset(data: &[u8], shm: &raw::TEEC_SharedMemory, offset: usize) {
440    // SAFETY:
441    // - `data.as_ptr()` 对读取有效(来自 slice 保证)
442    // - `(shm.buffer as *mut u8).add(offset)` 在边界内(调用者确保 offset + data.len() <= shm.size)
443    // - 源和目标不重叠
444    unsafe {
445        ptr::copy_nonoverlapping(
446            data.as_ptr(),
447            (shm.buffer as *mut u8).add(offset),
448            data.len(),
449        );
450    }
451}
452
453// 创建 MEMREF 操作参数
454fn create_memref_operation(shm: &mut raw::TEEC_SharedMemory, size: usize) -> raw::TEEC_Operation {
455    // SAFETY: `TEEC_Operation` 是 POD 类型,零初始化是有效的。
456    let mut op: raw::TEEC_Operation = unsafe { mem::zeroed() };
457    op.paramTypes = raw::TEEC_PARAM_TYPES(
458        raw::TEEC_MEMREF_WHOLE,
459        raw::TEEC_NONE,
460        raw::TEEC_NONE,
461        raw::TEEC_NONE,
462    );
463    op.params[0].memref.parent = shm;
464    op.params[0].memref.size = size;
465    op
466}
467
468// MEMREF PARTIAL INPUT + OUTPUT 演示
469fn memref_partial_input_output(
470    session: &mut Client_Session,
471    shm: &mut raw::TEEC_SharedMemory,
472    page_size: usize,
473) -> Result<()> {
474    let input_data = vec![0x10, 0x20, 0x30, 0x40];
475    let output_size = 8;
476    let input_offset = 0; // 使用共享内存的起始区域
477    let output_offset = page_size; // 使用共享内存的第 2 个页(偏移 4096)
478
479    // 将输入数据复制到共享内存的指定偏移位置
480    copy_to_shm_offset(&input_data, shm, input_offset);
481
482    // SAFETY: `TEEC_Operation` 是 POD 类型,零初始化是有效的。
483    let mut op: raw::TEEC_Operation = unsafe { mem::zeroed() };
484    op.paramTypes = raw::TEEC_PARAM_TYPES(
485        raw::TEEC_MEMREF_PARTIAL_INPUT,
486        raw::TEEC_MEMREF_PARTIAL_OUTPUT,
487        raw::TEEC_NONE,
488        raw::TEEC_NONE,
489    );
490    // 参数 0: PARTIAL INPUT
491    op.params[0].memref.parent = shm;
492    op.params[0].memref.offset = input_offset;
493    op.params[0].memref.size = input_data.len();
494    // 参数 1: PARTIAL OUTPUT
495    op.params[1].memref.parent = shm;
496    op.params[1].memref.offset = output_offset;
497    op.params[1].memref.size = output_size;
498
499    session.invoke_command(Command::MemrefPartialInputOutput.into(), &mut op)?;
500
501    // 从共享内存的指定偏移位置读取结果
502    let output_data = read_from_shm_offset(shm, output_offset, output_size);
503    println!(
504        "  PARTIAL_INPUT+OUTPUT:\toffset[0]={:?} → offset[{}]={:?}",
505        input_data, output_offset, output_data
506    );
507
508    Ok(())
509}
510
511// MEMREF PARTIAL INOUT 演示
512fn memref_partial_inout(
513    session: &mut Client_Session,
514    shm: &mut raw::TEEC_SharedMemory,
515    page_size: usize,
516) -> Result<()> {
517    let data = vec![0x01, 0x02, 0x03, 0x04];
518    let key = 0x55u8;
519    let original = data.clone();
520
521    let offset = 2 * page_size; // 使用共享内存的第 3 个页(偏移 8192)
522
523    // 将数据复制到共享内存的指定偏移位置
524    copy_to_shm_offset(&data, shm, offset);
525
526    // SAFETY: `TEEC_Operation` 是 POD 类型,零初始化是有效的。
527    let mut op: raw::TEEC_Operation = unsafe { mem::zeroed() };
528
529    // 混合参数:VALUE_INPUT + MEMREF_PARTIAL_INOUT
530    op.paramTypes = raw::TEEC_PARAM_TYPES(
531        raw::TEEC_VALUE_INPUT,
532        raw::TEEC_MEMREF_PARTIAL_INOUT,
533        raw::TEEC_NONE,
534        raw::TEEC_NONE,
535    );
536    op.params[0].value.a = key as u32;
537    // PARTIAL 参数:只引用共享内存的一部分
538    op.params[1].memref.parent = shm;
539    op.params[1].memref.offset = offset;
540    op.params[1].memref.size = data.len();
541
542    session.invoke_command(Command::MemrefPartialInout.into(), &mut op)?;
543
544    // 从共享内存的指定偏移位置读取 XOR 加密后的结果
545    let result = read_from_shm_offset(shm, offset, data.len());
546    println!(
547        "  PARTIAL_INOUT: offset[{}]={:?} ^ 0x{:02X} → {:?}",
548        offset, original, key, result
549    );
550
551    Ok(())
552}
553
554fn memref_partial(session: &mut Client_Session) -> Result<()> {
555    println!("\nMEMREF PARTIAL 参数类型");
556    // 分配共享内存(需要足够大以支持多个 PARTIAL 引用)
557    // 内存布局:
558    //   [0 ~ 4095]       : PARTIAL INPUT 使用的区域
559    //   [4096 ~ 8191]    : PARTIAL OUTPUT 使用的区域
560    //   [8192 ~ 12287]   : PARTIAL INOUT 使用的区域
561    //   [12288 ~ 32767]  : 未使用
562    let page_size = 4096;
563    let shm_size = 8 * page_size; // 32KB
564    let mut shm = allocate_shared_memory(
565        session.context_mut(),
566        shm_size,
567        raw::TEEC_MEM_INPUT | raw::TEEC_MEM_OUTPUT,
568    )?;
569
570    memref_partial_input_output(session, &mut shm, page_size)?;
571    memref_partial_inout(session, &mut shm, page_size)?;
572
573    TEEC_ReleaseSharedMemory(&mut shm);
574
575    Ok(())
576}