kdbus: the driver, original and non-working
[platform/kernel/linux-rpi.git] / ipc / kdbus / endpoint.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 #include <linux/uio.h>
24
25 #include "bus.h"
26 #include "connection.h"
27 #include "domain.h"
28 #include "endpoint.h"
29 #include "handle.h"
30 #include "item.h"
31 #include "message.h"
32 #include "policy.h"
33
34 static void kdbus_ep_free(struct kdbus_node *node)
35 {
36         struct kdbus_ep *ep = container_of(node, struct kdbus_ep, node);
37
38         WARN_ON(!list_empty(&ep->conn_list));
39
40         kdbus_policy_db_clear(&ep->policy_db);
41         kdbus_bus_unref(ep->bus);
42         kdbus_user_unref(ep->user);
43         kfree(ep);
44 }
45
46 static void kdbus_ep_release(struct kdbus_node *node, bool was_active)
47 {
48         struct kdbus_ep *ep = container_of(node, struct kdbus_ep, node);
49
50         /* disconnect all connections to this endpoint */
51         for (;;) {
52                 struct kdbus_conn *conn;
53
54                 mutex_lock(&ep->lock);
55                 conn = list_first_entry_or_null(&ep->conn_list,
56                                                 struct kdbus_conn,
57                                                 ep_entry);
58                 if (!conn) {
59                         mutex_unlock(&ep->lock);
60                         break;
61                 }
62
63                 /* take reference, release lock, disconnect without lock */
64                 kdbus_conn_ref(conn);
65                 mutex_unlock(&ep->lock);
66
67                 kdbus_conn_disconnect(conn, false);
68                 kdbus_conn_unref(conn);
69         }
70 }
71
72 /**
73  * kdbus_ep_new() - create a new endpoint
74  * @bus:                The bus this endpoint will be created for
75  * @name:               The name of the endpoint
76  * @access:             The access flags for this node (KDBUS_MAKE_ACCESS_*)
77  * @uid:                The uid of the node
78  * @gid:                The gid of the node
79  * @is_custom:          Whether this is a custom endpoint
80  *
81  * This function will create a new endpoint with the given
82  * name and properties for a given bus.
83  *
84  * Return: a new kdbus_ep on success, ERR_PTR on failure.
85  */
86 struct kdbus_ep *kdbus_ep_new(struct kdbus_bus *bus, const char *name,
87                               unsigned int access, kuid_t uid, kgid_t gid,
88                               bool is_custom)
89 {
90         struct kdbus_ep *e;
91         int ret;
92
93         /*
94          * Validate only custom endpoints names, default endpoints
95          * with a "bus" name are created when the bus is created
96          */
97         if (is_custom) {
98                 ret = kdbus_verify_uid_prefix(name, bus->domain->user_namespace,
99                                               uid);
100                 if (ret < 0)
101                         return ERR_PTR(ret);
102         }
103
104         e = kzalloc(sizeof(*e), GFP_KERNEL);
105         if (!e)
106                 return ERR_PTR(-ENOMEM);
107
108         kdbus_node_init(&e->node, KDBUS_NODE_ENDPOINT);
109
110         e->node.free_cb = kdbus_ep_free;
111         e->node.release_cb = kdbus_ep_release;
112         e->node.uid = uid;
113         e->node.gid = gid;
114         e->node.mode = S_IRUSR | S_IWUSR;
115         if (access & (KDBUS_MAKE_ACCESS_GROUP | KDBUS_MAKE_ACCESS_WORLD))
116                 e->node.mode |= S_IRGRP | S_IWGRP;
117         if (access & KDBUS_MAKE_ACCESS_WORLD)
118                 e->node.mode |= S_IROTH | S_IWOTH;
119
120         mutex_init(&e->lock);
121         INIT_LIST_HEAD(&e->conn_list);
122         kdbus_policy_db_init(&e->policy_db);
123         e->bus = kdbus_bus_ref(bus);
124
125         ret = kdbus_node_link(&e->node, &bus->node, name);
126         if (ret < 0)
127                 goto exit_unref;
128
129         /*
130          * Transactions on custom endpoints are never accounted on the global
131          * user limits. Instead, for each custom endpoint, we create a custom,
132          * unique user, which all transactions are accounted on. Regardless of
133          * the user using that endpoint, it is always accounted on the same
134          * user-object. This budget is not shared with ordinary users on
135          * non-custom endpoints.
136          */
137         if (is_custom) {
138                 e->user = kdbus_user_lookup(bus->domain, INVALID_UID);
139                 if (IS_ERR(e->user)) {
140                         ret = PTR_ERR(e->user);
141                         e->user = NULL;
142                         goto exit_unref;
143                 }
144         }
145
146         return e;
147
148 exit_unref:
149         kdbus_node_deactivate(&e->node);
150         kdbus_node_unref(&e->node);
151         return ERR_PTR(ret);
152 }
153
154 /**
155  * kdbus_ep_ref() - increase the reference counter of a kdbus_ep
156  * @ep:                 The endpoint to reference
157  *
158  * Every user of an endpoint, except for its creator, must add a reference to
159  * the kdbus_ep instance using this function.
160  *
161  * Return: the ep itself
162  */
163 struct kdbus_ep *kdbus_ep_ref(struct kdbus_ep *ep)
164 {
165         if (ep)
166                 kdbus_node_ref(&ep->node);
167         return ep;
168 }
169
170 /**
171  * kdbus_ep_unref() - decrease the reference counter of a kdbus_ep
172  * @ep:         The ep to unref
173  *
174  * Release a reference. If the reference count drops to 0, the ep will be
175  * freed.
176  *
177  * Return: NULL
178  */
179 struct kdbus_ep *kdbus_ep_unref(struct kdbus_ep *ep)
180 {
181         if (ep)
182                 kdbus_node_unref(&ep->node);
183         return NULL;
184 }
185
186 /**
187  * kdbus_ep_is_privileged() - check whether a file is privileged
188  * @ep:         endpoint to operate on
189  * @file:       file to test
190  *
191  * Return: True if @file is privileged in the domain of @ep.
192  */
193 bool kdbus_ep_is_privileged(struct kdbus_ep *ep, struct file *file)
194 {
195         return !ep->user &&
196                 file_ns_capable(file, ep->bus->domain->user_namespace,
197                                 CAP_IPC_OWNER);
198 }
199
200 /**
201  * kdbus_ep_is_owner() - check whether a file should be treated as bus owner
202  * @ep:         endpoint to operate on
203  * @file:       file to test
204  *
205  * Return: True if @file should be treated as bus owner on @ep
206  */
207 bool kdbus_ep_is_owner(struct kdbus_ep *ep, struct file *file)
208 {
209         return !ep->user &&
210                 (uid_eq(file->f_cred->euid, ep->bus->node.uid) ||
211                  kdbus_ep_is_privileged(ep, file));
212 }
213
214 /**
215  * kdbus_cmd_ep_make() - handle KDBUS_CMD_ENDPOINT_MAKE
216  * @bus:                bus to operate on
217  * @argp:               command payload
218  *
219  * Return: NULL or newly created endpoint on success, ERR_PTR on failure.
220  */
221 struct kdbus_ep *kdbus_cmd_ep_make(struct kdbus_bus *bus, void __user *argp)
222 {
223         const char *item_make_name;
224         struct kdbus_ep *ep = NULL;
225         struct kdbus_cmd *cmd;
226         int ret;
227
228         struct kdbus_arg argv[] = {
229                 { .type = KDBUS_ITEM_NEGOTIATE },
230                 { .type = KDBUS_ITEM_MAKE_NAME, .mandatory = true },
231         };
232         struct kdbus_args args = {
233                 .allowed_flags = KDBUS_FLAG_NEGOTIATE |
234                                  KDBUS_MAKE_ACCESS_GROUP |
235                                  KDBUS_MAKE_ACCESS_WORLD,
236                 .argv = argv,
237                 .argc = ARRAY_SIZE(argv),
238         };
239
240         ret = kdbus_args_parse(&args, argp, &cmd);
241         if (ret < 0)
242                 return ERR_PTR(ret);
243         if (ret > 0)
244                 return NULL;
245
246         item_make_name = argv[1].item->str;
247
248         ep = kdbus_ep_new(bus, item_make_name, cmd->flags,
249                           current_euid(), current_egid(), true);
250         if (IS_ERR(ep)) {
251                 ret = PTR_ERR(ep);
252                 ep = NULL;
253                 goto exit;
254         }
255
256         if (!kdbus_node_activate(&ep->node)) {
257                 ret = -ESHUTDOWN;
258                 goto exit;
259         }
260
261 exit:
262         ret = kdbus_args_clear(&args, ret);
263         if (ret < 0) {
264                 if (ep) {
265                         kdbus_node_deactivate(&ep->node);
266                         kdbus_ep_unref(ep);
267                 }
268                 return ERR_PTR(ret);
269         }
270         return ep;
271 }
272
273 /**
274  * kdbus_cmd_ep_update() - handle KDBUS_CMD_ENDPOINT_UPDATE
275  * @ep:                 endpoint to operate on
276  * @argp:               command payload
277  *
278  * Return: >=0 on success, negative error code on failure.
279  */
280 int kdbus_cmd_ep_update(struct kdbus_ep *ep, void __user *argp)
281 {
282         struct kdbus_cmd *cmd;
283         int ret;
284
285         struct kdbus_arg argv[] = {
286                 { .type = KDBUS_ITEM_NEGOTIATE },
287                 { .type = KDBUS_ITEM_NAME, .multiple = true },
288                 { .type = KDBUS_ITEM_POLICY_ACCESS, .multiple = true },
289         };
290         struct kdbus_args args = {
291                 .allowed_flags = KDBUS_FLAG_NEGOTIATE,
292                 .argv = argv,
293                 .argc = ARRAY_SIZE(argv),
294         };
295
296         ret = kdbus_args_parse(&args, argp, &cmd);
297         if (ret != 0)
298                 return ret;
299
300         ret = kdbus_policy_set(&ep->policy_db, args.items, args.items_size,
301                                0, true, ep);
302         return kdbus_args_clear(&args, ret);
303 }