diff options
author | vikram <none@none> | 2007-01-18 13:37:08 -0800 |
---|---|---|
committer | vikram <none@none> | 2007-01-18 13:37:08 -0800 |
commit | 49e92448e558772c002444c0d92e7a31d529d046 (patch) | |
tree | 7b94e27cf3cd12b5392a5d30c228f4c10e66be53 /usr/src | |
parent | c7ce59f142277983e66b3701901be4f1c31e57c8 (diff) | |
download | illumos-joyent-49e92448e558772c002444c0d92e7a31d529d046.tar.gz |
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
Diffstat (limited to 'usr/src')
-rw-r--r-- | usr/src/cmd/modload/drvsubr.c | 63 | ||||
-rw-r--r-- | usr/src/cmd/modload/errmsg.h | 8 | ||||
-rw-r--r-- | usr/src/cmd/truss/codes.c | 3 | ||||
-rw-r--r-- | usr/src/lib/brand/lx/lx_brand/common/ioctl.c | 6 | ||||
-rw-r--r-- | usr/src/lib/libc/port/gen/pt.c | 4 | ||||
-rw-r--r-- | usr/src/uts/common/fs/dev/sdev_ptsops.c | 24 | ||||
-rw-r--r-- | usr/src/uts/common/io/ptm.c | 4 | ||||
-rw-r--r-- | usr/src/uts/common/sys/ptms.h | 4 |
8 files changed, 74 insertions, 42 deletions
diff --git a/usr/src/cmd/modload/drvsubr.c b/usr/src/cmd/modload/drvsubr.c index 00c4a03786..f1fb38add3 100644 --- a/usr/src/cmd/modload/drvsubr.c +++ b/usr/src/cmd/modload/drvsubr.c @@ -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 @@ get_entry( 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 @@ cleanup_moddir(void) void exit_unlock(void) { - struct stat buf; + struct flock unlock; - if (stat(add_rem_lock, &buf) == NOERR) { - if (unlink(add_rem_lock) == -1) { - (void) fprintf(stderr, gettext(ERR_REM_LOCK), - add_rem_lock); - } + if (add_rem_lock_fd < 0) + return; + + 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; } } diff --git a/usr/src/cmd/modload/errmsg.h b/usr/src/cmd/modload/errmsg.h index bc41755678..6412f4d24b 100644 --- a/usr/src/cmd/modload/errmsg.h +++ b/usr/src/cmd/modload/errmsg.h @@ -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 @@ extern "C" { #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 @@ extern "C" { "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" diff --git a/usr/src/cmd/truss/codes.c b/usr/src/cmd/truss/codes.c index fe5a173211..b27be91c7b 100644 --- a/usr/src/cmd/truss/codes.c +++ b/usr/src/cmd/truss/codes.c @@ -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 @@ const struct ioc { { (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"}, diff --git a/usr/src/lib/brand/lx/lx_brand/common/ioctl.c b/usr/src/lib/brand/lx/lx_brand/common/ioctl.c index b6a6b79ad1..f9b2668700 100644 --- a/usr/src/lib/brand/lx/lx_brand/common/ioctl.c +++ b/usr/src/lib/brand/lx/lx_brand/common/ioctl.c @@ -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 @@ ict_gptn(int fd, struct stat *stat, int cmd, char *cmd_str, intptr_t arg) * 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. */ diff --git a/usr/src/lib/libc/port/gen/pt.c b/usr/src/lib/libc/port/gen/pt.c index 86bcd319c3..1272c947eb 100644 --- a/usr/src/lib/libc/port/gen/pt.c +++ b/usr/src/lib/libc/port/gen/pt.c @@ -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 @@ grantpt(int fd) 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; diff --git a/usr/src/uts/common/fs/dev/sdev_ptsops.c b/usr/src/uts/common/fs/dev/sdev_ptsops.c index 9ab5cf8881..50ed639ddb 100644 --- a/usr/src/uts/common/fs/dev/sdev_ptsops.c +++ b/usr/src/uts/common/fs/dev/sdev_ptsops.c @@ -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 @@ devpts_prunedir(struct sdev_node *ddv) * 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 @@ devpts_lookup(struct vnode *dvp, char *nm, struct vnode **vpp, { 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 @@ devpts_lookup(struct vnode *dvp, char *nm, struct vnode **vpp, 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_setattr(struct vnode *vp, struct vattr *vap, int flags, 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 diff --git a/usr/src/uts/common/io/ptm.c b/usr/src/uts/common/io/ptm.c index 7910b58cc8..aaa4886069 100644 --- a/usr/src/uts/common/io/ptm.c +++ b/usr/src/uts/common/io/ptm.c @@ -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 @@ ptmwput(queue_t *qp, mblk_t *mp) miocack(qp, mp, 0, 0); break; } - case PT_OWNER: + case OWNERPT: { pt_own_t *ptop; int error; diff --git a/usr/src/uts/common/sys/ptms.h b/usr/src/uts/common/sys/ptms.h index 120503539b..458022ebc8 100644 --- a/usr/src/uts/common/sys/ptms.h +++ b/usr/src/uts/common/sys/ptms.h @@ -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 @@ typedef struct pt_own { #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 /* |