Re: [PATCH] drm: Prevent modeset helpers to access an uninitialized drm_mode_config

From: Thomas Zimmermann
Date: Mon Jul 25 2022 - 03:12:48 EST


Hi Javier

Am 24.07.22 um 20:41 schrieb Javier Martinez Canillas:
Hello Thomas,

Thanks for your feedback.

On 7/24/22 20:24, Thomas Zimmermann wrote:
Hi Javier

Am 24.07.22 um 14:37 schrieb Javier Martinez Canillas:
DRM drivers initialize the mode configuration with drmm_mode_config_init()
and that function (among other things) initializes mutexes that are later
used by modeset helpers.

But the helpers should only attempt to grab those locks if the mode config
was properly initialized. Otherwise it can lead to kernel oops. An example
is when a DRM driver using the component framework does not initialize the
drm_mode_config, because its .bind callback was not being executed due one
of its expected sub-devices' driver failing to probe.

Some drivers check the struct drm_driver.registered field as an indication
on whether their .shutdown callback should call helpers to tearn down the
mode configuration or not, but most drivers just assume that it is always
safe to call helpers such as drm_atomic_helper_shutdown() during shutdown.

Let make the DRM core more robust and prevent this to happen, by marking a
struct drm_mode_config as initialized during drmm_mode_config_init(). that
way helpers can check for it and not attempt to grab uninitialized mutexes.

I disagree. This patch looks like cargo-cult programming and entirely
arbitrary. The solution here is to fix drivers. The actual test to
perform is to instrument the mutex implementation to detect
uninitialized mutexes.


While I do agree that drivers should be fixed, IMO we should try to make it
hard for the kernel to crash. We already have checks in other DRM helpers to
avoid accessing uninitialized data, so I don't see why we couldn't do the
same here.

Code should stand on its own merits, instead of doing something because something else does it. The latter is what is referred to as cargo-cult programming.

Doing sanity checks on values is not a problem, but putting flag variables throughout the code to question other code's state is. That's not 'The Way of the C.' There's also the problem that a good part of struct drm_mode_config's initialization is open-coded in drivers. So the meaning of is_initialized is somewhat fuzzy.


I wrote this patch after fixing a bug in the drm/msm driver [0]. By looking
at how other drivers handled this case, I'm pretty sure that they have the
same problem. A warning is much better than a kernel crash during shutdown.

[0]: https://patchwork.kernel.org/project/dri-devel/patch/20220724111327.1195693-1-javierm@xxxxxxxxxx/

I see. I wasn't aware that missing mode_config_init() is a problem. From the linked URL, I cannot really understand how it's related. msm appears to be calling drm_mode_config_init(), right? The idiomatic solution would be to convert msm to managed code. But that's an entirely different patchset, of course. (I only took a brief look at the link TBH.)

Here's a suggestion on how to construct the mode-config code in order to make it hard to misuse: Driver currently open-code the initialization of many fields in drm_mode_config. Expand the arguments of drm_mode_config_init() to take the pointer to the drm_mode_config_funcs. These functions are essential to do anything, so it's a good candidate for an argument. Drivers are easily converted the the new interface AFAICT. After the conversion, add a test to drm_mode_config_reset() that tests for the funcs to be set. drm_mode_config_reset() is also essential during initialization or the driver will fail immediately on the first modeset operation. That gives a test for an initialized mode_config without adding extra fields.

As a bit of a sidenote: we should consider making drm_mode_config_reset() and the reset callbacks return errors. The reset functions allocate memory for states and if this fails, we have no way of reporting the failure.

Best regards
Thomas



Best regards
Thomas



--
Thomas Zimmermann
Graphics Driver Developer
SUSE Software Solutions Germany GmbH
Maxfeldstr. 5, 90409 Nürnberg, Germany
(HRB 36809, AG Nürnberg)
Geschäftsführer: Ivo Totev

Attachment: OpenPGP_signature
Description: OpenPGP digital signature