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