| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: drm_ioctl.c,v 1.24 2022/10/15 15:19:28 riastradh Exp $ */ | | 1 | /* $NetBSD: drm_ioctl.c,v 1.25 2024/04/21 03:02:51 riastradh Exp $ */ |
2 | | | 2 | |
3 | /* | | 3 | /* |
4 | * Created: Fri Jan 8 09:01:26 1999 by faith@valinux.com | | 4 | * Created: Fri Jan 8 09:01:26 1999 by faith@valinux.com |
5 | * | | 5 | * |
6 | * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas. | | 6 | * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas. |
7 | * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. | | 7 | * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. |
8 | * All Rights Reserved. | | 8 | * All Rights Reserved. |
9 | * | | 9 | * |
10 | * Author Rickard E. (Rik) Faith <faith@valinux.com> | | 10 | * Author Rickard E. (Rik) Faith <faith@valinux.com> |
11 | * Author Gareth Hughes <gareth@valinux.com> | | 11 | * Author Gareth Hughes <gareth@valinux.com> |
12 | * | | 12 | * |
13 | * Permission is hereby granted, free of charge, to any person obtaining a | | 13 | * Permission is hereby granted, free of charge, to any person obtaining a |
14 | * copy of this software and associated documentation files (the "Software"), | | 14 | * copy of this software and associated documentation files (the "Software"), |
| @@ -21,27 +21,27 @@ | | | @@ -21,27 +21,27 @@ |
21 | * paragraph) shall be included in all copies or substantial portions of the | | 21 | * paragraph) shall be included in all copies or substantial portions of the |
22 | * Software. | | 22 | * Software. |
23 | * | | 23 | * |
24 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | | 24 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
25 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | | 25 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
26 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | | 26 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
27 | * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR | | 27 | * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR |
28 | * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | | 28 | * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, |
29 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | | 29 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR |
30 | * OTHER DEALINGS IN THE SOFTWARE. | | 30 | * OTHER DEALINGS IN THE SOFTWARE. |
31 | */ | | 31 | */ |
32 | | | 32 | |
33 | #include <sys/cdefs.h> | | 33 | #include <sys/cdefs.h> |
34 | __KERNEL_RCSID(0, "$NetBSD: drm_ioctl.c,v 1.24 2022/10/15 15:19:28 riastradh Exp $"); | | 34 | __KERNEL_RCSID(0, "$NetBSD: drm_ioctl.c,v 1.25 2024/04/21 03:02:51 riastradh Exp $"); |
35 | | | 35 | |
36 | #include <linux/export.h> | | 36 | #include <linux/export.h> |
37 | #include <linux/nospec.h> | | 37 | #include <linux/nospec.h> |
38 | #include <linux/pci.h> | | 38 | #include <linux/pci.h> |
39 | #include <linux/uaccess.h> | | 39 | #include <linux/uaccess.h> |
40 | #include <linux/capability.h> | | 40 | #include <linux/capability.h> |
41 | | | 41 | |
42 | #ifdef __NetBSD__ | | 42 | #ifdef __NetBSD__ |
43 | #include <sys/types.h> | | 43 | #include <sys/types.h> |
44 | #include <sys/file.h> | | 44 | #include <sys/file.h> |
45 | #endif | | 45 | #endif |
46 | | | 46 | |
47 | #include <drm/drm_agpsupport.h> | | 47 | #include <drm/drm_agpsupport.h> |
| @@ -119,39 +119,55 @@ __KERNEL_RCSID(0, "$NetBSD: drm_ioctl.c, | | | @@ -119,39 +119,55 @@ __KERNEL_RCSID(0, "$NetBSD: drm_ioctl.c, |
119 | * | | 119 | * |
120 | * \param inode device inode. | | 120 | * \param inode device inode. |
121 | * \param file_priv DRM file private. | | 121 | * \param file_priv DRM file private. |
122 | * \param cmd command. | | 122 | * \param cmd command. |
123 | * \param arg user argument, pointing to a drm_unique structure. | | 123 | * \param arg user argument, pointing to a drm_unique structure. |
124 | * \return zero on success or a negative number on failure. | | 124 | * \return zero on success or a negative number on failure. |
125 | * | | 125 | * |
126 | * Copies the bus id from drm_device::unique into user space. | | 126 | * Copies the bus id from drm_device::unique into user space. |
127 | */ | | 127 | */ |
128 | int drm_getunique(struct drm_device *dev, void *data, | | 128 | int drm_getunique(struct drm_device *dev, void *data, |
129 | struct drm_file *file_priv) | | 129 | struct drm_file *file_priv) |
130 | { | | 130 | { |
131 | struct drm_unique *u = data; | | 131 | struct drm_unique *u = data; |
132 | struct drm_master *master = file_priv->master; | | 132 | struct drm_master *master; |
| | | 133 | int ret; |
133 | | | 134 | |
134 | mutex_lock(&master->dev->master_mutex); | | 135 | mutex_lock(&dev->master_mutex); |
135 | if (u->unique_len >= master->unique_len) { | | 136 | master = dev->master; |
136 | if (copy_to_user(u->unique, master->unique, master->unique_len)) { | | 137 | if (master == NULL) { |
137 | mutex_unlock(&master->dev->master_mutex); | | 138 | ret = -ENXIO; |
138 | return -EFAULT; | | 139 | goto out; |
139 | } | | 140 | } |
| | | 141 | |
| | | 142 | /* |
| | | 143 | * Copy out only if the user allocated enough space. Either |
| | | 144 | * way, on success, report the actual size -- so the user can |
| | | 145 | * allocate enough space if they didn't before, or so they know |
| | | 146 | * exactly how much we copied out. |
| | | 147 | */ |
| | | 148 | if (u->unique_len < master->unique_len) { |
| | | 149 | ret = 0; |
| | | 150 | } else { |
| | | 151 | ret = copy_to_user(u->unique, master->unique, |
| | | 152 | master->unique_len); |
| | | 153 | if (ret) |
| | | 154 | goto out; |
140 | } | | 155 | } |
141 | u->unique_len = master->unique_len; | | 156 | u->unique_len = master->unique_len; |
142 | mutex_unlock(&master->dev->master_mutex); | | | |
143 | | | 157 | |
144 | return 0; | | 158 | out: mutex_unlock(&dev->master_mutex); |
| | | 159 | |
| | | 160 | return ret; |
145 | } | | 161 | } |
146 | | | 162 | |
147 | static void | | 163 | static void |
148 | drm_unset_busid(struct drm_device *dev, | | 164 | drm_unset_busid(struct drm_device *dev, |
149 | struct drm_master *master) | | 165 | struct drm_master *master) |
150 | { | | 166 | { |
151 | kfree(master->unique); | | 167 | kfree(master->unique); |
152 | master->unique = NULL; | | 168 | master->unique = NULL; |
153 | master->unique_len = 0; | | 169 | master->unique_len = 0; |
154 | } | | 170 | } |
155 | | | 171 | |
156 | static int drm_set_busid(struct drm_device *dev, struct drm_file *file_priv) | | 172 | static int drm_set_busid(struct drm_device *dev, struct drm_file *file_priv) |
157 | { | | 173 | { |
| @@ -587,27 +603,27 @@ EXPORT_SYMBOL(drm_ioctl_permit); | | | @@ -587,27 +603,27 @@ EXPORT_SYMBOL(drm_ioctl_permit); |
587 | .flags = _flags, \ | | 603 | .flags = _flags, \ |
588 | .name = #ioctl \ | | 604 | .name = #ioctl \ |
589 | } | | 605 | } |
590 | | | 606 | |
591 | #if IS_ENABLED(CONFIG_DRM_LEGACY) | | 607 | #if IS_ENABLED(CONFIG_DRM_LEGACY) |
592 | #define DRM_LEGACY_IOCTL_DEF(ioctl, _func, _flags) DRM_IOCTL_DEF(ioctl, _func, _flags) | | 608 | #define DRM_LEGACY_IOCTL_DEF(ioctl, _func, _flags) DRM_IOCTL_DEF(ioctl, _func, _flags) |
593 | #else | | 609 | #else |
594 | #define DRM_LEGACY_IOCTL_DEF(ioctl, _func, _flags) DRM_IOCTL_DEF(ioctl, drm_invalid_op, _flags) | | 610 | #define DRM_LEGACY_IOCTL_DEF(ioctl, _func, _flags) DRM_IOCTL_DEF(ioctl, drm_invalid_op, _flags) |
595 | #endif | | 611 | #endif |
596 | | | 612 | |
597 | /* Ioctl table */ | | 613 | /* Ioctl table */ |
598 | static const struct drm_ioctl_desc drm_ioctls[] = { | | 614 | static const struct drm_ioctl_desc drm_ioctls[] = { |
599 | DRM_IOCTL_DEF(DRM_IOCTL_VERSION, drm_version, DRM_RENDER_ALLOW), | | 615 | DRM_IOCTL_DEF(DRM_IOCTL_VERSION, drm_version, DRM_RENDER_ALLOW), |
600 | DRM_IOCTL_DEF(DRM_IOCTL_GET_UNIQUE, drm_getunique, 0), | | 616 | DRM_IOCTL_DEF(DRM_IOCTL_GET_UNIQUE, drm_getunique, DRM_RENDER_ALLOW), |
601 | DRM_IOCTL_DEF(DRM_IOCTL_GET_MAGIC, drm_getmagic, 0), | | 617 | DRM_IOCTL_DEF(DRM_IOCTL_GET_MAGIC, drm_getmagic, 0), |
602 | DRM_IOCTL_DEF(DRM_IOCTL_IRQ_BUSID, drm_irq_by_busid, DRM_MASTER|DRM_ROOT_ONLY), | | 618 | DRM_IOCTL_DEF(DRM_IOCTL_IRQ_BUSID, drm_irq_by_busid, DRM_MASTER|DRM_ROOT_ONLY), |
603 | | | 619 | |
604 | DRM_LEGACY_IOCTL_DEF(DRM_IOCTL_GET_MAP, drm_legacy_getmap_ioctl, 0), | | 620 | DRM_LEGACY_IOCTL_DEF(DRM_IOCTL_GET_MAP, drm_legacy_getmap_ioctl, 0), |
605 | | | 621 | |
606 | DRM_IOCTL_DEF(DRM_IOCTL_GET_CLIENT, drm_getclient, 0), | | 622 | DRM_IOCTL_DEF(DRM_IOCTL_GET_CLIENT, drm_getclient, 0), |
607 | DRM_IOCTL_DEF(DRM_IOCTL_GET_STATS, drm_getstats, 0), | | 623 | DRM_IOCTL_DEF(DRM_IOCTL_GET_STATS, drm_getstats, 0), |
608 | DRM_IOCTL_DEF(DRM_IOCTL_GET_CAP, drm_getcap, DRM_RENDER_ALLOW), | | 624 | DRM_IOCTL_DEF(DRM_IOCTL_GET_CAP, drm_getcap, DRM_RENDER_ALLOW), |
609 | DRM_IOCTL_DEF(DRM_IOCTL_SET_CLIENT_CAP, drm_setclientcap, 0), | | 625 | DRM_IOCTL_DEF(DRM_IOCTL_SET_CLIENT_CAP, drm_setclientcap, 0), |
610 | DRM_IOCTL_DEF(DRM_IOCTL_SET_VERSION, drm_setversion, DRM_MASTER), | | 626 | DRM_IOCTL_DEF(DRM_IOCTL_SET_VERSION, drm_setversion, DRM_MASTER), |
611 | | | 627 | |
612 | DRM_IOCTL_DEF(DRM_IOCTL_SET_UNIQUE, drm_invalid_op, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), | | 628 | DRM_IOCTL_DEF(DRM_IOCTL_SET_UNIQUE, drm_invalid_op, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), |
613 | DRM_IOCTL_DEF(DRM_IOCTL_BLOCK, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), | | 629 | DRM_IOCTL_DEF(DRM_IOCTL_BLOCK, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), |