Re: /tmp/.ICE-unix



> 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]