linux/drivers/gpu/drm/i915/i915_user_extensions.c
<<
>>
Prefs
   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
  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, ext))
  55                        return -EFAULT;
  56
  57                ext = u64_to_user_ptr(next);
  58        }
  59
  60        return 0;
  61}
  62