62 lines · c
1/*2 * SPDX-License-Identifier: MIT3 *4 * Copyright © 2018 Intel Corporation5 */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 16int 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 unsigned int stackdepth = 512;22 23 while (ext) {24 int i, err;25 u32 name;26 u64 next;27 28 if (!stackdepth--) /* recursion vs useful flexibility */29 return -E2BIG;30 31 err = check_user_mbz(&ext->flags);32 if (err)33 return err;34 35 for (i = 0; i < ARRAY_SIZE(ext->rsvd); i++) {36 err = check_user_mbz(&ext->rsvd[i]);37 if (err)38 return err;39 }40 41 if (get_user(name, &ext->name))42 return -EFAULT;43 44 err = -EINVAL;45 if (name < count) {46 name = array_index_nospec(name, count);47 if (tbl[name])48 err = tbl[name](ext, data);49 }50 if (err)51 return err;52 53 if (get_user(next, &ext->next_extension) ||54 overflows_type(next, uintptr_t))55 return -EFAULT;56 57 ext = u64_to_user_ptr(next);58 }59 60 return 0;61}62