[Dev] Tizen 3.0 proposal for fixing OSP/WRT/Core hard-coded UID issue

Jussi Laako jussi.laako at linux.intel.com
Mon Oct 14 13:22:46 GMT 2013


On 11.10.2013 19:30, Schaufler, Casey wrote:
>
> Dominique and I discussed the underlying problem in some detail
> and believe that we have a cleaner solution.

Nobody has yet explained why launcher needs to be somehow privileged and 
why it's not just a service part of a normal user session?

I'm not advocating for SO_PEERCRED & /proc/PID usage, but it can be made 
fairly proper. I have made a small demo client/server pair (attached) 
that should be quite OK for dealing with this combination for whatever use.

I think I will also attempt to fix kernel regarding the "feature" I 
found (as commented in the sources).


	- Jussi

-------------- next part --------------
/* small test/example client for SO_PEERCRED use
 * author: Jussi Laako <jussi.laako at linux.intel.com>
 */


#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>


int main (int argc, char *argv[])
{
	int nw = 0;
	int fd;
	struct sockaddr_un sun;
	char msg[8];
	
	if (argc > 1)
		nw = 1;

	fd = socket(AF_LOCAL, SOCK_STREAM, 0);
	if (fd < 0)
		return 1;
	sun.sun_family = AF_LOCAL;
	strcpy(sun.sun_path, "/tmp/peercred-test");
	if (connect(fd, (struct sockaddr *) &sun, sizeof(sun)) < 0)
		return 1;
	strcpy(msg, "YooHoo");
	puts(msg);
	if (send(fd, msg, sizeof(msg), 0) <= 0)
		return 2;
	if (nw)
	{
		close(fd);
		return 0;
	}
	if (recv(fd, msg, sizeof(msg), MSG_WAITALL) <= 0)
		return 2;
	msg[7] = '\0';
	puts(msg);
	close(fd);

	return 0;
}

-------------- next part --------------
/* small test/example server for SO_PEERCRED use
 * author: Jussi Laako <jussi.laako at linux.intel.com>
 */

#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <limits.h>
#include <signal.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>


int main (int argc, char *argv[])
{
	int lfd, cfd;
	struct sockaddr_un sun;
	char msg[8];
	struct ucred crd;
	socklen_t optsz = sizeof(crd);
	char pidf[_POSIX_PATH_MAX + 1];
	char lnkf[_POSIX_PATH_MAX + 1];

	/* we get same info in other way */
	signal(SIGPIPE, SIG_IGN);

	lfd = socket(AF_LOCAL, SOCK_STREAM, 0);
	if (lfd < 0)
		return 1;
	sun.sun_family = AF_LOCAL;
	strcpy(sun.sun_path, "/tmp/peercred-test");
	unlink(sun.sun_path);
	if (bind(lfd, (struct sockaddr *) &sun, sizeof(sun)) < 0)
		return 1;
	if (listen(lfd, 2) < 0)
		return 1;
	while ((cfd = accept(lfd, NULL, NULL)) >= 0)
	{
		while (recv(cfd, msg, sizeof(msg), MSG_WAITALL) > 0)
		{
			if (getsockopt(cfd, SOL_SOCKET, SO_PEERCRED,
				&crd, &optsz))
				break;
			printf("pid=%d uid=%d gid=%d\n",
				crd.pid, crd.uid, crd.gid);
			/* give other end chance to exit */
			sleep(1);
			/* dereference peer binary */
			snprintf(pidf, _POSIX_PATH_MAX,
				"/proc/%d/exe", crd.pid);
			memset(lnkf, 0x00, sizeof(lnkf));
			if (readlink(pidf, lnkf, _POSIX_PATH_MAX) <= 0)
				break;
			printf("\texe=%s\n", lnkf);
			/* this should probably fail if the peer doesn't
			 * exist anymore, however it doesn't */
			/*if (getsockopt(cfd, SOL_SOCKET, SO_PEERCRED,
				&crd, &optsz))
				break;
			printf("\tpid=%d uid=%d gid=%d\n",
				crd.pid, crd.uid, crd.gid);*/
			/* probe if the peer is still there */
			if (send(cfd, NULL, 0, 0) < 0)
			{
				if (errno == EPIPE)
					puts("\tpeer has gone away");
				else
					printf("\terror: %s\n",
						strerror(errno));
			}
			/* send reply */
			strcpy(msg, "2U2");
			if (send(cfd, msg, sizeof(msg), 0) < 0)
				break;
		}
		close(cfd);
	}
	close(lfd);
	unlink(sun.sun_path);

	return 0;
}



More information about the Dev mailing list