blob: 66c943e2c702b390f147a832acc77cf7b9e234f5 [file] [log] [blame]
Victor Hsiehb0f5fc82021-10-15 17:24:19 -07001/*
2 * Copyright (C) 2021 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17use anyhow::Result;
18use log::error;
Victor Hsieh45636232021-10-15 17:52:51 -070019use nix::{
20 dir::Dir, errno::Errno, fcntl::openat, fcntl::OFlag, sys::stat::mkdirat, sys::stat::Mode,
Victor Hsiehdd99b462021-12-02 17:36:15 -080021 sys::statvfs::statvfs, sys::statvfs::Statvfs, unistd::unlinkat, unistd::UnlinkatFlags,
Victor Hsieh45636232021-10-15 17:52:51 -070022};
Victor Hsiehb0f5fc82021-10-15 17:24:19 -070023use std::cmp::min;
Victor Hsieh45636232021-10-15 17:52:51 -070024use std::collections::{btree_map, BTreeMap};
Victor Hsiehb0f5fc82021-10-15 17:24:19 -070025use std::convert::TryInto;
26use std::fs::File;
27use std::io;
28use std::os::unix::fs::FileExt;
Victor Hsieh559b9272021-11-08 15:15:14 -080029use std::os::unix::io::{AsRawFd, FromRawFd, RawFd};
30use std::path::{Component, Path, PathBuf, MAIN_SEPARATOR};
Victor Hsieh45636232021-10-15 17:52:51 -070031use std::sync::{Arc, Mutex};
Victor Hsiehb0f5fc82021-10-15 17:24:19 -070032
33use crate::fsverity;
34use authfs_aidl_interface::aidl::com::android::virt::fs::IVirtFdService::{
Victor Hsiehf7fc3d32021-11-22 10:20:33 -080035 BnVirtFdService, FsStat::FsStat, IVirtFdService, MAX_REQUESTING_DATA,
Victor Hsiehb0f5fc82021-10-15 17:24:19 -070036};
37use authfs_aidl_interface::binder::{
Victor Hsieh45636232021-10-15 17:52:51 -070038 BinderFeatures, ExceptionCode, Interface, Result as BinderResult, Status, StatusCode, Strong,
Victor Hsiehb0f5fc82021-10-15 17:24:19 -070039};
Victor Hsieh45636232021-10-15 17:52:51 -070040use binder_common::{new_binder_exception, new_binder_service_specific_error};
Victor Hsiehb0f5fc82021-10-15 17:24:19 -070041
42fn validate_and_cast_offset(offset: i64) -> Result<u64, Status> {
Victor Hsiehbe8b08d2021-10-29 16:31:24 -070043 offset.try_into().map_err(|_| new_errno_error(Errno::EINVAL))
Victor Hsiehb0f5fc82021-10-15 17:24:19 -070044}
45
46fn validate_and_cast_size(size: i32) -> Result<usize, Status> {
47 if size > MAX_REQUESTING_DATA {
Victor Hsiehbe8b08d2021-10-29 16:31:24 -070048 Err(new_errno_error(Errno::EFBIG))
Victor Hsiehb0f5fc82021-10-15 17:24:19 -070049 } else {
Victor Hsiehbe8b08d2021-10-29 16:31:24 -070050 size.try_into().map_err(|_| new_errno_error(Errno::EINVAL))
Victor Hsiehb0f5fc82021-10-15 17:24:19 -070051 }
52}
53
54/// Configuration of a file descriptor to be served/exposed/shared.
55pub enum FdConfig {
56 /// A read-only file to serve by this server. The file is supposed to be verifiable with the
57 /// associated fs-verity metadata.
58 Readonly {
59 /// The file to read from. fs-verity metadata can be retrieved from this file's FD.
60 file: File,
61
62 /// Alternative Merkle tree stored in another file.
Victor Hsieh559b9272021-11-08 15:15:14 -080063 /// TODO(205987437): Replace with .fsv_meta file.
Victor Hsiehb0f5fc82021-10-15 17:24:19 -070064 alt_merkle_tree: Option<File>,
65
66 /// Alternative signature stored in another file.
Victor Hsieh559b9272021-11-08 15:15:14 -080067 /// TODO(205987437): Replace with .fsv_meta file.
Victor Hsiehb0f5fc82021-10-15 17:24:19 -070068 alt_signature: Option<File>,
69 },
70
71 /// A readable/writable file to serve by this server. This backing file should just be a
72 /// regular file and does not have any specific property.
73 ReadWrite(File),
Victor Hsieh45636232021-10-15 17:52:51 -070074
Victor Hsieh559b9272021-11-08 15:15:14 -080075 /// A read-only directory to serve by this server.
76 InputDir(Dir),
77
Victor Hsieh45636232021-10-15 17:52:51 -070078 /// A writable directory to serve by this server.
79 OutputDir(Dir),
Victor Hsiehb0f5fc82021-10-15 17:24:19 -070080}
81
82pub struct FdService {
Victor Hsieh45636232021-10-15 17:52:51 -070083 /// A pool of opened files and directories, which can be looked up by the FD number.
84 fd_pool: Arc<Mutex<BTreeMap<i32, FdConfig>>>,
Victor Hsiehb0f5fc82021-10-15 17:24:19 -070085}
86
87impl FdService {
88 pub fn new_binder(fd_pool: BTreeMap<i32, FdConfig>) -> Strong<dyn IVirtFdService> {
Victor Hsieh45636232021-10-15 17:52:51 -070089 BnVirtFdService::new_binder(
90 FdService { fd_pool: Arc::new(Mutex::new(fd_pool)) },
91 BinderFeatures::default(),
92 )
Victor Hsiehb0f5fc82021-10-15 17:24:19 -070093 }
94
Victor Hsieh45636232021-10-15 17:52:51 -070095 /// Handles the requesting file `id` with `handle_fn` if it is in the FD pool. This function
96 /// returns whatever `handle_fn` returns.
97 fn handle_fd<F, R>(&self, id: i32, handle_fn: F) -> BinderResult<R>
Victor Hsiehc85e4ef2021-10-18 15:28:53 -070098 where
99 F: FnOnce(&FdConfig) -> BinderResult<R>,
100 {
Victor Hsieh45636232021-10-15 17:52:51 -0700101 let fd_pool = self.fd_pool.lock().unwrap();
102 let fd_config = fd_pool.get(&id).ok_or_else(|| new_errno_error(Errno::EBADF))?;
103 handle_fn(fd_config)
104 }
105
106 /// Inserts a new FD and corresponding `FdConfig` created by `create_fn` to the FD pool, then
107 /// returns the new FD number.
108 fn insert_new_fd<F>(&self, fd: i32, create_fn: F) -> BinderResult<i32>
109 where
110 F: FnOnce(&mut FdConfig) -> BinderResult<(i32, FdConfig)>,
111 {
112 let mut fd_pool = self.fd_pool.lock().unwrap();
Chris Wailes641fc4a2021-12-01 15:03:21 -0800113 let fd_config = fd_pool.get_mut(&fd).ok_or_else(|| new_errno_error(Errno::EBADF))?;
114 let (new_fd, new_fd_config) = create_fn(fd_config)?;
Victor Hsieh45636232021-10-15 17:52:51 -0700115 if let btree_map::Entry::Vacant(entry) = fd_pool.entry(new_fd) {
116 entry.insert(new_fd_config);
117 Ok(new_fd)
118 } else {
119 Err(new_binder_exception(
120 ExceptionCode::ILLEGAL_STATE,
121 format!("The newly created FD {} is already in the pool unexpectedly", new_fd),
122 ))
123 }
Victor Hsiehb0f5fc82021-10-15 17:24:19 -0700124 }
125}
126
127impl Interface for FdService {}
128
129impl IVirtFdService for FdService {
130 fn readFile(&self, id: i32, offset: i64, size: i32) -> BinderResult<Vec<u8>> {
131 let size: usize = validate_and_cast_size(size)?;
132 let offset: u64 = validate_and_cast_offset(offset)?;
133
Victor Hsiehc85e4ef2021-10-18 15:28:53 -0700134 self.handle_fd(id, |config| match config {
Victor Hsiehb0f5fc82021-10-15 17:24:19 -0700135 FdConfig::Readonly { file, .. } | FdConfig::ReadWrite(file) => {
136 read_into_buf(file, size, offset).map_err(|e| {
137 error!("readFile: read error: {}", e);
Victor Hsiehbe8b08d2021-10-29 16:31:24 -0700138 new_errno_error(Errno::EIO)
Victor Hsiehb0f5fc82021-10-15 17:24:19 -0700139 })
140 }
Victor Hsieh559b9272021-11-08 15:15:14 -0800141 FdConfig::InputDir(_) | FdConfig::OutputDir(_) => Err(new_errno_error(Errno::EISDIR)),
Victor Hsiehc85e4ef2021-10-18 15:28:53 -0700142 })
Victor Hsiehb0f5fc82021-10-15 17:24:19 -0700143 }
144
145 fn readFsverityMerkleTree(&self, id: i32, offset: i64, size: i32) -> BinderResult<Vec<u8>> {
146 let size: usize = validate_and_cast_size(size)?;
147 let offset: u64 = validate_and_cast_offset(offset)?;
148
Victor Hsiehc85e4ef2021-10-18 15:28:53 -0700149 self.handle_fd(id, |config| match config {
Victor Hsiehb0f5fc82021-10-15 17:24:19 -0700150 FdConfig::Readonly { file, alt_merkle_tree, .. } => {
151 if let Some(tree_file) = &alt_merkle_tree {
152 read_into_buf(tree_file, size, offset).map_err(|e| {
153 error!("readFsverityMerkleTree: read error: {}", e);
Victor Hsiehbe8b08d2021-10-29 16:31:24 -0700154 new_errno_error(Errno::EIO)
Victor Hsiehb0f5fc82021-10-15 17:24:19 -0700155 })
156 } else {
157 let mut buf = vec![0; size];
158 let s = fsverity::read_merkle_tree(file.as_raw_fd(), offset, &mut buf)
159 .map_err(|e| {
160 error!("readFsverityMerkleTree: failed to retrieve merkle tree: {}", e);
Victor Hsiehbe8b08d2021-10-29 16:31:24 -0700161 new_errno_error(Errno::EIO)
Victor Hsiehb0f5fc82021-10-15 17:24:19 -0700162 })?;
163 debug_assert!(s <= buf.len(), "Shouldn't return more bytes than asked");
164 buf.truncate(s);
165 Ok(buf)
166 }
167 }
168 FdConfig::ReadWrite(_file) => {
169 // For a writable file, Merkle tree is not expected to be served since Auth FS
170 // doesn't trust it anyway. Auth FS may keep the Merkle tree privately for its own
171 // use.
Victor Hsiehbe8b08d2021-10-29 16:31:24 -0700172 Err(new_errno_error(Errno::ENOSYS))
Victor Hsiehb0f5fc82021-10-15 17:24:19 -0700173 }
Victor Hsieh559b9272021-11-08 15:15:14 -0800174 FdConfig::InputDir(_) | FdConfig::OutputDir(_) => Err(new_errno_error(Errno::EISDIR)),
Victor Hsiehc85e4ef2021-10-18 15:28:53 -0700175 })
Victor Hsiehb0f5fc82021-10-15 17:24:19 -0700176 }
177
178 fn readFsveritySignature(&self, id: i32) -> BinderResult<Vec<u8>> {
Victor Hsiehc85e4ef2021-10-18 15:28:53 -0700179 self.handle_fd(id, |config| match config {
Victor Hsiehb0f5fc82021-10-15 17:24:19 -0700180 FdConfig::Readonly { file, alt_signature, .. } => {
181 if let Some(sig_file) = &alt_signature {
182 // Supposedly big enough buffer size to store signature.
183 let size = MAX_REQUESTING_DATA as usize;
184 let offset = 0;
185 read_into_buf(sig_file, size, offset).map_err(|e| {
186 error!("readFsveritySignature: read error: {}", e);
Victor Hsiehbe8b08d2021-10-29 16:31:24 -0700187 new_errno_error(Errno::EIO)
Victor Hsiehb0f5fc82021-10-15 17:24:19 -0700188 })
189 } else {
190 let mut buf = vec![0; MAX_REQUESTING_DATA as usize];
191 let s = fsverity::read_signature(file.as_raw_fd(), &mut buf).map_err(|e| {
192 error!("readFsverityMerkleTree: failed to retrieve merkle tree: {}", e);
Victor Hsiehbe8b08d2021-10-29 16:31:24 -0700193 new_errno_error(Errno::EIO)
Victor Hsiehb0f5fc82021-10-15 17:24:19 -0700194 })?;
195 debug_assert!(s <= buf.len(), "Shouldn't return more bytes than asked");
196 buf.truncate(s);
197 Ok(buf)
198 }
199 }
200 FdConfig::ReadWrite(_file) => {
201 // There is no signature for a writable file.
Victor Hsiehbe8b08d2021-10-29 16:31:24 -0700202 Err(new_errno_error(Errno::ENOSYS))
Victor Hsiehb0f5fc82021-10-15 17:24:19 -0700203 }
Victor Hsieh559b9272021-11-08 15:15:14 -0800204 FdConfig::InputDir(_) | FdConfig::OutputDir(_) => Err(new_errno_error(Errno::EISDIR)),
Victor Hsiehc85e4ef2021-10-18 15:28:53 -0700205 })
Victor Hsiehb0f5fc82021-10-15 17:24:19 -0700206 }
207
208 fn writeFile(&self, id: i32, buf: &[u8], offset: i64) -> BinderResult<i32> {
Victor Hsiehc85e4ef2021-10-18 15:28:53 -0700209 self.handle_fd(id, |config| match config {
Victor Hsiehb0f5fc82021-10-15 17:24:19 -0700210 FdConfig::Readonly { .. } => Err(StatusCode::INVALID_OPERATION.into()),
211 FdConfig::ReadWrite(file) => {
Victor Hsiehbe8b08d2021-10-29 16:31:24 -0700212 let offset: u64 = offset.try_into().map_err(|_| new_errno_error(Errno::EINVAL))?;
Victor Hsiehb0f5fc82021-10-15 17:24:19 -0700213 // Check buffer size just to make `as i32` safe below.
214 if buf.len() > i32::MAX as usize {
Victor Hsiehbe8b08d2021-10-29 16:31:24 -0700215 return Err(new_errno_error(Errno::EOVERFLOW));
Victor Hsiehb0f5fc82021-10-15 17:24:19 -0700216 }
217 Ok(file.write_at(buf, offset).map_err(|e| {
218 error!("writeFile: write error: {}", e);
Victor Hsiehbe8b08d2021-10-29 16:31:24 -0700219 new_errno_error(Errno::EIO)
Victor Hsiehb0f5fc82021-10-15 17:24:19 -0700220 })? as i32)
221 }
Victor Hsieh559b9272021-11-08 15:15:14 -0800222 FdConfig::InputDir(_) | FdConfig::OutputDir(_) => Err(new_errno_error(Errno::EISDIR)),
Victor Hsiehc85e4ef2021-10-18 15:28:53 -0700223 })
Victor Hsiehb0f5fc82021-10-15 17:24:19 -0700224 }
225
226 fn resize(&self, id: i32, size: i64) -> BinderResult<()> {
Victor Hsiehc85e4ef2021-10-18 15:28:53 -0700227 self.handle_fd(id, |config| match config {
Victor Hsiehb0f5fc82021-10-15 17:24:19 -0700228 FdConfig::Readonly { .. } => Err(StatusCode::INVALID_OPERATION.into()),
229 FdConfig::ReadWrite(file) => {
230 if size < 0 {
Victor Hsiehbe8b08d2021-10-29 16:31:24 -0700231 return Err(new_errno_error(Errno::EINVAL));
Victor Hsiehb0f5fc82021-10-15 17:24:19 -0700232 }
233 file.set_len(size as u64).map_err(|e| {
234 error!("resize: set_len error: {}", e);
Victor Hsiehbe8b08d2021-10-29 16:31:24 -0700235 new_errno_error(Errno::EIO)
Victor Hsiehb0f5fc82021-10-15 17:24:19 -0700236 })
237 }
Victor Hsieh559b9272021-11-08 15:15:14 -0800238 FdConfig::InputDir(_) | FdConfig::OutputDir(_) => Err(new_errno_error(Errno::EISDIR)),
Victor Hsiehc85e4ef2021-10-18 15:28:53 -0700239 })
Victor Hsiehb0f5fc82021-10-15 17:24:19 -0700240 }
241
242 fn getFileSize(&self, id: i32) -> BinderResult<i64> {
Victor Hsiehc85e4ef2021-10-18 15:28:53 -0700243 self.handle_fd(id, |config| match config {
Victor Hsiehb0f5fc82021-10-15 17:24:19 -0700244 FdConfig::Readonly { file, .. } => {
245 let size = file
246 .metadata()
247 .map_err(|e| {
248 error!("getFileSize error: {}", e);
Victor Hsiehbe8b08d2021-10-29 16:31:24 -0700249 new_errno_error(Errno::EIO)
Victor Hsiehb0f5fc82021-10-15 17:24:19 -0700250 })?
251 .len();
252 Ok(size.try_into().map_err(|e| {
253 error!("getFileSize: File too large: {}", e);
Victor Hsiehbe8b08d2021-10-29 16:31:24 -0700254 new_errno_error(Errno::EFBIG)
Victor Hsiehb0f5fc82021-10-15 17:24:19 -0700255 })?)
256 }
257 FdConfig::ReadWrite(_file) => {
258 // Content and metadata of a writable file needs to be tracked by authfs, since
259 // fd_server isn't considered trusted. So there is no point to support getFileSize
260 // for a writable file.
Victor Hsiehbe8b08d2021-10-29 16:31:24 -0700261 Err(new_errno_error(Errno::ENOSYS))
Victor Hsiehb0f5fc82021-10-15 17:24:19 -0700262 }
Victor Hsieh559b9272021-11-08 15:15:14 -0800263 FdConfig::InputDir(_) | FdConfig::OutputDir(_) => Err(new_errno_error(Errno::EISDIR)),
264 })
265 }
266
Victor Hsiehdd99b462021-12-02 17:36:15 -0800267 fn openFileInDirectory(&self, dir_fd: i32, file_path: &str) -> BinderResult<i32> {
Victor Hsieh559b9272021-11-08 15:15:14 -0800268 let path_buf = PathBuf::from(file_path);
269 // Checks if the path is a simple, related path.
270 if path_buf.components().any(|c| !matches!(c, Component::Normal(_))) {
271 return Err(new_errno_error(Errno::EINVAL));
272 }
273
Victor Hsiehdd99b462021-12-02 17:36:15 -0800274 self.insert_new_fd(dir_fd, |config| match config {
Victor Hsieh559b9272021-11-08 15:15:14 -0800275 FdConfig::InputDir(dir) => {
276 let file = open_readonly_at(dir.as_raw_fd(), &path_buf).map_err(new_errno_error)?;
277
278 // TODO(205987437): Provide the corresponding ".fsv_meta" file when it's created.
279 Ok((
280 file.as_raw_fd(),
281 FdConfig::Readonly { file, alt_merkle_tree: None, alt_signature: None },
282 ))
283 }
284 FdConfig::OutputDir(_) => {
285 Err(new_errno_error(Errno::ENOSYS)) // TODO: Implement when needed
286 }
287 _ => Err(new_errno_error(Errno::ENOTDIR)),
Victor Hsieh45636232021-10-15 17:52:51 -0700288 })
289 }
290
Victor Hsiehdd99b462021-12-02 17:36:15 -0800291 fn createFileInDirectory(&self, dir_fd: i32, basename: &str) -> BinderResult<i32> {
292 validate_basename(basename)?;
293
294 self.insert_new_fd(dir_fd, |config| match config {
Victor Hsieh559b9272021-11-08 15:15:14 -0800295 FdConfig::InputDir(_) => Err(new_errno_error(Errno::EACCES)),
Victor Hsieh45636232021-10-15 17:52:51 -0700296 FdConfig::OutputDir(dir) => {
297 let new_fd = openat(
298 dir.as_raw_fd(),
299 basename,
300 // TODO(205172873): handle the case when the file already exist, e.g. truncate
301 // or fail, and possibly allow the client to specify. For now, always truncate.
302 OFlag::O_CREAT | OFlag::O_RDWR | OFlag::O_TRUNC,
303 Mode::S_IRUSR | Mode::S_IWUSR,
304 )
305 .map_err(new_errno_error)?;
306 // SAFETY: new_fd is just created and not an error.
307 let new_file = unsafe { File::from_raw_fd(new_fd) };
308 Ok((new_fd, FdConfig::ReadWrite(new_file)))
309 }
310 _ => Err(new_errno_error(Errno::ENOTDIR)),
311 })
312 }
313
314 fn createDirectoryInDirectory(&self, dir_fd: i32, basename: &str) -> BinderResult<i32> {
Victor Hsiehdd99b462021-12-02 17:36:15 -0800315 validate_basename(basename)?;
316
Victor Hsieh45636232021-10-15 17:52:51 -0700317 self.insert_new_fd(dir_fd, |config| match config {
Victor Hsieh559b9272021-11-08 15:15:14 -0800318 FdConfig::InputDir(_) => Err(new_errno_error(Errno::EACCES)),
Victor Hsieh45636232021-10-15 17:52:51 -0700319 FdConfig::OutputDir(_) => {
320 mkdirat(dir_fd, basename, Mode::S_IRWXU).map_err(new_errno_error)?;
321 let new_dir = Dir::openat(
322 dir_fd,
323 basename,
324 OFlag::O_DIRECTORY | OFlag::O_RDONLY,
325 Mode::empty(),
326 )
327 .map_err(new_errno_error)?;
328 Ok((new_dir.as_raw_fd(), FdConfig::OutputDir(new_dir)))
329 }
330 _ => Err(new_errno_error(Errno::ENOTDIR)),
Victor Hsiehc85e4ef2021-10-18 15:28:53 -0700331 })
Victor Hsiehb0f5fc82021-10-15 17:24:19 -0700332 }
Victor Hsiehf7fc3d32021-11-22 10:20:33 -0800333
Victor Hsiehdd99b462021-12-02 17:36:15 -0800334 fn deleteFile(&self, dir_fd: i32, basename: &str) -> BinderResult<()> {
335 validate_basename(basename)?;
336
337 self.handle_fd(dir_fd, |config| match config {
338 FdConfig::OutputDir(_dir) => {
339 unlinkat(Some(dir_fd), basename, UnlinkatFlags::NoRemoveDir)
340 .map_err(new_errno_error)?;
341 Ok(())
342 }
343 FdConfig::InputDir(_) => Err(new_errno_error(Errno::EACCES)),
344 _ => Err(new_errno_error(Errno::ENOTDIR)),
345 })
346 }
347
348 fn deleteDirectory(&self, dir_fd: i32, basename: &str) -> BinderResult<()> {
349 validate_basename(basename)?;
350
351 self.handle_fd(dir_fd, |config| match config {
352 FdConfig::OutputDir(_dir) => {
353 unlinkat(Some(dir_fd), basename, UnlinkatFlags::RemoveDir)
354 .map_err(new_errno_error)?;
355 Ok(())
356 }
357 FdConfig::InputDir(_) => Err(new_errno_error(Errno::EACCES)),
358 _ => Err(new_errno_error(Errno::ENOTDIR)),
359 })
360 }
361
Victor Hsiehf7fc3d32021-11-22 10:20:33 -0800362 fn statfs(&self) -> BinderResult<FsStat> {
363 let st = statvfs("/data").map_err(new_errno_error)?;
364 try_into_fs_stat(st).map_err(|_e| new_errno_error(Errno::EINVAL))
365 }
366}
367
368fn try_into_fs_stat(st: Statvfs) -> Result<FsStat, std::num::TryFromIntError> {
369 Ok(FsStat {
370 blockSize: st.block_size().try_into()?,
371 fragmentSize: st.fragment_size().try_into()?,
372 blockNumbers: st.blocks().try_into()?,
373 blockAvailable: st.blocks_available().try_into()?,
374 inodesAvailable: st.files_available().try_into()?,
375 maxFilename: st.name_max().try_into()?,
376 })
Victor Hsiehb0f5fc82021-10-15 17:24:19 -0700377}
378
379fn read_into_buf(file: &File, max_size: usize, offset: u64) -> io::Result<Vec<u8>> {
380 let remaining = file.metadata()?.len().saturating_sub(offset);
381 let buf_size = min(remaining, max_size as u64) as usize;
382 let mut buf = vec![0; buf_size];
383 file.read_exact_at(&mut buf, offset)?;
384 Ok(buf)
385}
Victor Hsiehbe8b08d2021-10-29 16:31:24 -0700386
387fn new_errno_error(errno: Errno) -> Status {
388 new_binder_service_specific_error(errno as i32, errno.desc())
389}
Victor Hsieh559b9272021-11-08 15:15:14 -0800390
391fn open_readonly_at(dir_fd: RawFd, path: &Path) -> nix::Result<File> {
392 let new_fd = openat(dir_fd, path, OFlag::O_RDONLY, Mode::empty())?;
393 // SAFETY: new_fd is just created successfully and not owned.
394 let new_file = unsafe { File::from_raw_fd(new_fd) };
395 Ok(new_file)
396}
Victor Hsiehdd99b462021-12-02 17:36:15 -0800397
398fn validate_basename(name: &str) -> BinderResult<()> {
399 if name.contains(MAIN_SEPARATOR) {
400 Err(new_errno_error(Errno::EINVAL))
401 } else {
402 Ok(())
403 }
404}