Author: trasz
Date: Tue Oct 20 17:19:10 2020
New Revision: 366899
URL: https://svnweb.freebsd.org/changeset/base/366899

Log:
  Fix potential race condition in linux stat(2).
  
  Reviewed by:  kib
  MFC after:    2 weeks
  Sponsored by: The FreeBSD Foundation
  Differential Revision:        https://reviews.freebsd.org/D25618

Modified:
  head/sys/compat/linux/linux_stats.c
  head/sys/compat/linux/linux_util.c
  head/sys/compat/linux/linux_util.h

Modified: head/sys/compat/linux/linux_stats.c
==============================================================================
--- head/sys/compat/linux/linux_stats.c Tue Oct 20 17:00:43 2020        
(r366898)
+++ head/sys/compat/linux/linux_stats.c Tue Oct 20 17:19:10 2020        
(r366899)
@@ -80,11 +80,8 @@ translate_vnhook_major_minor(struct vnode *vp, struct 
        if (rootdevmp != NULL && vp->v_mount->mnt_vfc == rootdevmp->mnt_vfc)
                sb->st_dev = rootdevmp->mnt_stat.f_fsid.val[0];
 
-       if (vp->v_type == VCHR && vp->v_rdev != NULL &&
-           linux_driver_get_major_minor(devtoname(vp->v_rdev),
-           &major, &minor) == 0) {
+       if (linux_vn_get_major_minor(vp, &major, &minor) == 0)
                sb->st_rdev = (major << 8 | minor);
-       }
 }
 
 static int
@@ -140,9 +137,7 @@ translate_fd_major_minor(struct thread *td, int fd, st
                if (mp != NULL && mp->mnt_vfc == rootdevmp->mnt_vfc)
                        buf->st_dev = rootdevmp->mnt_stat.f_fsid.val[0];
        }
-       if (vp != NULL && vp->v_rdev != NULL &&
-           linux_driver_get_major_minor(devtoname(vp->v_rdev),
-                                        &major, &minor) == 0) {
+       if (linux_vn_get_major_minor(vp, &major, &minor) == 0) {
                buf->st_rdev = (major << 8 | minor);
        } else if (fp->f_type == DTYPE_PTS) {
                struct tty *tp = fp->f_data;

Modified: head/sys/compat/linux/linux_util.c
==============================================================================
--- head/sys/compat/linux/linux_util.c  Tue Oct 20 17:00:43 2020        
(r366898)
+++ head/sys/compat/linux/linux_util.c  Tue Oct 20 17:19:10 2020        
(r366899)
@@ -36,6 +36,7 @@ __FBSDID("$FreeBSD$");
 
 #include <sys/param.h>
 #include <sys/bus.h>
+#include <sys/conf.h>
 #include <sys/fcntl.h>
 #include <sys/lock.h>
 #include <sys/malloc.h>
@@ -193,6 +194,24 @@ linux_driver_get_major_minor(const char *node, int *ma
        }
 
        return (1);
+}
+
+int
+linux_vn_get_major_minor(const struct vnode *vp, int *major, int *minor)
+{
+       int error;
+
+       if (vp->v_type != VCHR)
+               return (ENOTBLK);
+       dev_lock();
+       if (vp->v_rdev == NULL) {
+               dev_unlock();
+               return (ENXIO);
+       }
+       error = linux_driver_get_major_minor(devtoname(vp->v_rdev),
+           major, minor);
+       dev_unlock();
+       return (error);
 }
 
 char *

Modified: head/sys/compat/linux/linux_util.h
==============================================================================
--- head/sys/compat/linux/linux_util.h  Tue Oct 20 17:00:43 2020        
(r366898)
+++ head/sys/compat/linux/linux_util.h  Tue Oct 20 17:19:10 2020        
(r366899)
@@ -123,6 +123,7 @@ int linux_device_register_handler(struct linux_device_
 int    linux_device_unregister_handler(struct linux_device_handler *h);
 char   *linux_driver_get_name_dev(device_t dev);
 int    linux_driver_get_major_minor(const char *node, int *major, int *minor);
+int    linux_vn_get_major_minor(const struct vnode *vn, int *major, int 
*minor);
 char   *linux_get_char_devices(void);
 void   linux_free_get_char_devices(char *string);
 
_______________________________________________
svn-src-head@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to