ac9f760c150dd6c387e51ab3b6675dac947c4344
[platform/kernel/linux-rpi.git] / ipc / kdbus / domain.c
1 /*
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>
8  *
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.
13  */
14
15 #include <linux/fs.h>
16 #include <linux/idr.h>
17 #include <linux/init.h>
18 #include <linux/module.h>
19 #include <linux/sched.h>
20 #include <linux/sizes.h>
21 #include <linux/slab.h>
22 #include <linux/uaccess.h>
23
24 #include "bus.h"
25 #include "domain.h"
26 #include "handle.h"
27 #include "item.h"
28 #include "limits.h"
29 #include "util.h"
30
31 static void kdbus_domain_control_free(struct kdbus_node *node)
32 {
33         kfree(node);
34 }
35
36 static struct kdbus_node *kdbus_domain_control_new(struct kdbus_domain *domain,
37                                                    unsigned int access)
38 {
39         struct kdbus_node *node;
40         int ret;
41
42         node = kzalloc(sizeof(*node), GFP_KERNEL);
43         if (!node)
44                 return ERR_PTR(-ENOMEM);
45
46         kdbus_node_init(node, KDBUS_NODE_CONTROL);
47
48         node->free_cb = kdbus_domain_control_free;
49         node->mode = domain->node.mode;
50         node->mode = S_IRUSR | S_IWUSR;
51         if (access & (KDBUS_MAKE_ACCESS_GROUP | KDBUS_MAKE_ACCESS_WORLD))
52                 node->mode |= S_IRGRP | S_IWGRP;
53         if (access & KDBUS_MAKE_ACCESS_WORLD)
54                 node->mode |= S_IROTH | S_IWOTH;
55
56         ret = kdbus_node_link(node, &domain->node, "control");
57         if (ret < 0)
58                 goto exit_free;
59
60         return node;
61
62 exit_free:
63         kdbus_node_deactivate(node);
64         kdbus_node_unref(node);
65         return ERR_PTR(ret);
66 }
67
68 static void kdbus_domain_free(struct kdbus_node *node)
69 {
70         struct kdbus_domain *domain =
71                 container_of(node, struct kdbus_domain, node);
72
73         put_user_ns(domain->user_namespace);
74         ida_destroy(&domain->user_ida);
75         idr_destroy(&domain->user_idr);
76         kfree(domain);
77 }
78
79 /**
80  * kdbus_domain_new() - create a new domain
81  * @access:             The access mode for this node (KDBUS_MAKE_ACCESS_*)
82  *
83  * Return: a new kdbus_domain on success, ERR_PTR on failure
84  */
85 struct kdbus_domain *kdbus_domain_new(unsigned int access)
86 {
87         struct kdbus_domain *d;
88         int ret;
89
90         d = kzalloc(sizeof(*d), GFP_KERNEL);
91         if (!d)
92                 return ERR_PTR(-ENOMEM);
93
94         kdbus_node_init(&d->node, KDBUS_NODE_DOMAIN);
95
96         d->node.free_cb = kdbus_domain_free;
97         d->node.mode = S_IRUSR | S_IXUSR;
98         if (access & (KDBUS_MAKE_ACCESS_GROUP | KDBUS_MAKE_ACCESS_WORLD))
99                 d->node.mode |= S_IRGRP | S_IXGRP;
100         if (access & KDBUS_MAKE_ACCESS_WORLD)
101                 d->node.mode |= S_IROTH | S_IXOTH;
102
103         mutex_init(&d->lock);
104         idr_init(&d->user_idr);
105         ida_init(&d->user_ida);
106
107         /* Pin user namespace so we can guarantee domain-unique bus * names. */
108         d->user_namespace = get_user_ns(current_user_ns());
109
110         ret = kdbus_node_link(&d->node, NULL, NULL);
111         if (ret < 0)
112                 goto exit_unref;
113
114         return d;
115
116 exit_unref:
117         kdbus_node_deactivate(&d->node);
118         kdbus_node_unref(&d->node);
119         return ERR_PTR(ret);
120 }
121
122 /**
123  * kdbus_domain_ref() - take a domain reference
124  * @domain:             Domain
125  *
126  * Return: the domain itself
127  */
128 struct kdbus_domain *kdbus_domain_ref(struct kdbus_domain *domain)
129 {
130         if (domain)
131                 kdbus_node_ref(&domain->node);
132         return domain;
133 }
134
135 /**
136  * kdbus_domain_unref() - drop a domain reference
137  * @domain:             Domain
138  *
139  * When the last reference is dropped, the domain internal structure
140  * is freed.
141  *
142  * Return: NULL
143  */
144 struct kdbus_domain *kdbus_domain_unref(struct kdbus_domain *domain)
145 {
146         if (domain)
147                 kdbus_node_unref(&domain->node);
148         return NULL;
149 }
150
151 /**
152  * kdbus_domain_populate() - populate static domain nodes
153  * @domain:     domain to populate
154  * @access:     KDBUS_MAKE_ACCESS_* access restrictions for new nodes
155  *
156  * Allocate and activate static sub-nodes of the given domain. This will fail if
157  * you call it on a non-active node or if the domain was already populated.
158  *
159  * Return: 0 on success, negative error code on failure.
160  */
161 int kdbus_domain_populate(struct kdbus_domain *domain, unsigned int access)
162 {
163         struct kdbus_node *control;
164
165         /*
166          * Create a control-node for this domain. We drop our own reference
167          * immediately, effectively causing the node to be deactivated and
168          * released when the parent domain is.
169          */
170         control = kdbus_domain_control_new(domain, access);
171         if (IS_ERR(control))
172                 return PTR_ERR(control);
173
174         kdbus_node_activate(control);
175         kdbus_node_unref(control);
176         return 0;
177 }
178
179 /**
180  * kdbus_user_lookup() - lookup a kdbus_user object
181  * @domain:             domain of the user
182  * @uid:                uid of the user; INVALID_UID for an anon user
183  *
184  * Lookup the kdbus user accounting object for the given domain. If INVALID_UID
185  * is passed, a new anonymous user is created which is private to the caller.
186  *
187  * Return: The user object is returned, ERR_PTR on failure.
188  */
189 struct kdbus_user *kdbus_user_lookup(struct kdbus_domain *domain, kuid_t uid)
190 {
191         struct kdbus_user *u = NULL, *old = NULL;
192         int ret;
193
194         mutex_lock(&domain->lock);
195
196         if (uid_valid(uid)) {
197                 old = idr_find(&domain->user_idr, __kuid_val(uid));
198                 /*
199                  * If the object is about to be destroyed, ignore it and
200                  * replace the slot in the IDR later on.
201                  */
202                 if (old && kref_get_unless_zero(&old->kref)) {
203                         mutex_unlock(&domain->lock);
204                         return old;
205                 }
206         }
207
208         u = kzalloc(sizeof(*u), GFP_KERNEL);
209         if (!u) {
210                 ret = -ENOMEM;
211                 goto exit;
212         }
213
214         kref_init(&u->kref);
215         u->domain = kdbus_domain_ref(domain);
216         u->uid = uid;
217         atomic_set(&u->buses, 0);
218         atomic_set(&u->connections, 0);
219
220         if (uid_valid(uid)) {
221                 if (old) {
222                         idr_replace(&domain->user_idr, u, __kuid_val(uid));
223                         old->uid = INVALID_UID; /* mark old as removed */
224                 } else {
225                         ret = idr_alloc(&domain->user_idr, u, __kuid_val(uid),
226                                         __kuid_val(uid) + 1, GFP_KERNEL);
227                         if (ret < 0)
228                                 goto exit;
229                 }
230         }
231
232         /*
233          * Allocate the smallest possible index for this user; used
234          * in arrays for accounting user quota in receiver queues.
235          */
236         ret = ida_simple_get(&domain->user_ida, 1, 0, GFP_KERNEL);
237         if (ret < 0)
238                 goto exit;
239
240         u->id = ret;
241         mutex_unlock(&domain->lock);
242         return u;
243
244 exit:
245         if (u) {
246                 if (uid_valid(u->uid))
247                         idr_remove(&domain->user_idr, __kuid_val(u->uid));
248                 kdbus_domain_unref(u->domain);
249                 kfree(u);
250         }
251         mutex_unlock(&domain->lock);
252         return ERR_PTR(ret);
253 }
254
255 static void __kdbus_user_free(struct kref *kref)
256 {
257         struct kdbus_user *user = container_of(kref, struct kdbus_user, kref);
258
259         WARN_ON(atomic_read(&user->buses) > 0);
260         WARN_ON(atomic_read(&user->connections) > 0);
261
262         mutex_lock(&user->domain->lock);
263         ida_simple_remove(&user->domain->user_ida, user->id);
264         if (uid_valid(user->uid))
265                 idr_remove(&user->domain->user_idr, __kuid_val(user->uid));
266         mutex_unlock(&user->domain->lock);
267
268         kdbus_domain_unref(user->domain);
269         kfree(user);
270 }
271
272 /**
273  * kdbus_user_ref() - take a user reference
274  * @u:          User
275  *
276  * Return: @u is returned
277  */
278 struct kdbus_user *kdbus_user_ref(struct kdbus_user *u)
279 {
280         if (u)
281                 kref_get(&u->kref);
282         return u;
283 }
284
285 /**
286  * kdbus_user_unref() - drop a user reference
287  * @u:          User
288  *
289  * Return: NULL
290  */
291 struct kdbus_user *kdbus_user_unref(struct kdbus_user *u)
292 {
293         if (u)
294                 kref_put(&u->kref, __kdbus_user_free);
295         return NULL;
296 }