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