Subject: Re: Addition to force open to open only regular files
To: Bill Studenmund <wrstuden@zembu.com>
From: Warner Losh <imp@village.org>
List: tech-kern
Date: 11/28/2000 23:35:44
In message
<Pine.NEB.4.21.0011281842460.262-100000@candlekeep.z.zembu.com> Bill
Studenmund writes:
: One of the security models we impliment (mainly to be compatible with
: other systems), setre[gu]id(), makes recovering this info hard as it
: overwrites the variables we'd want to look at to see what that ID was.
: 
: So why not just make things easy and add a syscall to get it???
: 
: Sounds a lot easier than re-writing the syscall interfaces....

[[ apart from the fact that getsid() is already a process session
   thing, I like this idea.  getsuid() is what I've renamed it to ]]

[[ just to recap my reading of intro(2) ]]
real uid is the original uid of the process.
effective uid is the uid that is curently active.  For setuid
  programs, the effective uid is set to the owner of the file on the
  exec.
saved uid is the effective uid at the start of the program after any
  uid change has been made to it.

Let us say that we have setuid 0 program run by user 100.  Let us
ignore group things for the moment.

Without any uid change at all, things work:
// suid == 0, ruid == 100, euid == 0
/* library call happens */
	// suid == 0, ruid == 100, euid == 0
	euid = geteuid();	// 0
	if (getsuid() == geteuid())
		seteuid(getuid());
	// suid == 0, ruid == 100, euid == 100
	/* do it */
	if (geteuid() != euid)
		seteuid(euid);
	// suid == 0, ruid == 100, euid == 0
	return;
// suid == 0, ruid == 100, euid == 0

Privs dropped with setreuid():
// suid == 0, ruid == 100, euid == 0
setreuid(geteuid(), getuid())
// suid == 0, ruid == 0, euid == 100
/* library call happens */
	// suid == 0, ruid == 0, euid == 100
	euid = geteuid();
	if (getsuid() == geteuid())
		seteuid(getuid());
	// suid == 0, ruid == 0, euid == 100
	/* do it */
	if (geteuid() != euid)
		seteuid(getuid());
	// suid == 0, ruid == 0, euid == 100
	return;
// suid == 0, ruid == 0, euid == 100

Privs dropped with seteuid():
// suid == 0, ruid == 100, euid == 0
seteuid(getuid());
// suid == 0, ruid == 100, euid == 100
/* library call happens */
	// suid == 0, ruid == 100, euid == 100
	euid = geteuid();	// 100
	if (getsuid() == geteuid())
		seteuid(getuid());
	// suid == 0, ruid == 100, euid == 100
	/* do it */
	if (geteuid() != euid)
		seteuid(getuid());
	// suid == 0, ruid == 100, euid == 100
	return;
// suid == 0, ruid == 100, euid == 100

So unless I'm missing something, this looks like it is correct in all
cases.

Warner