Clear the p_stops field on change of user/group id, unless the correct
flag is set in the p_pfsflags field. This, essentially, prevents an SUID proram from hanging after being traced. (E.g., "truss /usr/bin/rlogin" would fail, but leave rlogin in a stopevent state.) Yet another case where procctl is (hopefully ;)) no longer needed in the general case. Reviewed by: bde (thanks bruce :))
This commit is contained in:
parent
e9263ed667
commit
915794d267
@ -36,7 +36,7 @@
|
|||||||
*
|
*
|
||||||
* @(#)procfs_vnops.c 8.18 (Berkeley) 5/21/95
|
* @(#)procfs_vnops.c 8.18 (Berkeley) 5/21/95
|
||||||
*
|
*
|
||||||
* $Id: procfs_vnops.c,v 1.47 1997/12/12 03:33:43 sef Exp $
|
* $Id: procfs_vnops.c,v 1.48 1997/12/13 03:13:46 sef Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -224,11 +224,13 @@ procfs_ioctl(ap)
|
|||||||
struct vop_ioctl_args *ap;
|
struct vop_ioctl_args *ap;
|
||||||
{
|
{
|
||||||
struct pfsnode *pfs = VTOPFS(ap->a_vp);
|
struct pfsnode *pfs = VTOPFS(ap->a_vp);
|
||||||
struct proc *procp;
|
struct proc *procp, *p;
|
||||||
int error;
|
int error;
|
||||||
int signo;
|
int signo;
|
||||||
struct procfs_status *psp;
|
struct procfs_status *psp;
|
||||||
|
unsigned char flags;
|
||||||
|
|
||||||
|
p = ap->a_p;
|
||||||
procp = pfind(pfs->pfs_pid);
|
procp = pfind(pfs->pfs_pid);
|
||||||
if (procp == NULL) {
|
if (procp == NULL) {
|
||||||
return ENOTTY;
|
return ENOTTY;
|
||||||
@ -242,7 +244,15 @@ procfs_ioctl(ap)
|
|||||||
procp->p_stops &= ~*(unsigned int*)ap->a_data;
|
procp->p_stops &= ~*(unsigned int*)ap->a_data;
|
||||||
break;
|
break;
|
||||||
case PIOCSFL:
|
case PIOCSFL:
|
||||||
procp->p_pfsflags = (unsigned char)*(unsigned int*)ap->a_data;
|
/*
|
||||||
|
* NFLAGS is "non-suser flags" -- currently, only
|
||||||
|
* PFS_ISUGID ("ignore set u/g id");
|
||||||
|
*/
|
||||||
|
#define NFLAGS (PF_ISUGID)
|
||||||
|
flags = (unsigned char)*(unsigned int*)ap->a_data;
|
||||||
|
if (flags & NFLAGS && (error = suser(p->p_ucred, &p->p_acflag)))
|
||||||
|
return error;
|
||||||
|
procp->p_pfsflags = flags;
|
||||||
break;
|
break;
|
||||||
case PIOCGFL:
|
case PIOCGFL:
|
||||||
*(unsigned int*)ap->a_data = (unsigned int)procp->p_pfsflags;
|
*(unsigned int*)ap->a_data = (unsigned int)procp->p_pfsflags;
|
||||||
|
@ -23,7 +23,7 @@
|
|||||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
* SUCH DAMAGE.
|
* SUCH DAMAGE.
|
||||||
*
|
*
|
||||||
* $Id: kern_exec.c,v 1.69 1997/12/06 04:11:09 sef Exp $
|
* $Id: kern_exec.c,v 1.70 1997/12/16 15:40:29 davidg Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
@ -313,7 +313,7 @@ execve(p, uap)
|
|||||||
p->p_ucred->cr_uid = attr.va_uid;
|
p->p_ucred->cr_uid = attr.va_uid;
|
||||||
if (attr.va_mode & VSGID)
|
if (attr.va_mode & VSGID)
|
||||||
p->p_ucred->cr_gid = attr.va_gid;
|
p->p_ucred->cr_gid = attr.va_gid;
|
||||||
p->p_flag |= P_SUGID;
|
setsugid(p);
|
||||||
} else {
|
} else {
|
||||||
if (p->p_ucred->cr_uid == p->p_cred->p_ruid &&
|
if (p->p_ucred->cr_uid == p->p_cred->p_ruid &&
|
||||||
p->p_ucred->cr_gid == p->p_cred->p_rgid)
|
p->p_ucred->cr_gid == p->p_cred->p_rgid)
|
||||||
|
@ -36,7 +36,7 @@
|
|||||||
* SUCH DAMAGE.
|
* SUCH DAMAGE.
|
||||||
*
|
*
|
||||||
* @(#)kern_prot.c 8.6 (Berkeley) 1/21/94
|
* @(#)kern_prot.c 8.6 (Berkeley) 1/21/94
|
||||||
* $Id: kern_prot.c,v 1.37 1997/11/06 19:29:12 phk Exp $
|
* $Id: kern_prot.c,v 1.38 1997/12/16 17:40:16 eivind Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -52,6 +52,7 @@
|
|||||||
#include <sys/proc.h>
|
#include <sys/proc.h>
|
||||||
#include <sys/malloc.h>
|
#include <sys/malloc.h>
|
||||||
#include <sys/unistd.h>
|
#include <sys/unistd.h>
|
||||||
|
#include <sys/pioctl.h>
|
||||||
|
|
||||||
static MALLOC_DEFINE(M_CRED, "cred", "credentials");
|
static MALLOC_DEFINE(M_CRED, "cred", "credentials");
|
||||||
|
|
||||||
@ -413,8 +414,8 @@ setuid(p, uap)
|
|||||||
* Set real uid
|
* Set real uid
|
||||||
*/
|
*/
|
||||||
if (uid != pc->p_ruid) {
|
if (uid != pc->p_ruid) {
|
||||||
p->p_flag |= P_SUGID;
|
|
||||||
pc->p_ruid = uid;
|
pc->p_ruid = uid;
|
||||||
|
setsugid(p);
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
* Set saved uid
|
* Set saved uid
|
||||||
@ -424,8 +425,8 @@ setuid(p, uap)
|
|||||||
* is important that we should do this.
|
* is important that we should do this.
|
||||||
*/
|
*/
|
||||||
if (pc->p_svuid != uid) {
|
if (pc->p_svuid != uid) {
|
||||||
p->p_flag |= P_SUGID;
|
|
||||||
pc->p_svuid = uid;
|
pc->p_svuid = uid;
|
||||||
|
setsugid(p);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -436,7 +437,7 @@ setuid(p, uap)
|
|||||||
if (pc->pc_ucred->cr_uid != uid) {
|
if (pc->pc_ucred->cr_uid != uid) {
|
||||||
pc->pc_ucred = crcopy(pc->pc_ucred);
|
pc->pc_ucred = crcopy(pc->pc_ucred);
|
||||||
pc->pc_ucred->cr_uid = uid;
|
pc->pc_ucred->cr_uid = uid;
|
||||||
p->p_flag |= P_SUGID;
|
setsugid(p);
|
||||||
}
|
}
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
@ -468,7 +469,7 @@ seteuid(p, uap)
|
|||||||
if (pc->pc_ucred->cr_uid != euid) {
|
if (pc->pc_ucred->cr_uid != euid) {
|
||||||
pc->pc_ucred = crcopy(pc->pc_ucred);
|
pc->pc_ucred = crcopy(pc->pc_ucred);
|
||||||
pc->pc_ucred->cr_uid = euid;
|
pc->pc_ucred->cr_uid = euid;
|
||||||
p->p_flag |= P_SUGID;
|
setsugid(p);
|
||||||
}
|
}
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
@ -526,8 +527,8 @@ setgid(p, uap)
|
|||||||
* Set real gid
|
* Set real gid
|
||||||
*/
|
*/
|
||||||
if (pc->p_rgid != gid) {
|
if (pc->p_rgid != gid) {
|
||||||
p->p_flag |= P_SUGID;
|
|
||||||
pc->p_rgid = gid;
|
pc->p_rgid = gid;
|
||||||
|
setsugid(p);
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
* Set saved gid
|
* Set saved gid
|
||||||
@ -537,8 +538,8 @@ setgid(p, uap)
|
|||||||
* is important that we should do this.
|
* is important that we should do this.
|
||||||
*/
|
*/
|
||||||
if (pc->p_svgid != gid) {
|
if (pc->p_svgid != gid) {
|
||||||
p->p_flag |= P_SUGID;
|
|
||||||
pc->p_svgid = gid;
|
pc->p_svgid = gid;
|
||||||
|
setsugid(p);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
@ -548,7 +549,7 @@ setgid(p, uap)
|
|||||||
if (pc->pc_ucred->cr_groups[0] != gid) {
|
if (pc->pc_ucred->cr_groups[0] != gid) {
|
||||||
pc->pc_ucred = crcopy(pc->pc_ucred);
|
pc->pc_ucred = crcopy(pc->pc_ucred);
|
||||||
pc->pc_ucred->cr_groups[0] = gid;
|
pc->pc_ucred->cr_groups[0] = gid;
|
||||||
p->p_flag |= P_SUGID;
|
setsugid(p);
|
||||||
}
|
}
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
@ -576,7 +577,7 @@ setegid(p, uap)
|
|||||||
if (pc->pc_ucred->cr_groups[0] != egid) {
|
if (pc->pc_ucred->cr_groups[0] != egid) {
|
||||||
pc->pc_ucred = crcopy(pc->pc_ucred);
|
pc->pc_ucred = crcopy(pc->pc_ucred);
|
||||||
pc->pc_ucred->cr_groups[0] = egid;
|
pc->pc_ucred->cr_groups[0] = egid;
|
||||||
p->p_flag |= P_SUGID;
|
setsugid(p);
|
||||||
}
|
}
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
@ -621,7 +622,7 @@ setgroups(p, uap)
|
|||||||
return (error);
|
return (error);
|
||||||
pc->pc_ucred->cr_ngroups = ngrp;
|
pc->pc_ucred->cr_ngroups = ngrp;
|
||||||
}
|
}
|
||||||
p->p_flag |= P_SUGID;
|
setsugid(p);
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -652,18 +653,18 @@ setreuid(p, uap)
|
|||||||
if (euid != (uid_t)-1 && pc->pc_ucred->cr_uid != euid) {
|
if (euid != (uid_t)-1 && pc->pc_ucred->cr_uid != euid) {
|
||||||
pc->pc_ucred = crcopy(pc->pc_ucred);
|
pc->pc_ucred = crcopy(pc->pc_ucred);
|
||||||
pc->pc_ucred->cr_uid = euid;
|
pc->pc_ucred->cr_uid = euid;
|
||||||
p->p_flag |= P_SUGID;
|
setsugid(p);
|
||||||
}
|
}
|
||||||
if (ruid != (uid_t)-1 && pc->p_ruid != ruid) {
|
if (ruid != (uid_t)-1 && pc->p_ruid != ruid) {
|
||||||
(void)chgproccnt(pc->p_ruid, -1);
|
(void)chgproccnt(pc->p_ruid, -1);
|
||||||
(void)chgproccnt(ruid, 1);
|
(void)chgproccnt(ruid, 1);
|
||||||
pc->p_ruid = ruid;
|
pc->p_ruid = ruid;
|
||||||
p->p_flag |= P_SUGID;
|
setsugid(p);
|
||||||
}
|
}
|
||||||
if ((ruid != (uid_t)-1 || pc->pc_ucred->cr_uid != pc->p_ruid) &&
|
if ((ruid != (uid_t)-1 || pc->pc_ucred->cr_uid != pc->p_ruid) &&
|
||||||
pc->p_svuid != pc->pc_ucred->cr_uid) {
|
pc->p_svuid != pc->pc_ucred->cr_uid) {
|
||||||
pc->p_svuid = pc->pc_ucred->cr_uid;
|
pc->p_svuid = pc->pc_ucred->cr_uid;
|
||||||
p->p_flag |= P_SUGID;
|
setsugid(p);
|
||||||
}
|
}
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
@ -695,16 +696,16 @@ setregid(p, uap)
|
|||||||
if (egid != (gid_t)-1 && pc->pc_ucred->cr_groups[0] != egid) {
|
if (egid != (gid_t)-1 && pc->pc_ucred->cr_groups[0] != egid) {
|
||||||
pc->pc_ucred = crcopy(pc->pc_ucred);
|
pc->pc_ucred = crcopy(pc->pc_ucred);
|
||||||
pc->pc_ucred->cr_groups[0] = egid;
|
pc->pc_ucred->cr_groups[0] = egid;
|
||||||
p->p_flag |= P_SUGID;
|
setsugid(p);
|
||||||
}
|
}
|
||||||
if (rgid != (gid_t)-1 && pc->p_rgid != rgid) {
|
if (rgid != (gid_t)-1 && pc->p_rgid != rgid) {
|
||||||
pc->p_rgid = rgid;
|
pc->p_rgid = rgid;
|
||||||
p->p_flag |= P_SUGID;
|
setsugid(p);
|
||||||
}
|
}
|
||||||
if ((rgid != (gid_t)-1 || pc->pc_ucred->cr_groups[0] != pc->p_rgid) &&
|
if ((rgid != (gid_t)-1 || pc->pc_ucred->cr_groups[0] != pc->p_rgid) &&
|
||||||
pc->p_svgid != pc->pc_ucred->cr_groups[0]) {
|
pc->p_svgid != pc->pc_ucred->cr_groups[0]) {
|
||||||
pc->p_svgid = pc->pc_ucred->cr_groups[0];
|
pc->p_svgid = pc->pc_ucred->cr_groups[0];
|
||||||
p->p_flag |= P_SUGID;
|
setsugid(p);
|
||||||
}
|
}
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
@ -879,3 +880,12 @@ setlogin(p, uap)
|
|||||||
sizeof(logintmp));
|
sizeof(logintmp));
|
||||||
return (error);
|
return (error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
setsugid(p)
|
||||||
|
struct proc *p;
|
||||||
|
{
|
||||||
|
p->p_flag |= P_SUGID;
|
||||||
|
if (!(p->p_pfsflags & PF_ISUGID))
|
||||||
|
p->p_stops = 0;
|
||||||
|
}
|
||||||
|
@ -36,7 +36,7 @@
|
|||||||
*
|
*
|
||||||
* @(#)procfs_vnops.c 8.18 (Berkeley) 5/21/95
|
* @(#)procfs_vnops.c 8.18 (Berkeley) 5/21/95
|
||||||
*
|
*
|
||||||
* $Id: procfs_vnops.c,v 1.47 1997/12/12 03:33:43 sef Exp $
|
* $Id: procfs_vnops.c,v 1.48 1997/12/13 03:13:46 sef Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -224,11 +224,13 @@ procfs_ioctl(ap)
|
|||||||
struct vop_ioctl_args *ap;
|
struct vop_ioctl_args *ap;
|
||||||
{
|
{
|
||||||
struct pfsnode *pfs = VTOPFS(ap->a_vp);
|
struct pfsnode *pfs = VTOPFS(ap->a_vp);
|
||||||
struct proc *procp;
|
struct proc *procp, *p;
|
||||||
int error;
|
int error;
|
||||||
int signo;
|
int signo;
|
||||||
struct procfs_status *psp;
|
struct procfs_status *psp;
|
||||||
|
unsigned char flags;
|
||||||
|
|
||||||
|
p = ap->a_p;
|
||||||
procp = pfind(pfs->pfs_pid);
|
procp = pfind(pfs->pfs_pid);
|
||||||
if (procp == NULL) {
|
if (procp == NULL) {
|
||||||
return ENOTTY;
|
return ENOTTY;
|
||||||
@ -242,7 +244,15 @@ procfs_ioctl(ap)
|
|||||||
procp->p_stops &= ~*(unsigned int*)ap->a_data;
|
procp->p_stops &= ~*(unsigned int*)ap->a_data;
|
||||||
break;
|
break;
|
||||||
case PIOCSFL:
|
case PIOCSFL:
|
||||||
procp->p_pfsflags = (unsigned char)*(unsigned int*)ap->a_data;
|
/*
|
||||||
|
* NFLAGS is "non-suser flags" -- currently, only
|
||||||
|
* PFS_ISUGID ("ignore set u/g id");
|
||||||
|
*/
|
||||||
|
#define NFLAGS (PF_ISUGID)
|
||||||
|
flags = (unsigned char)*(unsigned int*)ap->a_data;
|
||||||
|
if (flags & NFLAGS && (error = suser(p->p_ucred, &p->p_acflag)))
|
||||||
|
return error;
|
||||||
|
procp->p_pfsflags = flags;
|
||||||
break;
|
break;
|
||||||
case PIOCGFL:
|
case PIOCGFL:
|
||||||
*(unsigned int*)ap->a_data = (unsigned int)procp->p_pfsflags;
|
*(unsigned int*)ap->a_data = (unsigned int)procp->p_pfsflags;
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* procfs ioctl definitions.
|
* procfs ioctl definitions.
|
||||||
*
|
*
|
||||||
* $Id: pioctl.h,v 1.4 1997/12/13 03:13:36 sef Exp $
|
* $Id: pioctl.h,v 1.5 1997/12/15 00:29:41 sef Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _SYS_PIOCTL_H
|
#ifndef _SYS_PIOCTL_H
|
||||||
@ -41,5 +41,5 @@ struct procfs_status {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
# define PF_LINGER 0x01 /* Keep stops around after last close */
|
# define PF_LINGER 0x01 /* Keep stops around after last close */
|
||||||
|
# define PF_ISUGID 0x02 /* Ignore UID/GID changes */
|
||||||
#endif
|
#endif
|
||||||
|
@ -36,7 +36,7 @@
|
|||||||
* SUCH DAMAGE.
|
* SUCH DAMAGE.
|
||||||
*
|
*
|
||||||
* @(#)proc.h 8.15 (Berkeley) 5/19/95
|
* @(#)proc.h 8.15 (Berkeley) 5/19/95
|
||||||
* $Id: proc.h,v 1.50 1997/12/06 04:11:14 sef Exp $
|
* $Id: proc.h,v 1.51 1997/12/12 04:00:48 dyson Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _SYS_PROC_H_
|
#ifndef _SYS_PROC_H_
|
||||||
@ -342,6 +342,7 @@ int fork1 __P((struct proc *, int));
|
|||||||
int trace_req __P((struct proc *));
|
int trace_req __P((struct proc *));
|
||||||
void cpu_wait __P((struct proc *));
|
void cpu_wait __P((struct proc *));
|
||||||
int cpu_coredump __P((struct proc *, struct vnode *, struct ucred *));
|
int cpu_coredump __P((struct proc *, struct vnode *, struct ucred *));
|
||||||
|
void setsugid __P((struct proc *p));
|
||||||
#endif /* KERNEL */
|
#endif /* KERNEL */
|
||||||
|
|
||||||
#endif /* !_SYS_PROC_H_ */
|
#endif /* !_SYS_PROC_H_ */
|
||||||
|
Loading…
Reference in New Issue
Block a user