Back to home page

OSCL-LXR

 
 

    


0001 /*
0002  * SPDX-License-Identifier: MIT
0003  *
0004  * Copyright © 2018 Intel Corporation
0005  */
0006 
0007 #include <linux/nospec.h>
0008 #include <linux/sched/signal.h>
0009 #include <linux/uaccess.h>
0010 
0011 #include <uapi/drm/i915_drm.h>
0012 
0013 #include "i915_user_extensions.h"
0014 #include "i915_utils.h"
0015 
0016 int i915_user_extensions(struct i915_user_extension __user *ext,
0017              const i915_user_extension_fn *tbl,
0018              unsigned int count,
0019              void *data)
0020 {
0021     unsigned int stackdepth = 512;
0022 
0023     while (ext) {
0024         int i, err;
0025         u32 name;
0026         u64 next;
0027 
0028         if (!stackdepth--) /* recursion vs useful flexibility */
0029             return -E2BIG;
0030 
0031         err = check_user_mbz(&ext->flags);
0032         if (err)
0033             return err;
0034 
0035         for (i = 0; i < ARRAY_SIZE(ext->rsvd); i++) {
0036             err = check_user_mbz(&ext->rsvd[i]);
0037             if (err)
0038                 return err;
0039         }
0040 
0041         if (get_user(name, &ext->name))
0042             return -EFAULT;
0043 
0044         err = -EINVAL;
0045         if (name < count) {
0046             name = array_index_nospec(name, count);
0047             if (tbl[name])
0048                 err = tbl[name](ext, data);
0049         }
0050         if (err)
0051             return err;
0052 
0053         if (get_user(next, &ext->next_extension) ||
0054             overflows_type(next, ext))
0055             return -EFAULT;
0056 
0057         ext = u64_to_user_ptr(next);
0058     }
0059 
0060     return 0;
0061 }