Mercurial > illumos > illumos-gate
changeset 3442:770844b0f91a
6445040 add_drv/update_drv/rem_drv should use advisory record locking
6467524 Add a check to /dev/pts code to test for realvp
6509851 change name of PT_OWNER ioctl to OWNERPT
author | vikram |
---|---|
date | Thu, 18 Jan 2007 13:37:08 -0800 |
parents | 00abce5a0b16 |
children | e0e00ef6cee8 |
files | usr/src/cmd/modload/drvsubr.c usr/src/cmd/modload/errmsg.h usr/src/cmd/truss/codes.c usr/src/lib/brand/lx/lx_brand/common/ioctl.c usr/src/lib/libc/port/gen/pt.c usr/src/uts/common/fs/dev/sdev_ptsops.c usr/src/uts/common/io/ptm.c usr/src/uts/common/sys/ptms.h |
diffstat | 8 files changed, 74 insertions(+), 42 deletions(-) [+] |
line wrap: on
line diff
--- a/usr/src/cmd/modload/drvsubr.c Thu Jan 18 08:49:43 2007 -0800 +++ b/usr/src/cmd/modload/drvsubr.c Thu Jan 18 13:37:08 2007 -0800 @@ -19,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #pragma ident "%Z%%M% %I% %E% SMI" @@ -45,6 +45,7 @@ static char *add_rem_lock; /* lock file */ static char *tmphold; /* temperary file for updating */ +static int add_rem_lock_fd = -1; static int get_cached_n_to_m_file(char *filename, char ***cache); static int get_name_to_major_entry(int *major_no, char *driver_name, @@ -648,39 +649,36 @@ return (ptr); } -/*ARGSUSED0*/ -static void -signal_rtn(int sig) -{ - exit_unlock(); -} - void enter_lock(void) { - int fd; - - /* - * Setup handler to clean lock file in case user terminates - * the command. - */ - (void) sigset(SIGINT, signal_rtn); - (void) sigset(SIGHUP, signal_rtn); - (void) sigset(SIGTERM, signal_rtn); + struct flock lock; /* * attempt to create the lock file */ - if ((fd = open(add_rem_lock, O_CREAT | O_EXCL | O_WRONLY, - S_IRUSR | S_IWUSR)) == -1) { - if (errno == EEXIST) { + add_rem_lock_fd = open(add_rem_lock, O_CREAT|O_RDWR, S_IRUSR|S_IWUSR); + if (add_rem_lock_fd < 0) { + (void) fprintf(stderr, gettext(ERR_CREAT_LOCK), + add_rem_lock, strerror(errno)); + exit(1); + } + + lock.l_type = F_WRLCK; + lock.l_whence = SEEK_SET; + lock.l_start = 0; + lock.l_len = 0; + + /* Try for the lock but don't wait. */ + if (fcntl(add_rem_lock_fd, F_SETLK, &lock) == -1) { + if (errno == EACCES || errno == EAGAIN) { (void) fprintf(stderr, gettext(ERR_PROG_IN_USE)); } else { - perror(gettext(ERR_LOCKFILE)); + (void) fprintf(stderr, gettext(ERR_LOCK), + add_rem_lock, strerror(errno)); } exit(1); } - (void) close(fd); } void @@ -709,13 +707,22 @@ void exit_unlock(void) { - struct stat buf; + struct flock unlock; + + if (add_rem_lock_fd < 0) + return; - if (stat(add_rem_lock, &buf) == NOERR) { - if (unlink(add_rem_lock) == -1) { - (void) fprintf(stderr, gettext(ERR_REM_LOCK), - add_rem_lock); - } + unlock.l_type = F_UNLCK; + unlock.l_whence = SEEK_SET; + unlock.l_start = 0; + unlock.l_len = 0; + + if (fcntl(add_rem_lock_fd, F_SETLK, &unlock) == -1) { + (void) fprintf(stderr, gettext(ERR_UNLOCK), + add_rem_lock, strerror(errno)); + } else { + (void) close(add_rem_lock_fd); + add_rem_lock_fd = -1; } }
--- a/usr/src/cmd/modload/errmsg.h Thu Jan 18 08:49:43 2007 -0800 +++ b/usr/src/cmd/modload/errmsg.h Thu Jan 18 13:37:08 2007 -0800 @@ -19,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -59,7 +59,6 @@ #define ERR_ALIAS_IN_NAM_MAJ "Alias (%s) already in use as driver name.\n" #define ERR_ALIAS_IN_USE "(%s) already in use as a driver or alias.\n" #define ERR_CANT_ACCESS_FILE "Cannot access file (%s).\n" -#define ERR_REM_LOCK "Cannot remove lockfile (%s). Remove by hand.\n" #define ERR_BAD_PATH "Bad syntax for pathname : (%s)\n" #define ERR_FORK_FAIL "Fork failed; cannot exec : %s\n" #define ERR_PROG_IN_USE "add_drv/rem_drv currently busy; try later\n" @@ -95,7 +94,10 @@ "Warning: Major number (%d) inconsistent with /etc/name_to_major file.\n" #define ERR_MAJ_TOOBIG "Warning: Entry '%s %llu' in %s has a major number " \ "larger\nthan the maximum allowed value %u.\n" -#define ERR_LOCKFILE "Failed to create lock file.\n" + +#define ERR_CREAT_LOCK "Failed to create lock file(%s): %s\n" +#define ERR_LOCK "Failed to lock the lock file(%s): %s\n" +#define ERR_UNLOCK "Failed to unlock the lock file(%s): %s\n" #define ERR_LOCATION \ "Warning: %s-bit version of driver found at %s.\n"
--- a/usr/src/cmd/truss/codes.c Thu Jan 18 08:49:43 2007 -0800 +++ b/usr/src/cmd/truss/codes.c Thu Jan 18 13:37:08 2007 -0800 @@ -19,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -818,6 +818,7 @@ { (uint_t)UNLKPT, "UNLKPT", NULL}, { (uint_t)PTSSTTY, "PTSSTTY", NULL}, { (uint_t)ZONEPT, "ZONEPT", NULL}, + { (uint_t)OWNERPT, "OWNERPT", NULL}, /* aggr link aggregation pseudo driver ioctls */ { (uint_t)LAIOC_CREATE, "LAIOC_CREATE", "laioc_create"},
--- a/usr/src/lib/brand/lx/lx_brand/common/ioctl.c Thu Jan 18 08:49:43 2007 -0800 +++ b/usr/src/lib/brand/lx/lx_brand/common/ioctl.c Thu Jan 18 13:37:08 2007 -0800 @@ -20,7 +20,7 @@ */ /* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -1202,11 +1202,11 @@ * it assumes the fd node that's passed to it is a ptm node, * and in our case it's an lx_ptm node. It also relies on * naming services to get the current process group name. - * Hence we have to invoke the PT_OWNER ioctl directly here. + * Hence we have to invoke the OWNERPT ioctl directly here. */ pto.pto_ruid = getuid(); pto.pto_rgid = getgid(); - if (ioctl_istr(fd, PT_OWNER, "PT_OWNER", &pto, sizeof (pto)) != 0) + if (ioctl_istr(fd, OWNERPT, "OWNERPT", &pto, sizeof (pto)) != 0) return (-EACCES); /* Copy out the data. */
--- a/usr/src/lib/libc/port/gen/pt.c Thu Jan 18 08:49:43 2007 -0800 +++ b/usr/src/lib/libc/port/gen/pt.c Thu Jan 18 13:37:08 2007 -0800 @@ -19,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -156,7 +156,7 @@ else pto.pto_rgid = getgid(); - istr.ic_cmd = PT_OWNER; + istr.ic_cmd = OWNERPT; istr.ic_len = sizeof (pt_own_t); istr.ic_timout = 0; istr.ic_dp = (char *)&pto;
--- a/usr/src/uts/common/fs/dev/sdev_ptsops.c Thu Jan 18 08:49:43 2007 -0800 +++ b/usr/src/uts/common/fs/dev/sdev_ptsops.c Thu Jan 18 13:37:08 2007 -0800 @@ -19,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -274,6 +274,25 @@ * Lookup for /dev/pts directory * If the entry does not exist, the devpts_create_rvp() callback * is invoked to create it. Nodes do not persist across reboot. + * + * There is a potential denial of service here via + * fattach on top of a /dev/pts node - any permission changes + * applied to the node, apply to the fattached file and not + * to the underlying pts node. As a result when the previous + * user fdetaches, the pts node is still owned by the previous + * owner. To prevent this we don't allow fattach() on top of a pts + * node. This is done by a modification in the namefs filesystem + * where we check if the underlying node has the /dev/pts vnodeops. + * We do this via VOP_REALVP() on the underlying specfs node. + * sdev_nodes currently don't have a realvp. If a realvp is ever + * created for sdev_nodes, then VOP_REALVP() will return the + * actual realvp (possibly a ufs vnode). This will defeat the check + * in namefs code which checks if VOP_REALVP() returns a devpts + * node. We add an ASSERT here in /dev/pts lookup() to check for + * this condition. If sdev_nodes ever get a VOP_REALVP() entry point, + * change the code in the namefs filesystem code (in nm_mount()) to + * access the realvp of the specfs node directly instead of using + * VOP_REALVP(). */ /*ARGSUSED3*/ static int @@ -282,6 +301,7 @@ { struct sdev_node *sdvp = VTOSDEV(dvp); struct sdev_node *dv; + struct vnode *rvp = NULL; int error; error = devname_lookup_func(sdvp, nm, vpp, cred, devpts_create_rvp, @@ -291,6 +311,7 @@ switch ((*vpp)->v_type) { case VCHR: dv = VTOSDEV(VTOS(*vpp)->s_realvp); + ASSERT(VOP_REALVP(SDEVTOV(dv), &rvp) == ENOSYS); break; case VDIR: dv = VTOSDEV(*vpp); @@ -379,6 +400,7 @@ devpts_set_id, AT_UID|AT_GID)); } + /* * We override lookup and readdir to build entries based on the * in kernel pty table. Also override setattr/setsecattr to
--- a/usr/src/uts/common/io/ptm.c Thu Jan 18 08:49:43 2007 -0800 +++ b/usr/src/uts/common/io/ptm.c Thu Jan 18 13:37:08 2007 -0800 @@ -19,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ @@ -560,7 +560,7 @@ miocack(qp, mp, 0, 0); break; } - case PT_OWNER: + case OWNERPT: { pt_own_t *ptop; int error;
--- a/usr/src/uts/common/sys/ptms.h Thu Jan 18 08:49:43 2007 -0800 +++ b/usr/src/uts/common/sys/ptms.h Thu Jan 18 13:37:08 2007 -0800 @@ -19,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ @@ -164,7 +164,7 @@ #define UNLKPT (('P'<<8)|2) /* unlock master/slave pair */ #define PTSSTTY (('P'<<8)|3) /* set tty flag */ #define ZONEPT (('P'<<8)|4) /* set zone of master/slave pair */ -#define PT_OWNER (('P'<<8)|5) /* set owner/group for slave device */ +#define OWNERPT (('P'<<8)|5) /* set owner/group for slave device */ #ifdef _KERNEL /*