Re: /tmp/.ICE-unix
- From: Alan Cox <alan redhat com>
 
- To: hp redhat com (Havoc Pennington)
 
- Cc: snickell Stanford EDU (Seth Aaron Nickell),	alan redhat com (Alan Cox), gnome-hackers gnome org
 
- Subject: Re: /tmp/.ICE-unix
 
- Date: Mon, 17 Sep 2001 08:52:13 -0400 (EDT)
 
> all the file says is Open Group and NCR Corporation. ;-)
CERT have this capability
> The same code runs to create /tmp/.X11-unix, for the X server
> connections, but I think in that case getting the perms right is done
> by the xserver and involves running as root at least part of the time.
> Clearly we can't run gnome-session as root.
You could however write a safe, audited, "ice_create" app something like this.
(This wants trying, and auditing of course). Note that it does not use
stdio it simply exits with 0 or 1 - that is intentional. It wants to be
small and setuid so the interpretation of results wants to be done by
its caller who is non suid.
#include <errno.h>
#include <sys/stat.h>
[etc]
int main(int argc, char *argv[])
{
	int fd;
	int delete_tried = 0;
	struct stat st;
retry:
	// Check we can become root
	if(seteuid(0)<0)
		exit(1);
	if(setegid(0)<0)
		exit(1):
	// Clear umask so we can create .ICE-unix as we want it
	if(umask(0)<0)
		exit(1);
	// Create it (as root) - atomically
	if(mkdir("/tmp/.ICE-unix", 0777)==0)
	{
		// Make it sticky
		if(chmod("/tmp/.ICE-unix", 02777)==0)
			exit(1);
		exit(0);
	}
	// It existing might be ok.. other errors we bale
	if(errno != EEXIST)
		exit(1);
	// Become the user for stage 2
	if(setegid(getgid())<0)
		exit(1);
	if(seteuid(getuid())<0)
		exit(1);
	/* This might be a link so open it as the user and for no harm 
	   Sadly not all gnome platforms have O_NOFOLLOW */
	fd=open("/tmp/.ICE-unix", O_RDONLY|O_NDELAY);
	if(fd==-1)
		exit(1);
	if(fstat(fd, &st)<0)
		exit(1);
	// Make sure its a directory
	if(!S_ISDIR(st.st_mode))
	{
		close(fd):
		// Delete the junk (if we can) and retry
		if(!delete_tried && unlink("/tmp/.ICE-unix")==0)
		{
			delete_tried = 1;
			goto retry;
		}
		exit(1);
	}
	/* Check the permissions are ok - if so we do nothing */
	if(st.st_uid==0 && st.st_gid==0 && (st.st_mode&03777)==02777)
		exit(0);
	/* Fix the permissions */
	if(setegid(0)<0)
		exit(1);
	if(seteuid(0)<0)
		exit(1);
	if(fchown(fd, 0, 0)==-1)
		exit(1);
	if(fchmod(fd, 02777)==-1)
		exit(1);
	close(fd);
	exit(0);
}
[
Date Prev][
Date Next]   [
Thread Prev][
Thread Next]   
[
Thread Index]
[
Date Index]
[
Author Index]