From 06518ce4b19ccd4762d5985970b0e06b71280b56 Mon Sep 17 00:00:00 2001 From: ed Date: Sat, 31 May 2008 14:06:37 +0000 Subject: Merge back devfs changes from the mpsafetty branch. In the mpsafetty branch, PTY's are allocated through the posix_openpt() system call. The controller side of a PTY now uses its own file descriptor type (just like sockets, vnodes, pipes, etc). To remain compatible with existing FreeBSD and Linux C libraries, we can still create PTY's by opening /dev/ptmx or /dev/ptyXX. These nodes implement d_fdopen(). Devfs has been slightly changed here, to allow finit() to be called from d_fdopen(). The routine grantpt() has also been moved into the kernel. This routine is a little odd, because it needs to bypass standard UNIX permissions. It needs to change the owner/group/mode of the slave device node, which may often not be possible. The old implementation solved this by spawning a setuid utility. When VOP_SETATTR() is called with NOCRED, devfs_setattr() dereferences ap->a_cred, causing a kernel panic. Change the de_{uid,gid,mode} code to allow changes when a->a_cred is set to NOCRED. Approved by: philip (mentor) --- sys/fs/devfs/devfs_vnops.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'sys/fs/devfs') diff --git a/sys/fs/devfs/devfs_vnops.c b/sys/fs/devfs/devfs_vnops.c index 80f2dba..724f082 100644 --- a/sys/fs/devfs/devfs_vnops.c +++ b/sys/fs/devfs/devfs_vnops.c @@ -891,9 +891,8 @@ devfs_open(struct vop_open_args *ap) if(fp == NULL) return (error); #endif - KASSERT(fp->f_ops == &badfileops, - ("Could not vnode bypass device on fdops %p", fp->f_ops)); - finit(fp, fp->f_flag, DTYPE_VNODE, dev, &devfs_ops_f); + if (fp->f_ops == &badfileops) + finit(fp, fp->f_flag, DTYPE_VNODE, dev, &devfs_ops_f); return (error); } @@ -1265,8 +1264,9 @@ devfs_setattr(struct vop_setattr_args *ap) else gid = vap->va_gid; if (uid != de->de_uid || gid != de->de_gid) { - if ((ap->a_cred->cr_uid != de->de_uid) || uid != de->de_uid || - (gid != de->de_gid && !groupmember(gid, ap->a_cred))) { + if (ap->a_cred != NOCRED && + (ap->a_cred->cr_uid != de->de_uid || uid != de->de_uid || + (gid != de->de_gid && !groupmember(gid, ap->a_cred)))) { error = priv_check(ap->a_td, PRIV_VFS_CHOWN); if (error) return (error); @@ -1277,7 +1277,7 @@ devfs_setattr(struct vop_setattr_args *ap) } if (vap->va_mode != (mode_t)VNOVAL) { - if (ap->a_cred->cr_uid != de->de_uid) { + if (ap->a_cred != NOCRED && ap->a_cred->cr_uid != de->de_uid) { error = priv_check(ap->a_td, PRIV_VFS_ADMIN); if (error) return (error); -- cgit v1.1