Merge tag 'io_uring-5.11-2021-01-16' of git://git.kernel.dk/linux-block
[linux/fpc-iii.git] / drivers / gpu / drm / i915 / i915_user_extensions.c
blobc822d0aafd2dc7d9d480e208a386c41458b4d5c9
1 /*
2 * SPDX-License-Identifier: MIT
4 * Copyright © 2018 Intel Corporation
5 */
7 #include <linux/nospec.h>
8 #include <linux/sched/signal.h>
9 #include <linux/uaccess.h>
11 #include <uapi/drm/i915_drm.h>
13 #include "i915_user_extensions.h"
14 #include "i915_utils.h"
16 int i915_user_extensions(struct i915_user_extension __user *ext,
17 const i915_user_extension_fn *tbl,
18 unsigned int count,
19 void *data)
21 unsigned int stackdepth = 512;
23 while (ext) {
24 int i, err;
25 u32 name;
26 u64 next;
28 if (!stackdepth--) /* recursion vs useful flexibility */
29 return -E2BIG;
31 err = check_user_mbz(&ext->flags);
32 if (err)
33 return err;
35 for (i = 0; i < ARRAY_SIZE(ext->rsvd); i++) {
36 err = check_user_mbz(&ext->rsvd[i]);
37 if (err)
38 return err;
41 if (get_user(name, &ext->name))
42 return -EFAULT;
44 err = -EINVAL;
45 if (name < count) {
46 name = array_index_nospec(name, count);
47 if (tbl[name])
48 err = tbl[name](ext, data);
50 if (err)
51 return err;
53 if (get_user(next, &ext->next_extension) ||
54 overflows_type(next, ext))
55 return -EFAULT;
57 ext = u64_to_user_ptr(next);
60 return 0;