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