From a89621315140045268ffcf636616bc2858be760d Mon Sep 17 00:00:00 2001 From: Chirantan Ekbote Date: Mon, 13 Apr 2020 17:30:19 +0900 Subject: [PATCH] devices: fs: Fix potential resource leak During a readdirplus call if we fail to add an entry to the response buffer, which can happen if the buffer doesn't have enough space to hold the entry, then the lookup count for that entry on the server will not match the lookup count in the kernel driver. Fix this by calling `forget_one` on that entry when this case happens. BUG=none TEST=vm.Virtiofs Change-Id: I66205ba94b451a726ddcde2376d731251eb7545f Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/crosvm/+/2145548 Tested-by: kokoro Commit-Queue: Chirantan Ekbote Reviewed-by: Dylan Reid --- devices/src/virtio/fs/passthrough.rs | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/devices/src/virtio/fs/passthrough.rs b/devices/src/virtio/fs/passthrough.rs index 60f9655be5..3488a7036a 100644 --- a/devices/src/virtio/fs/passthrough.rs +++ b/devices/src/virtio/fs/passthrough.rs @@ -962,7 +962,18 @@ impl FileSystem for PassthroughFs { self.do_lookup(inode, dir_entry.name)? }; - add_entry(dir_entry, entry) + let entry_inode = entry.inode; + add_entry(dir_entry, entry).map_err(|e| { + if entry_inode != 0 { + // Undo the `do_lookup` for this inode since we aren't going to report it to + // the kernel. If `entry_inode` was 0 then that means this was the "." or + // ".." entry and there wasn't a lookup in the first place. + let mut inodes = self.inodes.lock(); + forget_one(&mut inodes, entry_inode, 1); + } + + e + }) }) }