From mboxrd@z Thu Jan 1 00:00:00 1970 From: Claude Code Review Bot To: dri-devel-reviews@example.com Subject: Claude review: drm/atomic: Return user readable error in atomic_ioctl Date: Wed, 11 Feb 2026 16:31:47 +1000 Message-ID: In-Reply-To: <20260210-atomic-v9-5-525c88fd2402@intel.com> References: <20260210-atomic-v9-0-525c88fd2402@intel.com> <20260210-atomic-v9-5-525c88fd2402@intel.com> Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Mailer: Claude Code Patch Reviewer Patch Review **Issues:** ```c + if (!arg->reserved) + drm_dbg_atomic(dev, + "memory not allocated for drm_atomic error reporting\n"); + else + /* Update the error code if any error to allow user handling it */ + error_code_ptr = (struct drm_mode_atomic_err_code __user *) + (unsigned long)arg->reserved; ``` - **No Validation**: Userspace pointer is blindly trusted. No `access_ok()` check. - **Comment After else**: Comment should explain what happens, not repeat what code does - **Double Cast**: The `(unsigned long)` cast is unnecessary noise ```c + memset(&state->error_code, 0, sizeof(*error_code_ptr)); ``` - **Size Mismatch**: Using `sizeof(*error_code_ptr)` (userspace size) to clear kernel's `state->error_code`. Should be `sizeof(state->error_code)`. These happen to be the same type, but the pattern is wrong. ```c if (!file_priv->atomic) { + drm_mode_atomic_add_error_msg(&state->error_code, + DRM_MODE_ATOMIC_INVALID_API_USAGE, + "drm atomic capability not enabled"); drm_dbg_atomic(dev, "commit failed: atomic cap not enabled\n"); ``` - **Duplication**: Error message is duplicated between `add_error_msg` and `drm_dbg_atomic`. The `drm_dbg_atomic` call inside `add_error_msg` already logs. ```c if (arg->flags & ~DRM_MODE_ATOMIC_FLAGS) { - drm_dbg_atomic(dev, "commit failed: invalid flag\n"); - ret = -EINVAL; - goto out; - } - - if (arg->reserved) { - drm_dbg_atomic(dev, "commit failed: reserved field set\n"); ``` - **Logic Error**: The removal of `arg->reserved` check means old code that validated reserved==0 is gone. This is an ABI break. ```c +out: + /* Update the error code if any error to allow user handling it */ + if (ret < 0 && arg->reserved) { + if (copy_to_user(error_code_ptr, &state->error_code, + sizeof(state->error_code))) + return -EFAULT; + } ``` - **Cleanup Leak**: Returning -EFAULT directly bypasses remaining cleanup code (modeset locks, state free). Should set `ret = -EFAULT;` and fall through. - **Error Path**: If `copy_to_user` fails, we're already in an error path and now leaking more resources. --- Generated by Claude Code Patch Reviewer