Skip to contentSkip to conversation

Namespace support for Android binder (under ipc-ns)

PATCH In review Oren Laadan 3 participants 5 messages Dec 22, 2013 – Jan 8, 2014 Staging

lore
Share & tools
lore
#0 lore raw

cover Namespace support for Android binder (under ipc-ns)

Hi,

This patch-duo adds namespaces support for the Android binder driver. As discussed in Plumbers 2013, binder is a form of IPC and therefore will be tied to ipc namespace.

On the ipc-ns side, the implementation is modelled after generic net-ns pointers (see commit dec827d), but simplified to suit single user/caller for now, to reduce complexity.

The binder driver registers with ipc-ns and uses the generic pointer to store and retrieve its namespace data. That is, each namespace maintains its own binder context manager - which suffices for separation, since all transactions require binder handles provided by the context manager.

Thanks,

Oren.

Oren Laadan (2):
ipc namespace: a generic per-ipc pointer and peripc_ops
binder: implement namepsace support for Android binder driver

 drivers/staging/android/Kconfig  |   1 +
 drivers/staging/android/binder.c | 172 ++++++++++++++++++++++++++++++++-------
 include/linux/ipc_namespace.h    |  29 +++++++
 ipc/namespace.c                  |   9 ++
 ipc/util.c                       |  60 ++++++++++++++
 ipc/util.h                       |   3 +
 6 files changed, 244 insertions(+), 30 deletions(-)
Signature · 1 line
1.8.3.2
#1 lore raw

PATCH 1/2 ipc namespace: a generic per-ipc pointer and peripc_ops

Add a void * pointer to struct ipc_namespace. The access rules are:
1. (un)register ops with (un)register_peripc_operations()
2. call ipc_assign_generic() to put private data on the ipc_namespace
3. call ipc_access_generic() to access the private data
4. do not change the pointer during the lifetime of ipc_namespace

Modeled after generic net-ns pointers (commit dec827d), but simplified to accommodate a single user for now (reduce code churn):
5. only one caller can register at a time
6. caller must register at boot time (not to be used by modules)

---
 include/linux/ipc_namespace.h | 29 +++++++++++++++++++++
 ipc/namespace.c               |  9 +++++++
 ipc/util.c                    | 60 +++++++++++++++++++++++++++++++++++++++++++
 ipc/util.h                    |  3 +++
 4 files changed, 101 insertions(+)
include/linux/ipc_namespace.h +29 -0
index f6c82de..72da9bf 100644
@@ -70,8 +70,37 @@ struct ipc_namespace {
 	struct user_namespace *user_ns;
 
 	unsigned int	proc_inum;
+
+	/* allow others to piggyback on ipc_namesspaces */
+	void *gen;			/* for others' private stuff */
 };
 
+/*
+ * To access to the per-ipc generic data:
+ * 1. (un)register ops with (un)register_peripc_operations()
+ * 2. call ipc_assign_generic() to put private data on the ipc_namespace
+ * 3. call ipc_access_generic() to access the private data
+ * 4. do not change the pointer during the lifetime of ipc_namespace
+ *
+ * Modeled after generic net-ns pointers (commit dec827d), simplified for
+ * a single user case for now:
+ * 5. only one caller can register at a time
+ * 6. caller must register at boot time (not to be used by modules)
+ */
+struct peripc_operations {
+	int (*init)(struct ipc_namespace *);
+	void (*exit)(struct ipc_namespace *);
+};
+
+static inline void ipc_assign_generic(struct ipc_namespace *ns, void *data)
+{ ns->gen = data; }
+
+static inline void *ipc_access_generic(struct ipc_namespace *ns)
+{ return ns->gen; }
+
+extern int register_peripc_ops(struct peripc_operations *ops);
+extern void unregister_peripc_ops(struct peripc_operations *ops);
+
 extern struct ipc_namespace init_ipc_ns;
 extern atomic_t nr_ipc_ns;
 
ipc/namespace.c +9 -0
index 59451c1..83968b6 100644
@@ -33,9 +33,17 @@ static struct ipc_namespace *create_ipc_ns(struct user_namespace *user_ns,
 	}
 
 	atomic_set(&ns->count, 1);
+
+	err = init_peripc_ns(ns);
+	if (err) {
+		kfree(ns);
+		return ERR_PTR(err);
+	}
+
 	err = mq_init_ns(ns);
 	if (err) {
 		proc_free_inum(ns->proc_inum);
+		exit_peripc_ns(ns);
 		kfree(ns);
 		return ERR_PTR(err);
 	}
@@ -111,6 +119,7 @@ static void free_ipc_ns(struct ipc_namespace *ns)
 	sem_exit_ns(ns);
 	msg_exit_ns(ns);
 	shm_exit_ns(ns);
+	exit_peripc_ns(ns);
 	atomic_dec(&nr_ipc_ns);
 
 	/*
ipc/util.c +60 -0

66 lines not on this page · raw message

ipc/util.h +3 -0
index 59d78aa..daee0be 100644
@@ -47,6 +47,9 @@ static inline void msg_exit_ns(struct ipc_namespace *ns) { }
 static inline void shm_exit_ns(struct ipc_namespace *ns) { }
 #endif
 
+int init_peripc_ns(struct ipc_namespace *ns);
+void exit_peripc_ns(struct ipc_namespace *ns);
+
 struct ipc_rcu {
 	struct rcu_head rcu;
 	atomic_t refcount;
Signature · 1 line
1.8.3.2
#2 lore raw

PATCH 2/2 binder: implement namepsace support for Android binder driver

In reply to Oren Laadan

Add namespaces support for the Android binder driver. As binder is an IPC mechanism, tie its namespace to IPC_NS.

In binder, the first process to call BINDER_SET_CONTEXT_MGR ioctl becomes the manager with context 0, and thereafter IPC is realized through binder handles obtained from this manager.

For namespaces, associate a separate binder state with each namespace so each namespace has its own context manager. Binder users within a namespace interact only with the context manager there. This suffices because binder does not allow IPC not via the context manager.

Currently, statistics remain global, except for the list of processes that hold an open binder device (reported per namespace).

---
 drivers/staging/android/Kconfig  |   1 +
 drivers/staging/android/binder.c | 172 ++++++++++++++++++++++++++++++++-------
 2 files changed, 143 insertions(+), 30 deletions(-)
drivers/staging/android/Kconfig +1 -0
index 1e9ab6d..208685e 100644
@@ -11,6 +11,7 @@ if ANDROID
 config ANDROID_BINDER_IPC
 	bool "Android Binder IPC Driver"
 	depends on MMU
+	select SYSVIPC
 	default n
 	---help---
 	  Binder is used in Android for both communication between processes,
drivers/staging/android/binder.c +142 -30

358 lines not on this page · raw message

Signature · 1 line
1.8.3.2
#3 lore raw

Re: [PATCH 2/2] binder: implement namepsace support for Android binder driver

Quoted 4 lines

#include <linux/uaccess.h>
#include <linux/vmalloc.h>
#include <linux/slab.h>

drivers/staging/android/binder.c line 48

Quoted 10 lines
drivers/staging/android/binder.c +5 -0
+#include <linux/ipc_namespace.h>
 #include <linux/pid_namespace.h>
 
 #include "binder.h"
 #include "binder_trace.h"
 
+/*
+ * Using a private context manager for each binder namespace is sufficient
+ * to isolate between namespaces, because in binder all IPC must be realized
+ * via hanldes obtained from the context manager.

handles

Quoted 11 lines

+ *
+ * TODO: currently, most debugfs data is not tracked per binder namespaces.
+ * Except for "procs" which are properly virtualized, everything else is
+ * global, including stats, logs, and dead nodes.
+ */

drivers/staging/android/binder.c +6 -0
+struct binder_namespace {
+	struct kref kref;
+
+	struct binder_node *context_mgr_node;
+	kuid_t context_mgr_uid;
+	int last_id;
#4 lore raw

Re: [PATCH 2/2] binder: implement namepsace support for Android binder driver

In reply to Oren Laadan
Quoted 2 lines · Oren Laadan

Add namespaces support for the Android binder driver. As binder is an IPC mechanism, tie its namespace to IPC_NS.

Why does binder need namespace support?

Does the Android userspace code support this?

I need an ack from the Android developers before I can take this.

Same goes for the ipc core changes, I need an ack from the maintainer of that code before I can take it as well.

thanks,

greg k-h