2 * Copyright (C) 2013-2015 Kay Sievers
3 * Copyright (C) 2013-2015 Greg Kroah-Hartman <gregkh@linuxfoundation.org>
4 * Copyright (C) 2013-2015 Daniel Mack <daniel@zonque.org>
5 * Copyright (C) 2013-2015 David Herrmann <dh.herrmann@gmail.com>
6 * Copyright (C) 2013-2015 Linux Foundation
7 * Copyright (C) 2014-2015 Djalal Harouni <tixxdz@opendz.org>
9 * kdbus is free software; you can redistribute it and/or modify it under
10 * the terms of the GNU Lesser General Public License as published by the
11 * Free Software Foundation; either version 2.1 of the License, or (at
12 * your option) any later version.
15 #include <linux/cred.h>
17 #include <linux/idr.h>
18 #include <linux/init.h>
19 #include <linux/module.h>
20 #include <linux/sched.h>
21 #include <linux/sizes.h>
22 #include <linux/slab.h>
23 #include <linux/uaccess.h>
32 static void kdbus_domain_control_free(struct kdbus_node *node)
37 static struct kdbus_node *kdbus_domain_control_new(struct kdbus_domain *domain,
40 struct kdbus_node *node;
43 node = kzalloc(sizeof(*node), GFP_KERNEL);
45 return ERR_PTR(-ENOMEM);
47 kdbus_node_init(node, KDBUS_NODE_CONTROL);
49 node->free_cb = kdbus_domain_control_free;
50 node->mode = domain->node.mode;
51 node->mode = S_IRUSR | S_IWUSR;
52 if (access & (KDBUS_MAKE_ACCESS_GROUP | KDBUS_MAKE_ACCESS_WORLD))
53 node->mode |= S_IRGRP | S_IWGRP;
54 if (access & KDBUS_MAKE_ACCESS_WORLD)
55 node->mode |= S_IROTH | S_IWOTH;
57 ret = kdbus_node_link(node, &domain->node, "control");
64 kdbus_node_deactivate(node);
65 kdbus_node_unref(node);
69 static void kdbus_domain_free(struct kdbus_node *node)
71 struct kdbus_domain *domain =
72 container_of(node, struct kdbus_domain, node);
74 put_user_ns(domain->user_namespace);
75 ida_destroy(&domain->user_ida);
76 idr_destroy(&domain->user_idr);
81 * kdbus_domain_new() - create a new domain
82 * @access: The access mode for this node (KDBUS_MAKE_ACCESS_*)
84 * Return: a new kdbus_domain on success, ERR_PTR on failure
86 struct kdbus_domain *kdbus_domain_new(unsigned int access)
88 struct kdbus_domain *d;
91 d = kzalloc(sizeof(*d), GFP_KERNEL);
93 return ERR_PTR(-ENOMEM);
95 kdbus_node_init(&d->node, KDBUS_NODE_DOMAIN);
97 d->node.free_cb = kdbus_domain_free;
98 d->node.mode = S_IRUSR | S_IXUSR;
99 if (access & (KDBUS_MAKE_ACCESS_GROUP | KDBUS_MAKE_ACCESS_WORLD))
100 d->node.mode |= S_IRGRP | S_IXGRP;
101 if (access & KDBUS_MAKE_ACCESS_WORLD)
102 d->node.mode |= S_IROTH | S_IXOTH;
104 mutex_init(&d->lock);
105 idr_init(&d->user_idr);
106 ida_init(&d->user_ida);
108 /* Pin user namespace so we can guarantee domain-unique bus * names. */
109 d->user_namespace = get_user_ns(current_user_ns());
111 ret = kdbus_node_link(&d->node, NULL, NULL);
118 kdbus_node_deactivate(&d->node);
119 kdbus_node_unref(&d->node);
124 * kdbus_domain_ref() - take a domain reference
127 * Return: the domain itself
129 struct kdbus_domain *kdbus_domain_ref(struct kdbus_domain *domain)
132 kdbus_node_ref(&domain->node);
137 * kdbus_domain_unref() - drop a domain reference
140 * When the last reference is dropped, the domain internal structure
145 struct kdbus_domain *kdbus_domain_unref(struct kdbus_domain *domain)
148 kdbus_node_unref(&domain->node);
153 * kdbus_domain_populate() - populate static domain nodes
154 * @domain: domain to populate
155 * @access: KDBUS_MAKE_ACCESS_* access restrictions for new nodes
157 * Allocate and activate static sub-nodes of the given domain. This will fail if
158 * you call it on a non-active node or if the domain was already populated.
160 * Return: 0 on success, negative error code on failure.
162 int kdbus_domain_populate(struct kdbus_domain *domain, unsigned int access)
164 struct kdbus_node *control;
167 * Create a control-node for this domain. We drop our own reference
168 * immediately, effectively causing the node to be deactivated and
169 * released when the parent domain is.
171 control = kdbus_domain_control_new(domain, access);
173 return PTR_ERR(control);
175 kdbus_node_activate(control);
176 kdbus_node_unref(control);
181 * kdbus_user_lookup() - lookup a kdbus_user object
182 * @domain: domain of the user
183 * @uid: uid of the user; INVALID_UID for an anon user
185 * Lookup the kdbus user accounting object for the given domain. If INVALID_UID
186 * is passed, a new anonymous user is created which is private to the caller.
188 * Return: The user object is returned, ERR_PTR on failure.
190 struct kdbus_user *kdbus_user_lookup(struct kdbus_domain *domain, kuid_t uid)
192 struct kdbus_user *u = NULL, *old = NULL;
195 mutex_lock(&domain->lock);
197 if (uid_valid(uid)) {
198 old = idr_find(&domain->user_idr, __kuid_val(uid));
200 * If the object is about to be destroyed, ignore it and
201 * replace the slot in the IDR later on.
203 if (old && kref_get_unless_zero(&old->kref)) {
204 mutex_unlock(&domain->lock);
209 u = kzalloc(sizeof(*u), GFP_KERNEL);
216 u->domain = kdbus_domain_ref(domain);
218 atomic_set(&u->buses, 0);
219 atomic_set(&u->connections, 0);
221 if (uid_valid(uid)) {
223 idr_replace(&domain->user_idr, u, __kuid_val(uid));
224 old->uid = INVALID_UID; /* mark old as removed */
226 ret = idr_alloc(&domain->user_idr, u, __kuid_val(uid),
227 __kuid_val(uid) + 1, GFP_KERNEL);
234 * Allocate the smallest possible index for this user; used
235 * in arrays for accounting user quota in receiver queues.
237 ret = ida_simple_get(&domain->user_ida, 1, 0, GFP_KERNEL);
242 mutex_unlock(&domain->lock);
247 if (uid_valid(u->uid))
248 idr_remove(&domain->user_idr, __kuid_val(u->uid));
249 kdbus_domain_unref(u->domain);
252 mutex_unlock(&domain->lock);
256 static void __kdbus_user_free(struct kref *kref)
258 struct kdbus_user *user = container_of(kref, struct kdbus_user, kref);
260 WARN_ON(atomic_read(&user->buses) > 0);
261 WARN_ON(atomic_read(&user->connections) > 0);
263 mutex_lock(&user->domain->lock);
264 ida_simple_remove(&user->domain->user_ida, user->id);
265 if (uid_valid(user->uid))
266 idr_remove(&user->domain->user_idr, __kuid_val(user->uid));
267 mutex_unlock(&user->domain->lock);
269 kdbus_domain_unref(user->domain);
274 * kdbus_user_ref() - take a user reference
277 * Return: @u is returned
279 struct kdbus_user *kdbus_user_ref(struct kdbus_user *u)
287 * kdbus_user_unref() - drop a user reference
292 struct kdbus_user *kdbus_user_unref(struct kdbus_user *u)
295 kref_put(&u->kref, __kdbus_user_free);