diff options
-rw-r--r-- | sys/fs/devfs/devfs_devs.c | 9 | ||||
-rw-r--r-- | sys/fs/devfs/devfs_vnops.c | 60 | ||||
-rw-r--r-- | sys/kern/kern_conf.c | 35 |
3 files changed, 64 insertions, 40 deletions
diff --git a/sys/fs/devfs/devfs_devs.c b/sys/fs/devfs/devfs_devs.c index e9c2a55..761caa5 100644 --- a/sys/fs/devfs/devfs_devs.c +++ b/sys/fs/devfs/devfs_devs.c @@ -114,6 +114,8 @@ struct devfs_dirent ** devfs_itode (struct devfs_mount *dm, int inode) { + if (inode < 0) + return (NULL); if (inode < NDEVFSINO) return (&dm->dm_dirent[inode]); if (devfs_overflow == NULL) @@ -127,6 +129,8 @@ struct cdev ** devfs_itod (int inode) { + if (inode < 0) + return (NULL); if (inode < NDEVFSINO) return (&devfs_inot[inode]); if (devfs_overflow == NULL) @@ -270,10 +274,7 @@ devfs_populate(struct devfs_mount *dm) if (dev == NULL && de != NULL) { dd = de->de_dir; *dep = NULL; - TAILQ_REMOVE(&dd->de_dlist, de, de_list); - if (de->de_vnode) - de->de_vnode->v_data = NULL; - FREE(de, M_DEVFS); + devfs_delete(dd, de); devfs_dropref(i); continue; } diff --git a/sys/fs/devfs/devfs_vnops.c b/sys/fs/devfs/devfs_vnops.c index 09a978a..dbce518 100644 --- a/sys/fs/devfs/devfs_vnops.c +++ b/sys/fs/devfs/devfs_vnops.c @@ -61,6 +61,7 @@ #include <sys/proc.h> #include <sys/stat.h> #include <sys/sx.h> +#include <sys/sysctl.h> #include <sys/time.h> #include <sys/ttycom.h> #include <sys/unistd.h> @@ -113,6 +114,25 @@ static vop_symlink_t devfs_symlink; extern struct vop_vector devfs_vnodeops; extern struct vop_vector devfs_specops; +static u_int +devfs_random(void) +{ + static u_int devfs_seed; + + while (devfs_seed == 0) { + /* + * Make sure people don't make stupid assumptions + * about device major/minor numbers in userspace. + * We do this late to get entropy and for the same + * reason we force a reseed, but it may not be + * late enough for entropy to be available. + */ + arc4rand(&devfs_seed, sizeof devfs_seed, 1); + devfs_seed &= 0xf0f; + } + return (devfs_seed); +} + static int devfs_fp_check(struct file *fp, struct cdev **devp, struct cdevsw **dswp) { @@ -441,7 +461,8 @@ devfs_getattr(ap) vap->va_mtime = dev->si_mtime; fix(dev->si_ctime); vap->va_ctime = dev->si_ctime; - vap->va_rdev = dev->si_udev; + + vap->va_rdev = de->de_inode ^ devfs_random(); } vap->va_gen = 0; vap->va_flags = 0; @@ -1432,6 +1453,43 @@ static struct vop_vector devfs_specops = { .vop_write = VOP_PANIC, }; +dev_t +dev2udev(struct cdev *x) +{ + if (x == NULL) + return (NODEV); + return (x->si_inode ^ devfs_random()); +} + +/* + * Helper sysctl for devname(3). We're given a struct cdev * and return + * the name, if any, registered by the device driver. + */ +static int +sysctl_devname(SYSCTL_HANDLER_ARGS) +{ + int error; + dev_t ud; + struct cdev *dev, **dp; + + error = SYSCTL_IN(req, &ud, sizeof (ud)); + if (error) + return (error); + if (ud == NODEV) + return(EINVAL); + dp = devfs_itod(ud ^ devfs_random()); + if (dp == NULL) + return(ENOENT); + dev = *dp; + if (dev == NULL) + return(ENOENT); + return(SYSCTL_OUT(req, dev->si_name, strlen(dev->si_name) + 1)); + return (error); +} + +SYSCTL_PROC(_kern, OID_AUTO, devname, CTLTYPE_OPAQUE|CTLFLAG_RW|CTLFLAG_ANYBODY, + NULL, 0, sysctl_devname, "", "devname(3) handler"); + /* * Our calling convention to the device drivers used to be that we passed * vnode.h IO_* flags to read()/write(), but we're moving to fcntl.h O_ diff --git a/sys/kern/kern_conf.c b/sys/kern/kern_conf.c index bd71a8d..dc2d3d4 100644 --- a/sys/kern/kern_conf.c +++ b/sys/kern/kern_conf.c @@ -317,14 +317,6 @@ freedev(struct cdev *dev) free(dev, M_DEVT); } -dev_t -dev2udev(struct cdev *x) -{ - if (x == NULL) - return (NODEV); - return (x->si_udev); -} - struct cdev * findcdev(dev_t udev) { @@ -792,30 +784,3 @@ clone_cleanup(struct clonedevs **cdp) free(cd, M_DEVBUF); *cdp = NULL; } - -/* - * Helper sysctl for devname(3). We're given a struct cdev * and return - * the name, if any, registered by the device driver. - */ -static int -sysctl_devname(SYSCTL_HANDLER_ARGS) -{ - int error; - dev_t ud; - struct cdev *dev; - - error = SYSCTL_IN(req, &ud, sizeof (ud)); - if (error) - return (error); - if (ud == NODEV) - return(EINVAL); - dev = findcdev(ud); - if (dev == NULL) - error = ENOENT; - else - error = SYSCTL_OUT(req, dev->si_name, strlen(dev->si_name) + 1); - return (error); -} - -SYSCTL_PROC(_kern, OID_AUTO, devname, CTLTYPE_OPAQUE|CTLFLAG_RW|CTLFLAG_ANYBODY, - NULL, 0, sysctl_devname, "", "devname(3) handler"); |