Subject: kern/133: setuid/setgid don't check effective id
To: None <gnats-admin>
From: David Burren <davidb@eyrie.img.com.au>
List: netbsd-bugs
Date: 02/18/1994 23:35:02
>Number:         133
>Category:       kern
>Synopsis:       setuid/setgid don't check effective id
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    gnats-admin (Kernel Bug People)
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Fri Feb 18 23:35:01 1994
>Originator:     David Burren
>Organization:
	img Consultants
>Release:        
>Environment:
	24/1/93 current
System: NetBSD pandion.eyrie.img.com.au 0.9a PANDION#3 i386


>Description:
	According to setuid(3) (the same man page as setgid(3)):

     If the user is not the super user, or the uid specified is not the real
     or effective ID, these functions return -1.

	The seteuid and setegid calls have this behaviour, but the setuid
	and setgid calls do not.  They do not check the current effective id.
	This breaks programs such as INN.

	Do we change the system calls or the man page?  I believe the man
	page is correct.

>How-To-Repeat:

	setgid(getegid()) will fail in a setgid executeable where the file's
	group is different from the (non-root) user.

>Fix:

*** src/sys/kern/kern_prot.c.orig	Sat Feb 19 13:28:14 1994
--- src/sys/kern/kern_prot.c	Sat Feb 19 13:36:01 1994
***************
*** 265,271 ****
  	int error;
  
  	uid = (uid_t) uap->uid;
! 	if (uid != pc->p_ruid &&
  	    (error = suser(pc->pc_ucred, &p->p_acflag)))
  		return (error);
  	/*
--- 265,271 ----
  	int error;
  
  	uid = (uid_t) uap->uid;
! 	if (uid != pc->p_ruid && uid != pc->p_svuid &&
  	    (error = suser(pc->pc_ucred, &p->p_acflag)))
  		return (error);
  	/*
***************
*** 323,329 ****
  	int error;
  
  	gid = (gid_t) uap->gid;
! 	if (gid != pc->p_rgid && (error = suser(pc->pc_ucred, &p->p_acflag)))
  		return (error);
  	pc->pc_ucred = crcopy(pc->pc_ucred);
  	pc->pc_ucred->cr_groups[0] = gid;
--- 323,330 ----
  	int error;
  
  	gid = (gid_t) uap->gid;
! 	if (gid != pc->p_rgid && gid != pc->p_svgid &&
! 	    (error = suser(pc->pc_ucred, &p->p_acflag)))
  		return (error);
  	pc->pc_ucred = crcopy(pc->pc_ucred);
  	pc->pc_ucred->cr_groups[0] = gid;
>Audit-Trail:
>Unformatted:


------------------------------------------------------------------------------