Fix unsanitized input to remove_fd_tap()
authorBarret Rhoden <brho@cs.berkeley.edu>
Tue, 30 Apr 2019 00:00:48 +0000 (20:00 -0400)
committerBarret Rhoden <brho@cs.berkeley.edu>
Tue, 30 Apr 2019 00:00:48 +0000 (20:00 -0400)
Reported-by: syzbot+23841a68e22cc895cab7@syzkaller.appspotmail.com
Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
kern/src/fdtap.c

index e8edaca..72d4932 100644 (file)
@@ -132,17 +132,27 @@ int remove_fd_tap(struct proc *p, int fd)
        struct fd_table *fdt = &p->open_files;
        struct fd_tap *tap;
 
+       if (fd < 0) {
+               set_errno(EBADF);
+               return -1;
+       }
        spin_lock(&fdt->lock);
+       if (fd >= fdt->max_fdset) {
+               set_errno(ENFILE);
+               goto err_with_lock;
+       }
        tap = fdt->fd[fd].fd_tap;
-       fdt->fd[fd].fd_tap = 0;
-       spin_unlock(&fdt->lock);
-       if (tap) {
-               kref_put(&tap->kref);
-               return 0;
-       } else {
+       if (!tap) {
                set_error(EBADF, "FD %d was not tapped", fd);
-               return -1;
+               goto err_with_lock;
        }
+       fdt->fd[fd].fd_tap = 0;
+       spin_unlock(&fdt->lock);
+       kref_put(&tap->kref);
+       return 0;
+err_with_lock:
+       spin_unlock(&fdt->lock);
+       return -1;
 }
 
 /* Fires off tap, with the events of filter having occurred.  Returns -1 on