From d8447077f0585379cd513c96144e00a8fe23e291 Mon Sep 17 00:00:00 2001 From: Chirantan Ekbote Date: Thu, 25 Jun 2020 13:57:46 +0900 Subject: [PATCH] devices: fs: Fix linkat impl Using AT_EMPTY_PATH with linkat requires the caller to have CAP_DAC_READ_SEARCH in the init user namespace. Since the fs device isn't going to have this when run in a sandbox, switch to using /proc/self/fd with AT_SYMLINK_FOLLOW instead, which is documented in the manpage as an alternative to AT_EMPTY_PATH. BUG=b:159861594 TEST=`touch foo; ln foo bar` succeeds Change-Id: I944d80d955742d653e36d245024adc48cf77d77e Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/crosvm/+/2265933 Tested-by: kokoro Commit-Queue: Chirantan Ekbote Auto-Submit: Chirantan Ekbote Reviewed-by: Daniel Verkamp --- devices/src/virtio/fs/passthrough.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/devices/src/virtio/fs/passthrough.rs b/devices/src/virtio/fs/passthrough.rs index f065ce4e84..b9ebfafbca 100644 --- a/devices/src/virtio/fs/passthrough.rs +++ b/devices/src/virtio/fs/passthrough.rs @@ -1640,17 +1640,17 @@ impl FileSystem for PassthroughFs { .map(Arc::clone) .ok_or_else(ebadf)?; - // Safe because this is a constant value and a valid C string. - let empty = unsafe { CStr::from_bytes_with_nul_unchecked(EMPTY_CSTR) }; + let path = CString::new(format!("self/fd/{}", data.file.as_raw_fd())) + .map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e))?; // Safe because this doesn't modify any memory and we check the return value. let res = unsafe { libc::linkat( - data.file.as_raw_fd(), - empty.as_ptr(), + self.proc.as_raw_fd(), + path.as_ptr(), new_inode.file.as_raw_fd(), newname.as_ptr(), - libc::AT_EMPTY_PATH, + libc::AT_SYMLINK_FOLLOW, ) }; if res == 0 {