@@ -1,4 +1,4 @@
-/* $NetBSD: drm_ioctl.c,v 1.24 2022/10/15 15:19:28 riastradh Exp $ */
+/* $NetBSD: drm_ioctl.c,v 1.25 2024/04/21 03:02:51 riastradh Exp $ */
/*
* Created: Fri Jan 8 09:01:26 1999 by faith@valinux.com
@@ -31,7 +31,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: drm_ioctl.c,v 1.24 2022/10/15 15:19:28 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: drm_ioctl.c,v 1.25 2024/04/21 03:02:51 riastradh Exp $");
#include <linux/export.h>
#include <linux/nospec.h>
@@ -129,19 +129,35 @@
struct drm_file *file_priv)
{
struct drm_unique *u = data;
- struct drm_master *master = file_priv->master;
+ struct drm_master *master;
+ int ret;
- mutex_lock(&master->dev->master_mutex);
- if (u->unique_len >= master->unique_len) {
- if (copy_to_user(u->unique, master->unique, master->unique_len)) {
- mutex_unlock(&master->dev->master_mutex);
- return -EFAULT;
- }
+ mutex_lock(&dev->master_mutex);
+ master = dev->master;
+ if (master == NULL) {
+ ret = -ENXIO;
+ goto out;
}
+
+ /*
+ * Copy out only if the user allocated enough space. Either
+ * way, on success, report the actual size -- so the user can
+ * allocate enough space if they didn't before, or so they know
+ * exactly how much we copied out.
+ */
+ if (u->unique_len < master->unique_len) {
+ ret = 0;
+ } else {
+ ret = copy_to_user(u->unique, master->unique,
+ master->unique_len);
+ if (ret)
+ goto out;
+ }
u->unique_len = master->unique_len;
- mutex_unlock(&master->dev->master_mutex);
- return 0;
+out: mutex_unlock(&dev->master_mutex);
+
+ return ret;
}
static void
@@ -597,7 +613,7 @@
/* Ioctl table */
static const struct drm_ioctl_desc drm_ioctls[] = {
DRM_IOCTL_DEF(DRM_IOCTL_VERSION, drm_version, DRM_RENDER_ALLOW),
- DRM_IOCTL_DEF(DRM_IOCTL_GET_UNIQUE, drm_getunique, 0),
+ DRM_IOCTL_DEF(DRM_IOCTL_GET_UNIQUE, drm_getunique, DRM_RENDER_ALLOW),
DRM_IOCTL_DEF(DRM_IOCTL_GET_MAGIC, drm_getmagic, 0),
DRM_IOCTL_DEF(DRM_IOCTL_IRQ_BUSID, drm_irq_by_busid, DRM_MASTER|DRM_ROOT_ONLY),