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
/* small test/example client for SO_PEERCRED use
* author: Jussi Laako <[email protected]>
*/
#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;
}
/* small test/example server for SO_PEERCRED use
* author: Jussi Laako <[email protected]>
*/
#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;
}
_______________________________________________
Dev mailing list
[email protected]
https://lists.tizen.org/listinfo/dev