On 12/4/19 9:32 AM, Richard Haines wrote:
Test SO_PEERSEC for sockets created by socketpair(2) added in kernel 4.18
Signed-off-by: Richard Haines <richard_c_haines@xxxxxxxxxxxxxx>
---
diff --git a/tests/unix_socket/Makefile b/tests/unix_socket/Makefile
index 5266096..7770f0b 100644
--- a/tests/unix_socket/Makefile
+++ b/tests/unix_socket/Makefile
@@ -2,6 +2,11 @@ TARGETS=client server
LDLIBS+= -lselinux
+# Test SO_PEERSEC for sockets created by socketpair(2).
+ifneq ($(shell ../kvercmp $$(uname -r) 4.18),-1)
+ TARGETS += socketpair
+endif
+
all: $(TARGETS)
clean:
rm -f $(TARGETS)
Wondering if we ought to unconditionally build all targets and only
perform the kvercmp test in the test script itself, as we do in binder,
inet_socket, keys, and sctp? Only need to conditionalize the build if
it won't build under older kernels.
diff --git a/tests/unix_socket/socketpair.c b/tests/unix_socket/socketpair.c
new file mode 100644
index 0000000..50cd3fa
--- /dev/null
+++ b/tests/unix_socket/socketpair.c
@@ -0,0 +1,190 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <stddef.h>
+#include <string.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <selinux/selinux.h>
+
+#ifndef SO_PEERSEC
+#define SO_PEERSEC 31
+#endif
+
+#ifndef SCM_SECURITY
+#define SCM_SECURITY 0x03
+#endif
+
+void print_usage(char *progname)
+{
+ fprintf(stderr,
+ "usage: %s stream|dgram\n"
+ "Where:\n\t"
+ "stream Use TCP protocol or:\n\t"
+ "dgram use UDP protocol.\n", progname);
+ exit(-1);
+}
+
+int run_parent(int sock, int type)
+{
+ int result, on = 1;
+ char byte, peerlabel[256];
+ socklen_t labellen = sizeof(peerlabel);
+
+ result = setsockopt(sock, SOL_SOCKET, SO_PASSSEC, &on, sizeof(on));
+ if (result < 0) {
+ perror("setsockopt: SO_PASSSEC");
+ goto err;
+ }
+
+ if (type == SOCK_STREAM) {
+ result = read(sock, &byte, 1);
+ if (result < 0) {
+ perror("read");
+ goto err;
+ }
+
+ result = getsockopt(sock, SOL_SOCKET, SO_PEERSEC, peerlabel,
+ &labellen);
+ if (result < 0) {
+ perror("getsockopt: SO_PEERSEC");
+ goto err;
+ }
+ printf("Parent got peer label=%s\n", peerlabel);
+
+ result = write(sock, peerlabel, sizeof(peerlabel));
You should be writing labellen bytes or strlen(peerlabel) bytes rather
than sizeof(peerlabel); otherwise you are sending extra uninitialized
bytes from the stack to the peer. Looks like elsewhere we are sending
strlen() of the label.