1 // Copyright 2020 The Chromium OS Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 use crate::{
6     AsRawDescriptor, FromRawDescriptor, IntoRawDescriptor, MemfdSeals, RawDescriptor, Result,
7     SafeDescriptor,
8 };
9 use std::ffi::CStr;
10 use std::fs::File;
11 use std::os::unix::io::{AsRawFd, IntoRawFd};
12 
13 use serde::{Deserialize, Serialize};
14 use sys_util::SharedMemory as SysUtilSharedMemory;
15 
16 /// See [SharedMemory](sys_util::SharedMemory) for struct- and method-level
17 /// documentation.
18 #[derive(Serialize, Deserialize)]
19 #[serde(transparent)]
20 pub struct SharedMemory(SysUtilSharedMemory);
21 impl SharedMemory {
named<T: Into<Vec<u8>>>(name: T, size: u64) -> Result<SharedMemory>22     pub fn named<T: Into<Vec<u8>>>(name: T, size: u64) -> Result<SharedMemory> {
23         SysUtilSharedMemory::named(name)
24             .and_then(|mut shm| shm.set_size(size).map(|_| shm))
25             .map(SharedMemory)
26     }
27 
anon(size: u64) -> Result<SharedMemory>28     pub fn anon(size: u64) -> Result<SharedMemory> {
29         Self::new(None, size)
30     }
31 
new(name: Option<&CStr>, size: u64) -> Result<SharedMemory>32     pub fn new(name: Option<&CStr>, size: u64) -> Result<SharedMemory> {
33         SysUtilSharedMemory::new(name)
34             .and_then(|mut shm| shm.set_size(size).map(|_| shm))
35             .map(SharedMemory)
36     }
37 
size(&self) -> u6438     pub fn size(&self) -> u64 {
39         self.0.size()
40     }
41 
42     /// Unwraps the sys_util::SharedMemory stored within this type.
43     /// This should be used only when necessary for interacting with
44     /// external libraries.
inner(&self) -> &SysUtilSharedMemory45     pub fn inner(&self) -> &SysUtilSharedMemory {
46         &self.0
47     }
48 }
49 
50 pub trait Unix {
51     /// Creates a SharedMemory instance from a SafeDescriptor owning a reference to a
52     /// shared memory descriptor. Ownership of the underlying descriptor is transferred to the
53     /// new SharedMemory object.
from_safe_descriptor(descriptor: SafeDescriptor) -> Result<SharedMemory>54     fn from_safe_descriptor(descriptor: SafeDescriptor) -> Result<SharedMemory> {
55         let file = unsafe { File::from_raw_descriptor(descriptor.into_raw_descriptor()) };
56         SysUtilSharedMemory::from_file(file).map(SharedMemory)
57     }
58 
from_file(file: File) -> Result<SharedMemory>59     fn from_file(file: File) -> Result<SharedMemory> {
60         SysUtilSharedMemory::from_file(file).map(SharedMemory)
61     }
62 
get_seals(&self) -> Result<MemfdSeals>63     fn get_seals(&self) -> Result<MemfdSeals>;
64 
add_seals(&mut self, seals: MemfdSeals) -> Result<()>65     fn add_seals(&mut self, seals: MemfdSeals) -> Result<()>;
66 }
67 
68 impl Unix for SharedMemory {
get_seals(&self) -> Result<MemfdSeals>69     fn get_seals(&self) -> Result<MemfdSeals> {
70         self.0.get_seals()
71     }
72 
add_seals(&mut self, seals: MemfdSeals) -> Result<()>73     fn add_seals(&mut self, seals: MemfdSeals) -> Result<()> {
74         self.0.add_seals(seals)
75     }
76 }
77 
78 impl AsRawDescriptor for SharedMemory {
as_raw_descriptor(&self) -> RawDescriptor79     fn as_raw_descriptor(&self) -> RawDescriptor {
80         self.0.as_raw_fd()
81     }
82 }
83 
84 impl IntoRawDescriptor for SharedMemory {
into_raw_descriptor(self) -> RawDescriptor85     fn into_raw_descriptor(self) -> RawDescriptor {
86         self.0.into_raw_fd()
87     }
88 }
89 
90 impl Into<SafeDescriptor> for SharedMemory {
into(self) -> SafeDescriptor91     fn into(self) -> SafeDescriptor {
92         // Safe because we own the SharedMemory at this point.
93         unsafe { SafeDescriptor::from_raw_descriptor(self.into_raw_descriptor()) }
94     }
95 }
96