diff options
author | Chirantan Ekbote <chirantan@chromium.org> | 2020-04-13 17:30:19 +0900 |
---|---|---|
committer | Commit Bot <commit-bot@chromium.org> | 2020-04-16 06:32:43 +0000 |
commit | a89621315140045268ffcf636616bc2858be760d (patch) | |
tree | a690c08c6f309f2aed6f9524cce253045750b156 /devices | |
parent | 80d61873eba0e40013bf6ffe1cba1276300e7dc5 (diff) | |
download | crosvm-a89621315140045268ffcf636616bc2858be760d.tar crosvm-a89621315140045268ffcf636616bc2858be760d.tar.gz crosvm-a89621315140045268ffcf636616bc2858be760d.tar.bz2 crosvm-a89621315140045268ffcf636616bc2858be760d.tar.lz crosvm-a89621315140045268ffcf636616bc2858be760d.tar.xz crosvm-a89621315140045268ffcf636616bc2858be760d.tar.zst crosvm-a89621315140045268ffcf636616bc2858be760d.zip |
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 <noreply+kokoro@google.com> Commit-Queue: Chirantan Ekbote <chirantan@chromium.org> Reviewed-by: Dylan Reid <dgreid@chromium.org>
Diffstat (limited to 'devices')
-rw-r--r-- | devices/src/virtio/fs/passthrough.rs | 13 |
1 files changed, 12 insertions, 1 deletions
diff --git a/devices/src/virtio/fs/passthrough.rs b/devices/src/virtio/fs/passthrough.rs index 60f9655..3488a70 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 + }) }) } |