1 /*
2  * Copyright (c) 2017, Mellanox Technologies inc.  All rights reserved.
3  *
4  * This software is available to you under a choice of one of two
5  * licenses.  You may choose to be licensed under the terms of the GNU
6  * General Public License (GPL) Version 2, available from the file
7  * COPYING in the main directory of this source tree, or the
8  * OpenIB.org BSD license below:
9  *
10  *     Redistribution and use in source and binary forms, with or
11  *     without modification, are permitted provided that the following
12  *     conditions are met:
13  *
14  *      - Redistributions of source code must retain the above
15  *        copyright notice, this list of conditions and the following
16  *        disclaimer.
17  *
18  *      - Redistributions in binary form must reproduce the above
19  *        copyright notice, this list of conditions and the following
20  *        disclaimer in the documentation and/or other materials
21  *        provided with the distribution.
22  *
23  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
27  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
28  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
29  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
30  * SOFTWARE.
31  */
32 
33 #include <rdma/rdma_user_ioctl.h>
34 #include <rdma/uverbs_ioctl.h>
35 #include "rdma_core.h"
36 #include "uverbs.h"
37 
38 static bool uverbs_is_attr_cleared(const struct ib_uverbs_attr *uattr,
39 				   u16 len)
40 {
41 	if (uattr->len > sizeof(((struct ib_uverbs_attr *)0)->data))
42 		return ib_is_buffer_cleared(u64_to_user_ptr(uattr->data) + len,
43 					    uattr->len - len);
44 
45 	return !memchr_inv((const void *)&uattr->data + len,
46 			   0, uattr->len - len);
47 }
48 
49 static int uverbs_process_attr(struct ib_device *ibdev,
50 			       struct ib_ucontext *ucontext,
51 			       const struct ib_uverbs_attr *uattr,
52 			       u16 attr_id,
53 			       const struct uverbs_attr_spec_hash *attr_spec_bucket,
54 			       struct uverbs_attr_bundle_hash *attr_bundle_h,
55 			       struct ib_uverbs_attr __user *uattr_ptr)
56 {
57 	const struct uverbs_attr_spec *spec;
58 	const struct uverbs_attr_spec *val_spec;
59 	struct uverbs_attr *e;
60 	const struct uverbs_object_spec *object;
61 	struct uverbs_obj_attr *o_attr;
62 	struct uverbs_attr *elements = attr_bundle_h->attrs;
63 
64 	if (attr_id >= attr_spec_bucket->num_attrs) {
65 		if (uattr->flags & UVERBS_ATTR_F_MANDATORY)
66 			return -EINVAL;
67 		else
68 			return 0;
69 	}
70 
71 	if (test_bit(attr_id, attr_bundle_h->valid_bitmap))
72 		return -EINVAL;
73 
74 	spec = &attr_spec_bucket->attrs[attr_id];
75 	val_spec = spec;
76 	e = &elements[attr_id];
77 	e->uattr = uattr_ptr;
78 
79 	switch (spec->type) {
80 	case UVERBS_ATTR_TYPE_ENUM_IN:
81 		if (uattr->attr_data.enum_data.elem_id >= spec->enum_def.num_elems)
82 			return -EOPNOTSUPP;
83 
84 		if (uattr->attr_data.enum_data.reserved)
85 			return -EINVAL;
86 
87 		val_spec = &spec->enum_def.ids[uattr->attr_data.enum_data.elem_id];
88 
89 		/* Currently we only support PTR_IN based enums */
90 		if (val_spec->type != UVERBS_ATTR_TYPE_PTR_IN)
91 			return -EOPNOTSUPP;
92 
93 		e->ptr_attr.enum_id = uattr->attr_data.enum_data.elem_id;
94 	/* fall through */
95 	case UVERBS_ATTR_TYPE_PTR_IN:
96 		/* Ensure that any data provided by userspace beyond the known
97 		 * struct is zero. Userspace that knows how to use some future
98 		 * longer struct will fail here if used with an old kernel and
99 		 * non-zero content, making ABI compat/discovery simpler.
100 		 */
101 		if (uattr->len > val_spec->ptr.len &&
102 		    val_spec->flags & UVERBS_ATTR_SPEC_F_MIN_SZ_OR_ZERO &&
103 		    !uverbs_is_attr_cleared(uattr, val_spec->ptr.len))
104 			return -EOPNOTSUPP;
105 
106 	/* fall through */
107 	case UVERBS_ATTR_TYPE_PTR_OUT:
108 		if (uattr->len < val_spec->ptr.min_len ||
109 		    (!(val_spec->flags & UVERBS_ATTR_SPEC_F_MIN_SZ_OR_ZERO) &&
110 		     uattr->len > val_spec->ptr.len))
111 			return -EINVAL;
112 
113 		if (spec->type != UVERBS_ATTR_TYPE_ENUM_IN &&
114 		    uattr->attr_data.reserved)
115 			return -EINVAL;
116 
117 		e->ptr_attr.data = uattr->data;
118 		e->ptr_attr.len = uattr->len;
119 		e->ptr_attr.flags = uattr->flags;
120 		break;
121 
122 	case UVERBS_ATTR_TYPE_IDR:
123 		if (uattr->data >> 32)
124 			return -EINVAL;
125 	/* fall through */
126 	case UVERBS_ATTR_TYPE_FD:
127 		if (uattr->attr_data.reserved)
128 			return -EINVAL;
129 
130 		if (uattr->len != 0 || !ucontext || uattr->data > INT_MAX)
131 			return -EINVAL;
132 
133 		o_attr = &e->obj_attr;
134 		object = uverbs_get_object(ibdev, spec->obj.obj_type);
135 		if (!object)
136 			return -EINVAL;
137 		o_attr->type = object->type_attrs;
138 
139 		o_attr->id = (int)uattr->data;
140 		o_attr->uobject = uverbs_get_uobject_from_context(
141 					o_attr->type,
142 					ucontext,
143 					spec->obj.access,
144 					o_attr->id);
145 
146 		if (IS_ERR(o_attr->uobject))
147 			return PTR_ERR(o_attr->uobject);
148 
149 		if (spec->obj.access == UVERBS_ACCESS_NEW) {
150 			u64 id = o_attr->uobject->id;
151 
152 			/* Copy the allocated id to the user-space */
153 			if (put_user(id, &e->uattr->data)) {
154 				uverbs_finalize_object(o_attr->uobject,
155 						       UVERBS_ACCESS_NEW,
156 						       false);
157 				return -EFAULT;
158 			}
159 		}
160 
161 		break;
162 	default:
163 		return -EOPNOTSUPP;
164 	}
165 
166 	set_bit(attr_id, attr_bundle_h->valid_bitmap);
167 	return 0;
168 }
169 
170 static int uverbs_uattrs_process(struct ib_device *ibdev,
171 				 struct ib_ucontext *ucontext,
172 				 const struct ib_uverbs_attr *uattrs,
173 				 size_t num_uattrs,
174 				 const struct uverbs_method_spec *method,
175 				 struct uverbs_attr_bundle *attr_bundle,
176 				 struct ib_uverbs_attr __user *uattr_ptr)
177 {
178 	size_t i;
179 	int ret = 0;
180 	int num_given_buckets = 0;
181 
182 	for (i = 0; i < num_uattrs; i++) {
183 		const struct ib_uverbs_attr *uattr = &uattrs[i];
184 		u16 attr_id = uattr->attr_id;
185 		struct uverbs_attr_spec_hash *attr_spec_bucket;
186 
187 		ret = uverbs_ns_idx(&attr_id, method->num_buckets);
188 		if (ret < 0) {
189 			if (uattr->flags & UVERBS_ATTR_F_MANDATORY) {
190 				uverbs_finalize_objects(attr_bundle,
191 							method->attr_buckets,
192 							num_given_buckets,
193 							false);
194 				return ret;
195 			}
196 			continue;
197 		}
198 
199 		/*
200 		 * ret is the found ns, so increase num_given_buckets if
201 		 * necessary.
202 		 */
203 		if (ret >= num_given_buckets)
204 			num_given_buckets = ret + 1;
205 
206 		attr_spec_bucket = method->attr_buckets[ret];
207 		ret = uverbs_process_attr(ibdev, ucontext, uattr, attr_id,
208 					  attr_spec_bucket, &attr_bundle->hash[ret],
209 					  uattr_ptr++);
210 		if (ret) {
211 			uverbs_finalize_objects(attr_bundle,
212 						method->attr_buckets,
213 						num_given_buckets,
214 						false);
215 			return ret;
216 		}
217 	}
218 
219 	return num_given_buckets;
220 }
221 
222 static int uverbs_validate_kernel_mandatory(const struct uverbs_method_spec *method_spec,
223 					    struct uverbs_attr_bundle *attr_bundle)
224 {
225 	unsigned int i;
226 
227 	for (i = 0; i < attr_bundle->num_buckets; i++) {
228 		struct uverbs_attr_spec_hash *attr_spec_bucket =
229 			method_spec->attr_buckets[i];
230 
231 		if (!bitmap_subset(attr_spec_bucket->mandatory_attrs_bitmask,
232 				   attr_bundle->hash[i].valid_bitmap,
233 				   attr_spec_bucket->num_attrs))
234 			return -EINVAL;
235 	}
236 
237 	for (; i < method_spec->num_buckets; i++) {
238 		struct uverbs_attr_spec_hash *attr_spec_bucket =
239 			method_spec->attr_buckets[i];
240 
241 		if (!bitmap_empty(attr_spec_bucket->mandatory_attrs_bitmask,
242 				  attr_spec_bucket->num_attrs))
243 			return -EINVAL;
244 	}
245 
246 	return 0;
247 }
248 
249 static int uverbs_handle_method(struct ib_uverbs_attr __user *uattr_ptr,
250 				const struct ib_uverbs_attr *uattrs,
251 				size_t num_uattrs,
252 				struct ib_device *ibdev,
253 				struct ib_uverbs_file *ufile,
254 				const struct uverbs_method_spec *method_spec,
255 				struct uverbs_attr_bundle *attr_bundle)
256 {
257 	int ret;
258 	int finalize_ret;
259 	int num_given_buckets;
260 
261 	num_given_buckets = uverbs_uattrs_process(ibdev, ufile->ucontext, uattrs,
262 						  num_uattrs, method_spec,
263 						  attr_bundle, uattr_ptr);
264 	if (num_given_buckets <= 0)
265 		return -EINVAL;
266 
267 	attr_bundle->num_buckets = num_given_buckets;
268 	ret = uverbs_validate_kernel_mandatory(method_spec, attr_bundle);
269 	if (ret)
270 		goto cleanup;
271 
272 	ret = method_spec->handler(ibdev, ufile, attr_bundle);
273 cleanup:
274 	finalize_ret = uverbs_finalize_objects(attr_bundle,
275 					       method_spec->attr_buckets,
276 					       attr_bundle->num_buckets,
277 					       !ret);
278 
279 	return ret ? ret : finalize_ret;
280 }
281 
282 #define UVERBS_OPTIMIZE_USING_STACK_SZ  256
283 static long ib_uverbs_cmd_verbs(struct ib_device *ib_dev,
284 				struct ib_uverbs_file *file,
285 				struct ib_uverbs_ioctl_hdr *hdr,
286 				void __user *buf)
287 {
288 	const struct uverbs_object_spec *object_spec;
289 	const struct uverbs_method_spec *method_spec;
290 	long err = 0;
291 	unsigned int i;
292 	struct {
293 		struct ib_uverbs_attr		*uattrs;
294 		struct uverbs_attr_bundle	*uverbs_attr_bundle;
295 	} *ctx = NULL;
296 	struct uverbs_attr *curr_attr;
297 	unsigned long *curr_bitmap;
298 	size_t ctx_size;
299 	uintptr_t data[UVERBS_OPTIMIZE_USING_STACK_SZ / sizeof(uintptr_t)];
300 
301 	if (hdr->driver_id != ib_dev->driver_id)
302 		return -EINVAL;
303 
304 	object_spec = uverbs_get_object(ib_dev, hdr->object_id);
305 	if (!object_spec)
306 		return -EPROTONOSUPPORT;
307 
308 	method_spec = uverbs_get_method(object_spec, hdr->method_id);
309 	if (!method_spec)
310 		return -EPROTONOSUPPORT;
311 
312 	if ((method_spec->flags & UVERBS_ACTION_FLAG_CREATE_ROOT) ^ !file->ucontext)
313 		return -EINVAL;
314 
315 	ctx_size = sizeof(*ctx) +
316 		   sizeof(struct uverbs_attr_bundle) +
317 		   sizeof(struct uverbs_attr_bundle_hash) * method_spec->num_buckets +
318 		   sizeof(*ctx->uattrs) * hdr->num_attrs +
319 		   sizeof(*ctx->uverbs_attr_bundle->hash[0].attrs) *
320 		   method_spec->num_child_attrs +
321 		   sizeof(*ctx->uverbs_attr_bundle->hash[0].valid_bitmap) *
322 			(method_spec->num_child_attrs / BITS_PER_LONG +
323 			 method_spec->num_buckets);
324 
325 	if (ctx_size <= UVERBS_OPTIMIZE_USING_STACK_SZ)
326 		ctx = (void *)data;
327 	if (!ctx)
328 		ctx = kmalloc(ctx_size, GFP_KERNEL);
329 	if (!ctx)
330 		return -ENOMEM;
331 
332 	ctx->uverbs_attr_bundle = (void *)ctx + sizeof(*ctx);
333 	ctx->uattrs = (void *)(ctx->uverbs_attr_bundle + 1) +
334 			      (sizeof(ctx->uverbs_attr_bundle->hash[0]) *
335 			       method_spec->num_buckets);
336 	curr_attr = (void *)(ctx->uattrs + hdr->num_attrs);
337 	curr_bitmap = (void *)(curr_attr + method_spec->num_child_attrs);
338 
339 	/*
340 	 * We just fill the pointers and num_attrs here. The data itself will be
341 	 * filled at a later stage (uverbs_process_attr)
342 	 */
343 	for (i = 0; i < method_spec->num_buckets; i++) {
344 		unsigned int curr_num_attrs = method_spec->attr_buckets[i]->num_attrs;
345 
346 		ctx->uverbs_attr_bundle->hash[i].attrs = curr_attr;
347 		curr_attr += curr_num_attrs;
348 		ctx->uverbs_attr_bundle->hash[i].num_attrs = curr_num_attrs;
349 		ctx->uverbs_attr_bundle->hash[i].valid_bitmap = curr_bitmap;
350 		bitmap_zero(curr_bitmap, curr_num_attrs);
351 		curr_bitmap += BITS_TO_LONGS(curr_num_attrs);
352 	}
353 
354 	err = copy_from_user(ctx->uattrs, buf,
355 			     sizeof(*ctx->uattrs) * hdr->num_attrs);
356 	if (err) {
357 		err = -EFAULT;
358 		goto out;
359 	}
360 
361 	err = uverbs_handle_method(buf, ctx->uattrs, hdr->num_attrs, ib_dev,
362 				   file, method_spec, ctx->uverbs_attr_bundle);
363 
364 	/*
365 	 * EPROTONOSUPPORT is ONLY to be returned if the ioctl framework can
366 	 * not invoke the method because the request is not supported.  No
367 	 * other cases should return this code.
368 	*/
369 	if (unlikely(err == -EPROTONOSUPPORT)) {
370 		WARN_ON_ONCE(err == -EPROTONOSUPPORT);
371 		err = -EINVAL;
372 	}
373 out:
374 	if (ctx != (void *)data)
375 		kfree(ctx);
376 	return err;
377 }
378 
379 #define IB_UVERBS_MAX_CMD_SZ 4096
380 
381 long ib_uverbs_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
382 {
383 	struct ib_uverbs_file *file = filp->private_data;
384 	struct ib_uverbs_ioctl_hdr __user *user_hdr =
385 		(struct ib_uverbs_ioctl_hdr __user *)arg;
386 	struct ib_uverbs_ioctl_hdr hdr;
387 	struct ib_device *ib_dev;
388 	int srcu_key;
389 	long err;
390 
391 	srcu_key = srcu_read_lock(&file->device->disassociate_srcu);
392 	ib_dev = srcu_dereference(file->device->ib_dev,
393 				  &file->device->disassociate_srcu);
394 	if (!ib_dev) {
395 		err = -EIO;
396 		goto out;
397 	}
398 
399 	if (cmd == RDMA_VERBS_IOCTL) {
400 		err = copy_from_user(&hdr, user_hdr, sizeof(hdr));
401 
402 		if (err || hdr.length > IB_UVERBS_MAX_CMD_SZ ||
403 		    hdr.length != sizeof(hdr) + hdr.num_attrs * sizeof(struct ib_uverbs_attr)) {
404 			err = -EINVAL;
405 			goto out;
406 		}
407 
408 		if (hdr.reserved1 || hdr.reserved2) {
409 			err = -EPROTONOSUPPORT;
410 			goto out;
411 		}
412 
413 		err = ib_uverbs_cmd_verbs(ib_dev, file, &hdr,
414 					  (__user void *)arg + sizeof(hdr));
415 	} else {
416 		err = -ENOIOCTLCMD;
417 	}
418 out:
419 	srcu_read_unlock(&file->device->disassociate_srcu, srcu_key);
420 
421 	return err;
422 }
423