Branch data Line data Source code
1 : : /* 2 : : * SPDX-License-Identifier: MIT 3 : : * 4 : : * Copyright © 2018 Intel Corporation 5 : : */ 6 : : 7 : : #include <linux/nospec.h> 8 : : #include <linux/sched/signal.h> 9 : : #include <linux/uaccess.h> 10 : : 11 : : #include <uapi/drm/i915_drm.h> 12 : : 13 : : #include "i915_user_extensions.h" 14 : : #include "i915_utils.h" 15 : : 16 : 0 : int i915_user_extensions(struct i915_user_extension __user *ext, 17 : : const i915_user_extension_fn *tbl, 18 : : unsigned int count, 19 : : void *data) 20 : : { 21 : 0 : unsigned int stackdepth = 512; 22 : : 23 [ # # ]: 0 : while (ext) { 24 : 0 : int i, err; 25 : 0 : u32 name; 26 : 0 : u64 next; 27 : : 28 [ # # ]: 0 : if (!stackdepth--) /* recursion vs useful flexibility */ 29 : : return -E2BIG; 30 : : 31 [ # # # # ]: 0 : err = check_user_mbz(&ext->flags); 32 : : if (err) 33 : 0 : return err; 34 : : 35 [ # # ]: 0 : for (i = 0; i < ARRAY_SIZE(ext->rsvd); i++) { 36 [ # # # # ]: 0 : err = check_user_mbz(&ext->rsvd[i]); 37 : 0 : if (err) 38 : 0 : return err; 39 : : } 40 : : 41 [ # # ]: 0 : if (get_user(name, &ext->name)) 42 : : return -EFAULT; 43 : : 44 : 0 : err = -EINVAL; 45 [ # # ]: 0 : if (name < count) { 46 : 0 : name = array_index_nospec(name, count); 47 [ # # ]: 0 : if (tbl[name]) 48 : 0 : err = tbl[name](ext, data); 49 : : } 50 [ # # ]: 0 : if (err) 51 : 0 : return err; 52 : : 53 [ # # ]: 0 : if (get_user(next, &ext->next_extension) || 54 : : overflows_type(next, ext)) 55 : : return -EFAULT; 56 : : 57 : 0 : ext = u64_to_user_ptr(next); 58 : : } 59 : : 60 : : return 0; 61 : : }