All of lore.kernel.org
 help / color / mirror / Atom feed
From: David Howells <dhowells@redhat.com>
To: keyrings@vger.kernel.org, trond.myklebust@hammerspace.com,
	sfrench@samba.org
Cc: linux-security-module@vger.kernel.org, linux-nfs@vger.kernel.org,
	linux-cifs@vger.kernel.org, linux-fsdevel@vger.kernel.org,
	rgb@redhat.com, dhowells@redhat.com,
	linux-kernel@vger.kernel.org
Subject: [RFC PATCH 19/27] containers: Sample: request_key upcall handling
Date: Fri, 15 Feb 2019 16:10:30 +0000	[thread overview]
Message-ID: <155024703003.21651.3499235528404179500.stgit@warthog.procyon.org.uk> (raw)
In-Reply-To: <155024683432.21651.14153938339749694146.stgit@warthog.procyon.org.uk>

Implement a sample upcall handling.

Firstly, the test-container sample is modified to (a) create a staging
keyring and to (b) intercept request_key calls for user-type keys inside
the container and place the authentication keys into that rather than
invoking /sbin/request-key.

Secondly, a test-upcall sample is added that will monitor the keyring for
notifications and spawn /sbin/request-key instances for each of key added.
This is run as:

	./test-upcall

to find a keyring called "upcall" in the session keyring (as created by the
./test-container program) and listen for additions to that, or it can be
run as:

	./test-upcall <keyring-id>

to listen on a specific keyring.

Note that the test-upcall sample is designed to be run separately from
test-container so that its stdout can be observed.

Signed-off-by: David Howells <dhowells@redhat.com>
---

 samples/vfs/Makefile         |    6 +
 samples/vfs/test-container.c |   16 +++
 samples/vfs/test-upcall.c    |  243 ++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 264 insertions(+), 1 deletion(-)
 create mode 100644 samples/vfs/test-upcall.c

diff --git a/samples/vfs/Makefile b/samples/vfs/Makefile
index 25420919ee40..a8e9e1142ae3 100644
--- a/samples/vfs/Makefile
+++ b/samples/vfs/Makefile
@@ -5,7 +5,8 @@ hostprogs-$(CONFIG_SAMPLE_VFS) := \
 	test-fsmount \
 	test-mntinfo \
 	test-statx \
-	test-container
+	test-container \
+	test-upcall
 
 # Tell kbuild to always build the programs
 always := $(hostprogs-y)
@@ -18,5 +19,8 @@ HOSTLDLIBS_test-mntinfo += -lm
 HOSTCFLAGS_test-fs-query.o += -I$(objtree)/usr/include
 HOSTCFLAGS_test-fsmount.o += -I$(objtree)/usr/include
 HOSTCFLAGS_test-statx.o += -I$(objtree)/usr/include
+
 HOSTCFLAGS_test-container.o += -I$(objtree)/usr/include
 HOSTLDLIBS_test-container += -lkeyutils
+HOSTCFLAGS_test-upcall.o += -I$(objtree)/usr/include
+HOSTLDLIBS_test-upcall += -lkeyutils
diff --git a/samples/vfs/test-container.c b/samples/vfs/test-container.c
index 44ff57afb5a4..7dc9071399b2 100644
--- a/samples/vfs/test-container.c
+++ b/samples/vfs/test-container.c
@@ -20,6 +20,8 @@
 #include <sys/stat.h>
 #include <keyutils.h>
 
+#define KEYCTL_CONTAINER_INTERCEPT	31	/* Intercept upcalls inside a container */
+
 /* Hope -1 isn't a syscall */
 #ifndef __NR_fsopen
 #define __NR_fsopen -1
@@ -187,6 +189,7 @@ void container_init(void)
  */
 int main(int argc, char *argv[])
 {
+	key_serial_t keyring;
 	pid_t pid;
 	int fsfd, mfd, cfd, ws;
 
@@ -259,6 +262,19 @@ int main(int argc, char *argv[])
 	E(close(fsfd));
 	E(close(mfd));
 
+	/* Create a keyring to catch upcalls. */
+	printf("Intercepting...\n");
+	keyring = add_key("keyring", "upcall", NULL, 0, KEY_SPEC_SESSION_KEYRING);
+	if (keyring = -1) {
+		perror("add_key/u");
+		exit(1);
+	}
+
+	if (keyctl(KEYCTL_CONTAINER_INTERCEPT, cfd, "user", 0, keyring) < 0) {
+		perror("keyctl_container_intercept");
+		exit(1);
+	}
+
 	/* Start the 'init' process. */
 	printf("Forking...\n");
 	switch ((pid = fork_into_container(cfd))) {
diff --git a/samples/vfs/test-upcall.c b/samples/vfs/test-upcall.c
new file mode 100644
index 000000000000..225fa0325d1b
--- /dev/null
+++ b/samples/vfs/test-upcall.c
@@ -0,0 +1,243 @@
+/* Container keyring upcall management test.
+ *
+ * Copyright (C) 2019 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public Licence
+ * as published by the Free Software Foundation; either version
+ * 2 of the Licence, or (at your option) any later version.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <poll.h>
+#include <sys/mman.h>
+#include <sys/ioctl.h>
+#include <keyutils.h>
+#include <linux/watch_queue.h>
+
+#define KEYCTL_WATCH_KEY		30	/* Watch a key or ring of keys for changes */
+#define KEYCTL_QUERY_REQUEST_KEY_AUTH	32	/* Query a request_key_auth key */
+#define KEYCTL_MOVE			33	/* Move keys between keyrings */
+#define KEYCTL_FIND_LRU			34	/* Find the least-recently used key in a keyring */
+
+struct keyctl_query_request_key_auth {
+	char		operation[32];	/* Operation name, typically "create" */
+	uid_t		fsuid;		/* UID of requester */
+	gid_t		fsgid;		/* GID of requester */
+	key_serial_t	target_key;	/* The key being instantiated */
+	key_serial_t	thread_keyring;	/* The requester's thread keyring */
+	key_serial_t	process_keyring; /* The requester's process keyring */
+	key_serial_t	session_keyring; /* The requester's session keyring */
+	long long	spare[1];
+};
+
+static void process_request(key_serial_t keyring, key_serial_t key)
+{
+	struct keyctl_query_request_key_auth info;
+	char target[32], uid[32], gid[32], thread[32], process[32], session[32];
+	void *callout;
+	long len;
+
+#if 0
+	key = keyctl(KEYCTL_FIND_LRU, keyring, ".request_key_auth");
+	if (key = -1) {
+		perror("keyctl/find");
+		exit(1);
+	}
+#endif
+
+	if (keyctl(KEYCTL_QUERY_REQUEST_KEY_AUTH, key, &info) = -1) {
+		perror("keyctl/query");
+		exit(1);
+	}
+
+	len = keyctl_read_alloc(key, &callout);
+	if (len = -1) {
+		perror("keyctl/read");
+		exit(1);
+	}
+
+	sprintf(target, "%d", info.target_key);
+	sprintf(uid, "%d", info.fsuid);
+	sprintf(gid, "%d", info.fsgid);
+	sprintf(thread, "%d", info.thread_keyring);
+	sprintf(process, "%d", info.process_keyring);
+	sprintf(session, "%d", info.session_keyring);
+
+	printf("Authentication key %d\n", key);
+	printf("- %s %s\n", info.operation, target);
+	printf("- uid=%s gid=%s\n", uid, gid);
+	printf("- rings=%s,%s,%s\n", thread, process, session);
+	printf("- callout='%s'\n", (char *)callout);
+
+	switch (fork()) {
+	case 0:
+		/* Only pass the auth token of interest onto /sbin/request-key */
+		if (keyctl(KEYCTL_MOVE, key, keyring, KEY_SPEC_THREAD_KEYRING) < 0) {
+			perror("keyctl_move/1");
+			exit(1);
+		}
+
+		if (keyctl_join_session_keyring(NULL) < 0) {
+			perror("keyctl_join");
+			exit(1);
+		}
+
+		if (keyctl(KEYCTL_MOVE, key,
+			   KEY_SPEC_THREAD_KEYRING, KEY_SPEC_SESSION_KEYRING) < 0) {
+			perror("keyctl_move/2");
+			exit(1);
+		}
+
+		execl("/sbin/request-key",
+		      "request-key", info.operation, target, uid, gid, thread, process, session,
+		      NULL);
+		perror("execve");
+		exit(1);
+
+	case -1:
+		perror("fork");
+		exit(1);
+
+	default:
+		return;
+	}
+}
+
+/*
+ * We saw a change on the keyring.
+ */
+static void saw_key_change(struct watch_notification *n)
+{
+	struct key_notification *k = (struct key_notification *)n;
+	unsigned int len = n->info & WATCH_INFO_LENGTH;
+
+	if (len != sizeof(struct key_notification))
+		return;
+
+	printf("KEY %d change=%u aux=%d\n", k->key_id, n->subtype, k->aux);
+
+	process_request(k->key_id, k->aux);
+}
+
+/*
+ * Consume and display events.
+ */
+static int consumer(int fd, struct watch_queue_buffer *buf)
+{
+	struct watch_notification *n;
+	struct pollfd p[1];
+	unsigned int head, tail, mask = buf->meta.mask;
+
+	for (;;) {
+		p[0].fd = fd;
+		p[0].events = POLLIN | POLLERR;
+		p[0].revents = 0;
+
+		if (poll(p, 1, -1) = -1) {
+			perror("poll");
+			break;
+		}
+
+		printf("ptrs h=%x t=%x m=%x\n",
+		       buf->meta.head, buf->meta.tail, buf->meta.mask);
+
+		while (head = __atomic_load_n(&buf->meta.head, __ATOMIC_ACQUIRE),
+		       tail = buf->meta.tail,
+		       tail != head
+		       ) {
+			n = &buf->slots[tail & mask];
+			printf("NOTIFY[%08x-%08x] ty=%04x sy=%04x i=%08x\n",
+			       head, tail, n->type, n->subtype, n->info);
+			if ((n->info & WATCH_INFO_LENGTH) = 0)
+				goto out;
+
+			switch (n->type) {
+			case WATCH_TYPE_META:
+				if (n->subtype = WATCH_META_REMOVAL_NOTIFICATION)
+					printf("REMOVAL of watchpoint %08x\n",
+					       n->info & WATCH_INFO_ID);
+				break;
+			case WATCH_TYPE_KEY_NOTIFY:
+				saw_key_change(n);
+				break;
+			}
+
+			tail += (n->info & WATCH_INFO_LENGTH) >> WATCH_LENGTH_SHIFT;
+			__atomic_store_n(&buf->meta.tail, tail, __ATOMIC_RELEASE);
+		}
+	}
+
+out:
+	return 0;
+}
+
+/*
+ * We're only interested in key insertion events.
+ */
+static struct watch_notification_filter filter = {
+	.nr_filters	= 1,
+	.filters = {
+		[0] = {
+			.type			= WATCH_TYPE_KEY_NOTIFY,
+			.subtype_filter[0]	= (1 << NOTIFY_KEY_LINKED),
+		},
+	}
+};
+
+int main(int argc, char *argv[])
+{
+	struct watch_queue_buffer *buf;
+	key_serial_t keyring;
+	size_t page_size = sysconf(_SC_PAGESIZE);
+	int fd;
+
+	if (argc = 1) {
+		keyring = keyctl_search(KEY_SPEC_SESSION_KEYRING, "keyring",
+					"upcall", 0);
+		if (keyring = -1) {
+			perror("keyctl_search");
+			exit(1);
+		}
+	} else if (argc = 2) {
+		keyring = strtoul(argv[1], NULL, 0);
+	} else {
+		fprintf(stderr, "Format: test-upcall [<keyring>]\n");
+		exit(2);
+	}
+
+	/* Create a watch on the keyring to detect the addition of keys. */
+	fd = open("/dev/watch_queue", O_RDWR | O_CLOEXEC);
+	if (fd = -1) {
+		perror("/dev/watch_queue");
+		exit(1);
+	}
+
+	if (ioctl(fd, IOC_WATCH_QUEUE_SET_SIZE, 1) = -1) {
+		perror("/dev/watch_queue(size)");
+		exit(1);
+	}
+
+	if (ioctl(fd, IOC_WATCH_QUEUE_SET_FILTER, &filter) = -1) {
+		perror("/dev/watch_queue(filter)");
+		exit(1);
+	}
+
+	buf = mmap(NULL, page_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
+	if (buf = MAP_FAILED) {
+		perror("mmap");
+		exit(1);
+	}
+
+	if (keyctl(KEYCTL_WATCH_KEY, keyring, fd, 0x01) = -1) {
+		perror("keyctl");
+		exit(1);
+	}
+
+	return consumer(fd, buf);
+}

WARNING: multiple messages have this Message-ID (diff)
From: David Howells <dhowells@redhat.com>
To: keyrings@vger.kernel.org, trond.myklebust@hammerspace.com,
	sfrench@samba.org
Cc: linux-security-module@vger.kernel.org, linux-nfs@vger.kernel.org,
	linux-cifs@vger.kernel.org, linux-fsdevel@vger.kernel.org,
	rgb@redhat.com, dhowells@redhat.com,
	linux-kernel@vger.kernel.org
Subject: [RFC PATCH 19/27] containers: Sample: request_key upcall handling
Date: Fri, 15 Feb 2019 16:10:30 +0000	[thread overview]
Message-ID: <155024703003.21651.3499235528404179500.stgit@warthog.procyon.org.uk> (raw)
In-Reply-To: <155024683432.21651.14153938339749694146.stgit@warthog.procyon.org.uk>

Implement a sample upcall handling.

Firstly, the test-container sample is modified to (a) create a staging
keyring and to (b) intercept request_key calls for user-type keys inside
the container and place the authentication keys into that rather than
invoking /sbin/request-key.

Secondly, a test-upcall sample is added that will monitor the keyring for
notifications and spawn /sbin/request-key instances for each of key added.
This is run as:

	./test-upcall

to find a keyring called "upcall" in the session keyring (as created by the
./test-container program) and listen for additions to that, or it can be
run as:

	./test-upcall <keyring-id>

to listen on a specific keyring.

Note that the test-upcall sample is designed to be run separately from
test-container so that its stdout can be observed.

Signed-off-by: David Howells <dhowells@redhat.com>
---

 samples/vfs/Makefile         |    6 +
 samples/vfs/test-container.c |   16 +++
 samples/vfs/test-upcall.c    |  243 ++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 264 insertions(+), 1 deletion(-)
 create mode 100644 samples/vfs/test-upcall.c

diff --git a/samples/vfs/Makefile b/samples/vfs/Makefile
index 25420919ee40..a8e9e1142ae3 100644
--- a/samples/vfs/Makefile
+++ b/samples/vfs/Makefile
@@ -5,7 +5,8 @@ hostprogs-$(CONFIG_SAMPLE_VFS) := \
 	test-fsmount \
 	test-mntinfo \
 	test-statx \
-	test-container
+	test-container \
+	test-upcall
 
 # Tell kbuild to always build the programs
 always := $(hostprogs-y)
@@ -18,5 +19,8 @@ HOSTLDLIBS_test-mntinfo += -lm
 HOSTCFLAGS_test-fs-query.o += -I$(objtree)/usr/include
 HOSTCFLAGS_test-fsmount.o += -I$(objtree)/usr/include
 HOSTCFLAGS_test-statx.o += -I$(objtree)/usr/include
+
 HOSTCFLAGS_test-container.o += -I$(objtree)/usr/include
 HOSTLDLIBS_test-container += -lkeyutils
+HOSTCFLAGS_test-upcall.o += -I$(objtree)/usr/include
+HOSTLDLIBS_test-upcall += -lkeyutils
diff --git a/samples/vfs/test-container.c b/samples/vfs/test-container.c
index 44ff57afb5a4..7dc9071399b2 100644
--- a/samples/vfs/test-container.c
+++ b/samples/vfs/test-container.c
@@ -20,6 +20,8 @@
 #include <sys/stat.h>
 #include <keyutils.h>
 
+#define KEYCTL_CONTAINER_INTERCEPT	31	/* Intercept upcalls inside a container */
+
 /* Hope -1 isn't a syscall */
 #ifndef __NR_fsopen
 #define __NR_fsopen -1
@@ -187,6 +189,7 @@ void container_init(void)
  */
 int main(int argc, char *argv[])
 {
+	key_serial_t keyring;
 	pid_t pid;
 	int fsfd, mfd, cfd, ws;
 
@@ -259,6 +262,19 @@ int main(int argc, char *argv[])
 	E(close(fsfd));
 	E(close(mfd));
 
+	/* Create a keyring to catch upcalls. */
+	printf("Intercepting...\n");
+	keyring = add_key("keyring", "upcall", NULL, 0, KEY_SPEC_SESSION_KEYRING);
+	if (keyring == -1) {
+		perror("add_key/u");
+		exit(1);
+	}
+
+	if (keyctl(KEYCTL_CONTAINER_INTERCEPT, cfd, "user", 0, keyring) < 0) {
+		perror("keyctl_container_intercept");
+		exit(1);
+	}
+
 	/* Start the 'init' process. */
 	printf("Forking...\n");
 	switch ((pid = fork_into_container(cfd))) {
diff --git a/samples/vfs/test-upcall.c b/samples/vfs/test-upcall.c
new file mode 100644
index 000000000000..225fa0325d1b
--- /dev/null
+++ b/samples/vfs/test-upcall.c
@@ -0,0 +1,243 @@
+/* Container keyring upcall management test.
+ *
+ * Copyright (C) 2019 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public Licence
+ * as published by the Free Software Foundation; either version
+ * 2 of the Licence, or (at your option) any later version.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <poll.h>
+#include <sys/mman.h>
+#include <sys/ioctl.h>
+#include <keyutils.h>
+#include <linux/watch_queue.h>
+
+#define KEYCTL_WATCH_KEY		30	/* Watch a key or ring of keys for changes */
+#define KEYCTL_QUERY_REQUEST_KEY_AUTH	32	/* Query a request_key_auth key */
+#define KEYCTL_MOVE			33	/* Move keys between keyrings */
+#define KEYCTL_FIND_LRU			34	/* Find the least-recently used key in a keyring */
+
+struct keyctl_query_request_key_auth {
+	char		operation[32];	/* Operation name, typically "create" */
+	uid_t		fsuid;		/* UID of requester */
+	gid_t		fsgid;		/* GID of requester */
+	key_serial_t	target_key;	/* The key being instantiated */
+	key_serial_t	thread_keyring;	/* The requester's thread keyring */
+	key_serial_t	process_keyring; /* The requester's process keyring */
+	key_serial_t	session_keyring; /* The requester's session keyring */
+	long long	spare[1];
+};
+
+static void process_request(key_serial_t keyring, key_serial_t key)
+{
+	struct keyctl_query_request_key_auth info;
+	char target[32], uid[32], gid[32], thread[32], process[32], session[32];
+	void *callout;
+	long len;
+
+#if 0
+	key = keyctl(KEYCTL_FIND_LRU, keyring, ".request_key_auth");
+	if (key == -1) {
+		perror("keyctl/find");
+		exit(1);
+	}
+#endif
+
+	if (keyctl(KEYCTL_QUERY_REQUEST_KEY_AUTH, key, &info) == -1) {
+		perror("keyctl/query");
+		exit(1);
+	}
+
+	len = keyctl_read_alloc(key, &callout);
+	if (len == -1) {
+		perror("keyctl/read");
+		exit(1);
+	}
+
+	sprintf(target, "%d", info.target_key);
+	sprintf(uid, "%d", info.fsuid);
+	sprintf(gid, "%d", info.fsgid);
+	sprintf(thread, "%d", info.thread_keyring);
+	sprintf(process, "%d", info.process_keyring);
+	sprintf(session, "%d", info.session_keyring);
+
+	printf("Authentication key %d\n", key);
+	printf("- %s %s\n", info.operation, target);
+	printf("- uid=%s gid=%s\n", uid, gid);
+	printf("- rings=%s,%s,%s\n", thread, process, session);
+	printf("- callout='%s'\n", (char *)callout);
+
+	switch (fork()) {
+	case 0:
+		/* Only pass the auth token of interest onto /sbin/request-key */
+		if (keyctl(KEYCTL_MOVE, key, keyring, KEY_SPEC_THREAD_KEYRING) < 0) {
+			perror("keyctl_move/1");
+			exit(1);
+		}
+
+		if (keyctl_join_session_keyring(NULL) < 0) {
+			perror("keyctl_join");
+			exit(1);
+		}
+
+		if (keyctl(KEYCTL_MOVE, key,
+			   KEY_SPEC_THREAD_KEYRING, KEY_SPEC_SESSION_KEYRING) < 0) {
+			perror("keyctl_move/2");
+			exit(1);
+		}
+
+		execl("/sbin/request-key",
+		      "request-key", info.operation, target, uid, gid, thread, process, session,
+		      NULL);
+		perror("execve");
+		exit(1);
+
+	case -1:
+		perror("fork");
+		exit(1);
+
+	default:
+		return;
+	}
+}
+
+/*
+ * We saw a change on the keyring.
+ */
+static void saw_key_change(struct watch_notification *n)
+{
+	struct key_notification *k = (struct key_notification *)n;
+	unsigned int len = n->info & WATCH_INFO_LENGTH;
+
+	if (len != sizeof(struct key_notification))
+		return;
+
+	printf("KEY %d change=%u aux=%d\n", k->key_id, n->subtype, k->aux);
+
+	process_request(k->key_id, k->aux);
+}
+
+/*
+ * Consume and display events.
+ */
+static int consumer(int fd, struct watch_queue_buffer *buf)
+{
+	struct watch_notification *n;
+	struct pollfd p[1];
+	unsigned int head, tail, mask = buf->meta.mask;
+
+	for (;;) {
+		p[0].fd = fd;
+		p[0].events = POLLIN | POLLERR;
+		p[0].revents = 0;
+
+		if (poll(p, 1, -1) == -1) {
+			perror("poll");
+			break;
+		}
+
+		printf("ptrs h=%x t=%x m=%x\n",
+		       buf->meta.head, buf->meta.tail, buf->meta.mask);
+
+		while (head = __atomic_load_n(&buf->meta.head, __ATOMIC_ACQUIRE),
+		       tail = buf->meta.tail,
+		       tail != head
+		       ) {
+			n = &buf->slots[tail & mask];
+			printf("NOTIFY[%08x-%08x] ty=%04x sy=%04x i=%08x\n",
+			       head, tail, n->type, n->subtype, n->info);
+			if ((n->info & WATCH_INFO_LENGTH) == 0)
+				goto out;
+
+			switch (n->type) {
+			case WATCH_TYPE_META:
+				if (n->subtype == WATCH_META_REMOVAL_NOTIFICATION)
+					printf("REMOVAL of watchpoint %08x\n",
+					       n->info & WATCH_INFO_ID);
+				break;
+			case WATCH_TYPE_KEY_NOTIFY:
+				saw_key_change(n);
+				break;
+			}
+
+			tail += (n->info & WATCH_INFO_LENGTH) >> WATCH_LENGTH_SHIFT;
+			__atomic_store_n(&buf->meta.tail, tail, __ATOMIC_RELEASE);
+		}
+	}
+
+out:
+	return 0;
+}
+
+/*
+ * We're only interested in key insertion events.
+ */
+static struct watch_notification_filter filter = {
+	.nr_filters	= 1,
+	.filters = {
+		[0] = {
+			.type			= WATCH_TYPE_KEY_NOTIFY,
+			.subtype_filter[0]	= (1 << NOTIFY_KEY_LINKED),
+		},
+	}
+};
+
+int main(int argc, char *argv[])
+{
+	struct watch_queue_buffer *buf;
+	key_serial_t keyring;
+	size_t page_size = sysconf(_SC_PAGESIZE);
+	int fd;
+
+	if (argc == 1) {
+		keyring = keyctl_search(KEY_SPEC_SESSION_KEYRING, "keyring",
+					"upcall", 0);
+		if (keyring == -1) {
+			perror("keyctl_search");
+			exit(1);
+		}
+	} else if (argc == 2) {
+		keyring = strtoul(argv[1], NULL, 0);
+	} else {
+		fprintf(stderr, "Format: test-upcall [<keyring>]\n");
+		exit(2);
+	}
+
+	/* Create a watch on the keyring to detect the addition of keys. */
+	fd = open("/dev/watch_queue", O_RDWR | O_CLOEXEC);
+	if (fd == -1) {
+		perror("/dev/watch_queue");
+		exit(1);
+	}
+
+	if (ioctl(fd, IOC_WATCH_QUEUE_SET_SIZE, 1) == -1) {
+		perror("/dev/watch_queue(size)");
+		exit(1);
+	}
+
+	if (ioctl(fd, IOC_WATCH_QUEUE_SET_FILTER, &filter) == -1) {
+		perror("/dev/watch_queue(filter)");
+		exit(1);
+	}
+
+	buf = mmap(NULL, page_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
+	if (buf == MAP_FAILED) {
+		perror("mmap");
+		exit(1);
+	}
+
+	if (keyctl(KEYCTL_WATCH_KEY, keyring, fd, 0x01) == -1) {
+		perror("keyctl");
+		exit(1);
+	}
+
+	return consumer(fd, buf);
+}


  parent reply	other threads:[~2019-02-15 16:10 UTC|newest]

Thread overview: 113+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-02-15 16:07 [RFC PATCH 00/27] Containers and using authenticated filesystems David Howells
2019-02-15 16:07 ` David Howells
2019-02-15 16:07 ` [RFC PATCH 01/27] containers: Rename linux/container.h to linux/container_dev.h David Howells
2019-02-15 16:07 ` [RFC PATCH 02/27] containers: Implement containers as kernel objects David Howells
2019-02-15 16:07   ` David Howells
2019-02-17 18:57   ` Trond Myklebust
2019-02-17 18:57     ` Trond Myklebust
2019-02-17 19:39   ` James Bottomley
2019-02-17 19:39     ` James Bottomley
2019-02-19 16:56   ` Eric W. Biederman
2019-02-19 16:56     ` Eric W. Biederman
2019-02-19 23:03   ` David Howells
2019-02-19 23:03     ` David Howells
2019-02-20 14:23     ` Trond Myklebust
2019-02-20 14:23       ` Trond Myklebust
2019-02-19 23:06   ` David Howells
2019-02-20  2:20     ` James Bottomley
2019-02-20  2:20       ` James Bottomley
2019-02-20  3:04       ` Ian Kent
2019-02-20  3:04         ` Ian Kent
2019-02-20  3:46         ` James Bottomley
2019-02-20  3:46           ` James Bottomley
2019-02-20  4:42           ` Ian Kent
2019-02-20  4:42             ` Ian Kent
2019-02-20  6:57           ` Paul Moore
2019-02-20  6:57             ` Paul Moore
2019-02-19 23:13   ` David Howells
2019-02-19 23:13     ` David Howells
2019-02-19 23:55   ` Tycho Andersen
2019-02-19 23:55     ` Tycho Andersen
2019-02-20  2:46   ` Ian Kent
2019-02-20  2:46     ` Ian Kent
2019-02-20 13:26     ` Christian Brauner
2019-02-20 13:26       ` Christian Brauner
2019-02-20 13:26       ` Christian Brauner
2019-02-21 10:39       ` Ian Kent
2019-02-21 10:39         ` Ian Kent
2019-02-15 16:07 ` [RFC PATCH 03/27] containers: Provide /proc/containers David Howells
2019-02-15 16:07   ` David Howells
2019-02-15 16:07 ` [RFC PATCH 04/27] containers: Allow a process to be forked into a container David Howells
2019-02-15 17:39   ` Stephen Smalley
2019-02-15 17:39     ` Stephen Smalley
2019-02-19 16:39   ` Eric W. Biederman
2019-02-19 16:39     ` Eric W. Biederman
2019-02-19 23:16   ` David Howells
2019-02-19 23:16     ` David Howells
2019-02-15 16:07 ` [RFC PATCH 05/27] containers: Open a socket inside " David Howells
2019-02-19 16:41   ` Eric W. Biederman
2019-02-19 16:41     ` Eric W. Biederman
2019-02-15 16:08 ` [RFC PATCH 06/27] containers, vfs: Allow syscall dirfd arguments to take a container fd David Howells
2019-02-19 16:45   ` Eric W. Biederman
2019-02-19 16:45     ` Eric W. Biederman
2019-02-19 23:24   ` David Howells
2019-02-19 23:24     ` David Howells
2019-02-15 16:08 ` [RFC PATCH 07/27] containers: Make fsopen() able to create a superblock in a container David Howells
2019-02-15 16:08   ` David Howells
2019-02-15 16:08 ` [RFC PATCH 08/27] containers, vfs: Honour CONTAINER_NEW_EMPTY_FS_NS David Howells
2019-02-17  0:11   ` Al Viro
2019-02-15 16:08 ` [RFC PATCH 09/27] vfs: Allow mounting to other namespaces David Howells
2019-02-17  0:14   ` Al Viro
2019-02-15 16:08 ` [RFC PATCH 10/27] containers: Provide fs_context op for container setting David Howells
2019-02-15 16:09 ` [RFC PATCH 11/27] containers: Sample program for driving container objects David Howells
2019-02-15 16:09   ` David Howells
2019-02-15 16:09 ` [RFC PATCH 12/27] containers: Allow a daemon to intercept request_key upcalls in a container David Howells
2019-02-15 16:09   ` David Howells
2019-02-15 16:09 ` [RFC PATCH 13/27] keys: Provide a keyctl to query a request_key authentication key David Howells
2019-02-15 16:09 ` [RFC PATCH 14/27] keys: Break bits out of key_unlink() David Howells
2019-02-15 16:09   ` David Howells
2019-02-15 16:09 ` [RFC PATCH 15/27] keys: Make __key_link_begin() handle lockdep nesting David Howells
2019-02-15 16:09   ` David Howells
2019-02-15 16:09 ` [RFC PATCH 16/27] keys: Grant Link permission to possessers of request_key auth keys David Howells
2019-02-15 16:10 ` [RFC PATCH 17/27] keys: Add a keyctl to move a key between keyrings David Howells
2019-02-15 16:10   ` David Howells
2019-02-15 16:10 ` [RFC PATCH 18/27] keys: Find the least-recently used unseen key in a keyring David Howells
2019-02-15 16:10   ` David Howells
2019-02-15 16:10 ` David Howells [this message]
2019-02-15 16:10   ` [RFC PATCH 19/27] containers: Sample: request_key upcall handling David Howells
2019-02-15 16:10 ` [RFC PATCH 20/27] container, keys: Add a container keyring David Howells
2019-02-15 16:10   ` David Howells
2019-02-15 21:46   ` Eric Biggers
2019-02-15 21:46     ` Eric Biggers
2019-02-15 16:11 ` [RFC PATCH 21/27] keys: Fix request_key() lack of Link perm check on found key David Howells
2019-02-15 16:11 ` [RFC PATCH 22/27] KEYS: Replace uid/gid/perm permissions checking with an ACL David Howells
2019-02-15 16:11   ` David Howells
2019-02-15 17:32   ` Stephen Smalley
2019-02-15 17:32     ` Stephen Smalley
2019-02-15 17:39   ` David Howells
2019-02-15 17:39     ` David Howells
2019-09-30 16:39     ` Richard Haines
2019-09-30 16:39       ` Richard Haines
2019-02-15 16:11 ` [RFC PATCH 23/27] KEYS: Provide KEYCTL_GRANT_PERMISSION David Howells
2019-02-15 16:11   ` David Howells
2019-02-15 16:11 ` [RFC PATCH 24/27] keys: Allow a container to be specified as a subject in a key's ACL David Howells
2019-02-15 16:11   ` David Howells
2019-02-15 16:11 ` [RFC PATCH 25/27] keys: Provide a way to ask for the container keyring David Howells
2019-02-15 16:11   ` David Howells
2019-02-15 16:12 ` [RFC PATCH 26/27] keys: Allow containers to be included in key ACLs by name David Howells
2019-02-15 16:12   ` David Howells
2019-02-15 16:12 ` [RFC PATCH 27/27] containers: Sample to grant access to a key in a container David Howells
2019-02-15 16:12   ` David Howells
2019-02-15 22:36 ` [RFC PATCH 00/27] Containers and using authenticated filesystems James Morris
2019-02-15 22:36   ` James Morris
2019-02-19 16:35 ` Eric W. Biederman
2019-02-19 16:35   ` Eric W. Biederman
2019-02-19 16:35   ` Eric W. Biederman
2019-02-20 14:18   ` Christian Brauner
2019-02-20 14:18     ` Christian Brauner
2019-02-19 23:42 ` David Howells
2019-02-19 23:42   ` David Howells
2019-02-20  7:00   ` Paul Moore
2019-02-20  7:00     ` Paul Moore
2019-02-20 18:54   ` Steve French
2019-02-20 18:54     ` Steve French

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=155024703003.21651.3499235528404179500.stgit@warthog.procyon.org.uk \
    --to=dhowells@redhat.com \
    --cc=keyrings@vger.kernel.org \
    --cc=linux-cifs@vger.kernel.org \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-nfs@vger.kernel.org \
    --cc=linux-security-module@vger.kernel.org \
    --cc=rgb@redhat.com \
    --cc=sfrench@samba.org \
    --cc=trond.myklebust@hammerspace.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.