#[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}