Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/kern Fix kern/50841: races in sys_lseek.



details:   https://anonhg.NetBSD.org/src/rev/34b736d78d88
branches:  trunk
changeset: 341908:34b736d78d88
user:      dholland <dholland%NetBSD.org@localhost>
date:      Sat Nov 28 15:26:29 2015 +0000

description:
Fix kern/50841: races in sys_lseek.

diffstat:

 sys/kern/vfs_syscalls.c |  11 +++++++----
 1 files changed, 7 insertions(+), 4 deletions(-)

diffs (48 lines):

diff -r d96f944e2b06 -r 34b736d78d88 sys/kern/vfs_syscalls.c
--- a/sys/kern/vfs_syscalls.c   Sat Nov 28 15:06:55 2015 +0000
+++ b/sys/kern/vfs_syscalls.c   Sat Nov 28 15:26:29 2015 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: vfs_syscalls.c,v 1.503 2015/10/28 14:05:04 martin Exp $        */
+/*     $NetBSD: vfs_syscalls.c,v 1.504 2015/11/28 15:26:29 dholland Exp $      */
 
 /*-
  * Copyright (c) 2008, 2009 The NetBSD Foundation, Inc.
@@ -70,7 +70,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: vfs_syscalls.c,v 1.503 2015/10/28 14:05:04 martin Exp $");
+__KERNEL_RCSID(0, "$NetBSD: vfs_syscalls.c,v 1.504 2015/11/28 15:26:29 dholland Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_fileassoc.h"
@@ -2761,15 +2761,16 @@
                goto out;
        }
 
+       vn_lock(vp, LK_SHARED | LK_RETRY);
+
        switch (SCARG(uap, whence)) {
        case SEEK_CUR:
                newoff = fp->f_offset + SCARG(uap, offset);
                break;
        case SEEK_END:
-               vn_lock(vp, LK_SHARED | LK_RETRY);
                error = VOP_GETATTR(vp, &vattr, cred);
-               VOP_UNLOCK(vp);
                if (error) {
+                       VOP_UNLOCK(vp);
                        goto out;
                }
                newoff = SCARG(uap, offset) + vattr.va_size;
@@ -2779,8 +2780,10 @@
                break;
        default:
                error = EINVAL;
+               VOP_UNLOCK(vp);
                goto out;
        }
+       VOP_UNLOCK(vp);
        if ((error = VOP_SEEK(vp, fp->f_offset, newoff, cred)) == 0) {
                *(off_t *)retval = fp->f_offset = newoff;
        }



Home | Main Index | Thread Index | Old Index