summary refs log tree commit diff
path: root/devices
diff options
context:
space:
mode:
authorChirantan Ekbote <chirantan@chromium.org>2020-04-13 17:30:19 +0900
committerCommit Bot <commit-bot@chromium.org>2020-04-16 06:32:43 +0000
commita89621315140045268ffcf636616bc2858be760d (patch)
treea690c08c6f309f2aed6f9524cce253045750b156 /devices
parent80d61873eba0e40013bf6ffe1cba1276300e7dc5 (diff)
downloadcrosvm-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.rs13
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
+            })
         })
     }