From: Arnd Bergmann Date: Tue, 22 Jul 2025 11:58:18 +0000 (+0200) Subject: Revert "drm/nouveau: check ioctl command codes better" X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=270b329f7ec4e4e8dca6735bd1fe286a8e39b82d;p=thirdparty%2Fkernel%2Flinux.git Revert "drm/nouveau: check ioctl command codes better" My previous patch ended up causing a regression for the DRM_IOCTL_NOUVEAU_NVIF ioctl. The intention of my patch was to only pass ioctl commands that have the correct dir/type/nr bits into the nouveau_abi16_ioctl() function. This turned out to be too strict, as userspace does use at least write-only and write-read direction settings. Checking for both of these still did not fix the issue, so the best we can do for the 6.16 release is to revert back to what we've had since linux-3.16. This version is still fragile, but at least it is known to work with existing userspace. Fixing this properly requires a better understanding of what commands are being passed from userspace in practice, and how that relies on the undocumented (miss)behavior in nouveau_drm_ioctl(). Fixes: e5478166dffb ("drm/nouveau: check ioctl command codes better") Reported-by: Satadru Pramanik Closes: https://lore.kernel.org/lkml/CAFrh3J85tsZRpOHQtKgNHUVnn=EG=QKBnZTRtWS8eWSc1K1xkA@mail.gmail.com/ Reported-by: Chris Bainbridge Closes: https://lore.kernel.org/lkml/aH9n_QGMFx2ZbKlw@debian.local/ Signed-off-by: Arnd Bergmann Link: https://lore.kernel.org/r/20250722115830.2587297-1-arnd@kernel.org [ Add Closes: tags, fix minor typo in commit message. - Danilo ] Signed-off-by: Danilo Krummrich --- diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.c b/drivers/gpu/drm/nouveau/nouveau_drm.c index 7bb64fcdd497..1527b801f013 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drm.c +++ b/drivers/gpu/drm/nouveau/nouveau_drm.c @@ -1284,9 +1284,6 @@ nouveau_ioctls[] = { DRM_IOCTL_DEF_DRV(NOUVEAU_EXEC, nouveau_exec_ioctl_exec, DRM_RENDER_ALLOW), }; -#define DRM_IOCTL_NOUVEAU_NVIF _IOC(_IOC_READ | _IOC_WRITE, DRM_IOCTL_BASE, \ - DRM_COMMAND_BASE + DRM_NOUVEAU_NVIF, 0) - long nouveau_drm_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { @@ -1300,10 +1297,14 @@ nouveau_drm_ioctl(struct file *file, unsigned int cmd, unsigned long arg) return ret; } - if ((cmd & ~IOCSIZE_MASK) == DRM_IOCTL_NOUVEAU_NVIF) + switch (_IOC_NR(cmd) - DRM_COMMAND_BASE) { + case DRM_NOUVEAU_NVIF: ret = nouveau_abi16_ioctl(filp, (void __user *)arg, _IOC_SIZE(cmd)); - else + break; + default: ret = drm_ioctl(file, cmd, arg); + break; + } pm_runtime_mark_last_busy(dev->dev); pm_runtime_put_autosuspend(dev->dev);