1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77
#define _GNU_SOURCE // for ucred
#include <sys/socket.h>
#include <sys/un.h>
#include <stdio.h>
#include <unistd.h>
void print_exe_path(pid_t pid) {
char link_path[512];
snprintf(link_path, sizeof(link_path), "/proc/%d/exe", pid);
char exe_path[512];
ssize_t exe_path_len = readlink(link_path, exe_path, sizeof(exe_path) - 1);
if (exe_path_len < 0) {
perror("readlink");
return;
}
exe_path[exe_path_len] = '\0';
printf("%d: path=%s\n", pid, exe_path);
}
int main(int argc, char *argv[]) {
int sfd = socket(AF_UNIX, SOCK_STREAM, 0);
if (sfd < 0) {
perror("socket");
return 1;
}
struct sockaddr_un addr = {
.sun_family = AF_UNIX,
.sun_path = "socket",
};
if (bind(sfd, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
perror("bind");
return 1;
}
if (listen(sfd, 32) < 0) {
perror("listen");
return 1;
}
while (1) {
int cfd = accept(sfd, NULL, NULL);
if (cfd < 0) {
perror("accept");
return 1;
}
printf("client connected\n");
struct ucred peer_ucred;
socklen_t ucred_size = sizeof(struct ucred);
if (getsockopt(cfd, SOL_SOCKET, SO_PEERCRED, &peer_ucred, &ucred_size) < 0) {
perror("getsockopt(SO_PEERCRED)");
goto next;
}
printf("SO_PEERCRED: pid=%d\n", peer_ucred.pid);
int data;
ssize_t n = read(cfd, &data, sizeof(data));
if (n < 0) {
perror("read");
goto next;
} else if (n == 0) {
fprintf(stderr, "read returned 0\n");
goto next;
}
print_exe_path(peer_ucred.pid);
next:
close(cfd);
}
return 0;
}
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
#include <sys/socket.h>
#include <sys/un.h>
#include <stdio.h>
#include <unistd.h>
int main(int argc, char *argv[]) {
int fd = socket(AF_UNIX, SOCK_STREAM, 0);
if (fd < 0) {
perror("socket");
return 1;
}
struct sockaddr_un addr = {
.sun_family = AF_UNIX,
.sun_path = "socket",
};
if (connect(fd, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
perror("connect");
return 1;
}
int data = 42;
if (write(fd, &data, sizeof(data)) < 0) {
perror("write");
return 1;
}
read(fd, &data, sizeof(data));
return 0;
}
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
#include <sys/socket.h>
#include <sys/un.h>
#include <sys/wait.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
int main(int argc, char *argv[]) {
int fd = socket(AF_UNIX, SOCK_STREAM, 0);
if (fd < 0) {
perror("socket");
return 1;
}
pid_t conn_pid = fork();
if (conn_pid < 0) {
perror("fork");
return 1;
} else if (conn_pid == 0) {
// On Linux, SO_PEERCRED is stashed on connect
struct sockaddr_un addr = {
.sun_family = AF_UNIX,
.sun_path = "socket",
};
if (connect(fd, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
perror("connect");
_exit(1);
}
execl("./client", NULL);
perror("exec");
_exit(1);
}
sleep(1);
printf("connected with PID %d\n", conn_pid);
int data = 42;
write(fd, &data, sizeof(data));
read(fd, &data, sizeof(data));
return 0;
}