lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date:   Wed, 26 Oct 2016 21:17:58 +0200
From:   David Herrmann <dh.herrmann@...il.com>
To:     linux-kernel@...r.kernel.org
Cc:     Andy Lutomirski <luto@...capital.net>,
        Jiri Kosina <jikos@...nel.org>, Greg KH <greg@...ah.com>,
        Hannes Reinecke <hare@...e.com>,
        Steven Rostedt <rostedt@...dmis.org>,
        Arnd Bergmann <arnd@...db.de>, Tom Gundersen <teg@...m.no>,
        David Herrmann <dh.herrmann@...il.com>,
        Josh Triplett <josh@...htriplett.org>,
        Linus Torvalds <torvalds@...ux-foundation.org>,
        Andrew Morton <akpm@...ux-foundation.org>
Subject: [RFC v1 02/14] bus1: provide stub cdev /dev/bus1

From: Tom Gundersen <teg@...m.no>

Add the CONFIG_BUS1 option to enable the bus1 kernel messaging bus. If
enabled, provide the bus1.ko module with a stub cdev /dev/bus1. So far
it does not expose any API, but the full intended uapi is provided in
include/uapi/linux/bus1.h already.

Signed-off-by: Tom Gundersen <teg@...m.no>
Signed-off-by: David Herrmann <dh.herrmann@...il.com>
---
 include/uapi/linux/bus1.h | 138 ++++++++++++++++++++++++++++++++++++++++++++++
 init/Kconfig              |  17 ++++++
 ipc/Makefile              |   1 +
 ipc/bus1/Makefile         |   6 ++
 ipc/bus1/main.c           |  80 +++++++++++++++++++++++++++
 ipc/bus1/main.h           |  74 +++++++++++++++++++++++++
 ipc/bus1/tests.c          |  19 +++++++
 ipc/bus1/tests.h          |  32 +++++++++++
 8 files changed, 367 insertions(+)
 create mode 100644 include/uapi/linux/bus1.h
 create mode 100644 ipc/bus1/Makefile
 create mode 100644 ipc/bus1/main.c
 create mode 100644 ipc/bus1/main.h
 create mode 100644 ipc/bus1/tests.c
 create mode 100644 ipc/bus1/tests.h

diff --git a/include/uapi/linux/bus1.h b/include/uapi/linux/bus1.h
new file mode 100644
index 0000000..8ec3357
--- /dev/null
+++ b/include/uapi/linux/bus1.h
@@ -0,0 +1,138 @@
+#ifndef _UAPI_LINUX_BUS1_H
+#define _UAPI_LINUX_BUS1_H
+
+/*
+ * Copyright (C) 2013-2016 Red Hat, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by the
+ * Free Software Foundation; either version 2.1 of the License, or (at
+ * your option) any later version.
+ */
+
+#include <linux/ioctl.h>
+#include <linux/types.h>
+
+#define BUS1_FD_MAX			(256)
+
+#define BUS1_IOCTL_MAGIC		0x96
+#define BUS1_HANDLE_INVALID		((__u64)-1)
+#define BUS1_OFFSET_INVALID		((__u64)-1)
+
+enum {
+	BUS1_HANDLE_FLAG_MANAGED				= 1ULL <<  0,
+	BUS1_HANDLE_FLAG_REMOTE					= 1ULL <<  1,
+};
+
+enum {
+	BUS1_PEER_FLAG_WANT_SECCTX				= 1ULL <<  0,
+};
+
+enum {
+	BUS1_PEER_RESET_FLAG_FLUSH				= 1ULL <<  0,
+	BUS1_PEER_RESET_FLAG_FLUSH_SEED				= 1ULL <<  1,
+};
+
+struct bus1_cmd_peer_reset {
+	__u64 flags;
+	__u64 peer_flags;
+	__u32 max_slices;
+	__u32 max_handles;
+	__u32 max_inflight_bytes;
+	__u32 max_inflight_fds;
+} __attribute__((__aligned__(8)));
+
+struct bus1_cmd_handle_transfer {
+	__u64 flags;
+	__u64 src_handle;
+	__u64 dst_fd;
+	__u64 dst_handle;
+} __attribute__((__aligned__(8)));
+
+enum {
+	BUS1_NODES_DESTROY_FLAG_RELEASE_HANDLES			= 1ULL <<  0,
+};
+
+struct bus1_cmd_nodes_destroy {
+	__u64 flags;
+	__u64 ptr_nodes;
+	__u64 n_nodes;
+} __attribute__((__aligned__(8)));
+
+enum {
+	BUS1_SEND_FLAG_CONTINUE					= 1ULL <<  0,
+	BUS1_SEND_FLAG_SEED					= 1ULL <<  1,
+};
+
+struct bus1_cmd_send {
+	__u64 flags;
+	__u64 ptr_destinations;
+	__u64 ptr_errors;
+	__u64 n_destinations;
+	__u64 ptr_vecs;
+	__u64 n_vecs;
+	__u64 ptr_handles;
+	__u64 n_handles;
+	__u64 ptr_fds;
+	__u64 n_fds;
+} __attribute__((__aligned__(8)));
+
+enum {
+	BUS1_RECV_FLAG_PEEK					= 1ULL <<  0,
+	BUS1_RECV_FLAG_SEED					= 1ULL <<  1,
+	BUS1_RECV_FLAG_INSTALL_FDS				= 1ULL <<  2,
+};
+
+enum {
+	BUS1_MSG_NONE,
+	BUS1_MSG_DATA,
+	BUS1_MSG_NODE_DESTROY,
+	BUS1_MSG_NODE_RELEASE,
+};
+
+enum {
+	BUS1_MSG_FLAG_HAS_SECCTX				= 1ULL <<  0,
+	BUS1_MSG_FLAG_CONTINUE					= 1ULL <<  1,
+};
+
+struct bus1_cmd_recv {
+	__u64 flags;
+	__u64 max_offset;
+	struct {
+		__u64 type;
+		__u64 flags;
+		__u64 destination;
+		__u32 uid;
+		__u32 gid;
+		__u32 pid;
+		__u32 tid;
+		__u64 offset;
+		__u64 n_bytes;
+		__u64 n_handles;
+		__u64 n_fds;
+		__u64 n_secctx;
+	} __attribute__((__aligned__(8))) msg;
+} __attribute__((__aligned__(8)));
+
+enum {
+	BUS1_CMD_PEER_DISCONNECT	= _IOWR(BUS1_IOCTL_MAGIC, 0x00,
+					__u64),
+	BUS1_CMD_PEER_QUERY		= _IOWR(BUS1_IOCTL_MAGIC, 0x01,
+					struct bus1_cmd_peer_reset),
+	BUS1_CMD_PEER_RESET		= _IOWR(BUS1_IOCTL_MAGIC, 0x02,
+					struct bus1_cmd_peer_reset),
+	BUS1_CMD_HANDLE_RELEASE		= _IOWR(BUS1_IOCTL_MAGIC, 0x10,
+					__u64),
+	BUS1_CMD_HANDLE_TRANSFER	= _IOWR(BUS1_IOCTL_MAGIC, 0x11,
+					struct bus1_cmd_handle_transfer),
+	BUS1_CMD_NODES_DESTROY		= _IOWR(BUS1_IOCTL_MAGIC, 0x20,
+					struct bus1_cmd_nodes_destroy),
+	BUS1_CMD_SLICE_RELEASE		= _IOWR(BUS1_IOCTL_MAGIC, 0x30,
+					__u64),
+	BUS1_CMD_SEND			= _IOWR(BUS1_IOCTL_MAGIC, 0x40,
+					struct bus1_cmd_send),
+	BUS1_CMD_RECV			= _IOWR(BUS1_IOCTL_MAGIC, 0x50,
+					struct bus1_cmd_recv),
+};
+
+#endif /* _UAPI_LINUX_BUS1_H */
diff --git a/init/Kconfig b/init/Kconfig
index 34407f1..04c7daf 100644
--- a/init/Kconfig
+++ b/init/Kconfig
@@ -273,6 +273,23 @@ config POSIX_MQUEUE_SYSCTL
 	depends on SYSCTL
 	default y
 
+config BUS1
+	tristate "Bus1 Kernel Message Bus"
+	help
+	  The Bus1 Kernel Message Bus defines and implements a distributed
+	  object model. It provides a capability-based IPC system for machine
+	  local communication.
+
+	  The Bus1 IPC system is exposed via /dev/bus1. If debugfs is enabled,
+	  bus1 exposes additional debug information there.
+
+config BUS1_TESTS
+	bool "Bus1 Self-Tests"
+	depends on BUS1
+	help
+	  Enable and run the bus1 self-tests before loading the module. The
+	  overhead is minimal, so there is generally no harm in enabling it.
+
 config CROSS_MEMORY_ATTACH
 	bool "Enable process_vm_readv/writev syscalls"
 	depends on MMU
diff --git a/ipc/Makefile b/ipc/Makefile
index 86c7300..eee12d1 100644
--- a/ipc/Makefile
+++ b/ipc/Makefile
@@ -9,4 +9,5 @@ obj_mq-$(CONFIG_COMPAT) += compat_mq.o
 obj-$(CONFIG_POSIX_MQUEUE) += mqueue.o msgutil.o $(obj_mq-y)
 obj-$(CONFIG_IPC_NS) += namespace.o
 obj-$(CONFIG_POSIX_MQUEUE_SYSCTL) += mq_sysctl.o
+obj-$(CONFIG_BUS1) += bus1/
 
diff --git a/ipc/bus1/Makefile b/ipc/bus1/Makefile
new file mode 100644
index 0000000..d3a4491
--- /dev/null
+++ b/ipc/bus1/Makefile
@@ -0,0 +1,6 @@
+bus1-y :=			\
+	main.o
+
+obj-$(CONFIG_BUS1) += bus1.o
+
+bus1-$(CONFIG_BUS1_TESTS) += tests.o
diff --git a/ipc/bus1/main.c b/ipc/bus1/main.c
new file mode 100644
index 0000000..02412a7
--- /dev/null
+++ b/ipc/bus1/main.c
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2013-2016 Red Hat, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by the
+ * Free Software Foundation; either version 2.1 of the License, or (at
+ * your option) any later version.
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+#include <linux/debugfs.h>
+#include <linux/err.h>
+#include <linux/fs.h>
+#include <linux/init.h>
+#include <linux/miscdevice.h>
+#include <linux/module.h>
+#include "main.h"
+#include "tests.h"
+
+static int bus1_fop_open(struct inode *inode, struct file *file)
+{
+	return 0;
+}
+
+static int bus1_fop_release(struct inode *inode, struct file *file)
+{
+	return 0;
+}
+
+const struct file_operations bus1_fops = {
+	.owner			= THIS_MODULE,
+	.open			= bus1_fop_open,
+	.release		= bus1_fop_release,
+	.llseek			= noop_llseek,
+};
+
+static struct miscdevice bus1_misc = {
+	.fops			= &bus1_fops,
+	.minor			= MISC_DYNAMIC_MINOR,
+	.name			= KBUILD_MODNAME,
+	.mode			= S_IRUGO | S_IWUGO,
+};
+
+struct dentry *bus1_debugdir;
+
+static int __init bus1_modinit(void)
+{
+	int r;
+
+	r = bus1_tests_run();
+	if (r < 0)
+		return r;
+
+	bus1_debugdir = debugfs_create_dir(KBUILD_MODNAME, NULL);
+	if (!bus1_debugdir)
+		pr_err("cannot create debugfs root\n");
+
+	r = misc_register(&bus1_misc);
+	if (r < 0)
+		goto error;
+
+	pr_info("loaded\n");
+	return 0;
+
+error:
+	debugfs_remove(bus1_debugdir);
+	return r;
+}
+
+static void __exit bus1_modexit(void)
+{
+	misc_deregister(&bus1_misc);
+	debugfs_remove(bus1_debugdir);
+	pr_info("unloaded\n");
+}
+
+module_init(bus1_modinit);
+module_exit(bus1_modexit);
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Bus based interprocess communication");
diff --git a/ipc/bus1/main.h b/ipc/bus1/main.h
new file mode 100644
index 0000000..76fce66
--- /dev/null
+++ b/ipc/bus1/main.h
@@ -0,0 +1,74 @@
+#ifndef __BUS1_MAIN_H
+#define __BUS1_MAIN_H
+
+/*
+ * Copyright (C) 2013-2016 Red Hat, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by the
+ * Free Software Foundation; either version 2.1 of the License, or (at
+ * your option) any later version.
+ */
+
+/**
+ * DOC: Bus1 Overview
+ *
+ * bus1 is a local IPC system, which provides a decentralized infrastructure to
+ * share objects between local peers. The main building blocks are nodes and
+ * handles. Nodes represent objects of a local peer, while handles represent
+ * descriptors that point to a node. Nodes can be created and destroyed by any
+ * peer, and they will always remain owned by their respective creator. Handles,
+ * on the other hand, are used to refer to nodes and can be passed around with
+ * messages as auxiliary data. Whenever a handle is transferred, the receiver
+ * will get its own handle allocated, pointing to the same node as the original
+ * handle.
+ *
+ * Any peer can send messages directed at one of their handles. This will
+ * transfer the message to the owner of the node the handle points to. If a
+ * peer does not posess a handle to a given node, it will not be able to send a
+ * message to that node. That is, handles provide exclusive access management.
+ * Anyone that somehow acquired a handle to a node is privileged to further
+ * send this handle to other peers. As such, access management is transitive.
+ * Once a peer acquired a handle, it cannot be revoked again. However, a node
+ * owner can, at anytime, destroy a node. This will effectively unbind all
+ * existing handles to that node on any peer, notifying each one of the
+ * destruction.
+ *
+ * Unlike nodes and handles, peers cannot be addressed directly. In fact, peers
+ * are completely disconnected entities. A peer is merely an anchor of a set of
+ * nodes and handles, including an incoming message queue for any of those.
+ * Whether multiple nodes are all part of the same peer, or part of different
+ * peers does not affect the remote view of those. Peers solely exist as
+ * management entity and command dispatcher to local processes.
+ *
+ * The set of actors on a system is completely decentralized. There is no
+ * global component involved that provides a central registry or discovery
+ * mechanism. Furthermore, communication between peers only involves those
+ * peers, and does not affect any other peer in any way. No global
+ * communication lock is taken. However, any communication is still globally
+ * ordered, including unicasts, multicasts, and notifications.
+ */
+
+struct dentry;
+struct file_operations;
+
+/**
+ * bus1_fops - file-operations of bus1 character devices
+ *
+ * All bus1 peers are backed by a character device with @bus1_fops used as
+ * file-operations. That is, a file is a bus1 peer if, and only if, its f_op
+ * pointer contains @bus1_fops.
+ */
+extern const struct file_operations bus1_fops;
+
+/**
+ * bus1_debugdir - debugfs root directory
+ *
+ * If debugfs is enabled, this is set to point to the debugfs root directory
+ * for this module. If debugfs is disabled, or if the root directory could not
+ * be created, this is set to NULL or ERR_PTR (which debugfs functions can deal
+ * with seamlessly).
+ */
+extern struct dentry *bus1_debugdir;
+
+#endif /* __BUS1_MAIN_H */
diff --git a/ipc/bus1/tests.c b/ipc/bus1/tests.c
new file mode 100644
index 0000000..6fd2946
--- /dev/null
+++ b/ipc/bus1/tests.c
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2013-2016 Red Hat, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by the
+ * Free Software Foundation; either version 2.1 of the License, or (at
+ * your option) any later version.
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+#include <linux/err.h>
+#include <linux/kernel.h>
+#include "tests.h"
+
+int bus1_tests_run(void)
+{
+	pr_info("run selftests..\n");
+	return 0;
+}
diff --git a/ipc/bus1/tests.h b/ipc/bus1/tests.h
new file mode 100644
index 0000000..fb554e2
--- /dev/null
+++ b/ipc/bus1/tests.h
@@ -0,0 +1,32 @@
+#ifndef __BUS1_TESTS_H
+#define __BUS1_TESTS_H
+
+/*
+ * Copyright (C) 2013-2016 Red Hat, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by the
+ * Free Software Foundation; either version 2.1 of the License, or (at
+ * your option) any later version.
+ */
+
+/**
+ * Kernel Selftests
+ *
+ * These tests are built into the kernel module itself if, and only if, the
+ * required configuration is selected. On every module load, the selftests will
+ * be run. On production builds, this option should not be selected.
+ */
+
+#include <linux/kernel.h>
+
+#if IS_ENABLED(CONFIG_BUS1_TESTS)
+int bus1_tests_run(void);
+#else
+static inline int bus1_tests_run(void)
+{
+	return 0;
+}
+#endif
+
+#endif /* __BUS1_TESTS_H */
-- 
2.10.1

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ