From: Jani Nikula <jani.nikula@linux.intel.com>
To: Daniel Vetter <daniel@ffwll.ch>, Dmitry Malkin <DMalkin@ptsecurity.com>
Cc: "dri-devel@lists.freedesktop.org" <dri-devel@lists.freedesktop.org>
Subject: Re: [DRM] drm_get_connector_name internal static string buffer causes a race
Date: Tue, 25 Mar 2014 12:44:02 +0200 [thread overview]
Message-ID: <87k3biimml.fsf@intel.com> (raw)
In-Reply-To: <20140324203132.GK26878@phenom.ffwll.local>
On Mon, 24 Mar 2014, Daniel Vetter <daniel@ffwll.ch> wrote:
> On Mon, Mar 24, 2014 at 12:06:21PM +0000, Dmitry Malkin wrote:
>>
>> Hello guys,
>>
>> I've been playing with reloading intel gfx driver (i915) in a cycle,
>> for a while, and at some point I've found a non-deterministic kernel
>> crash with a highly-variable iteration dependency -- 2 to 200 driver
>> reload iterations.
>>
>> The apparent race is over the shared internal string buffer in
>> drm_get_connector_name(). It is mostly harmless, due to its results
>> being mostly used for log output, but in at least one case --
>> drm_sysfs_connector_add() -- this leads to a more critical error.
>>
>> Race scenario:
>>
>> - drm_sysfs_connector_add()
>> - drm_get_connector_name()
>> vs.
>> - anything that generates log messages involving DRM connectors
>> - drm_get_connector_name()
>>
>> (and many other from drm_crtc.c) shares with caller const char* to
>> internal static char buffer. If something call it from other thread,
>> while main thread strore and use returned pointer it may overwrite
>> connector name.
>>
>> Here are we go: registering HDMI connecter (drm_sysfs_connector_add
>> store and use pointer from drm_get_connector_name) and the same time
>> got VGA connector name down through the stack. (the second thread is
>> upowerd who watch continuously sysfs)
>
> Yeah, in my recent kerneldoc series I've noticed this too and added FIXME
> comments. There's a lot more than just those you've pointed out. The
> problem is that fixing these will be an awful lot of work since you need
> to add proper cleanup code (calling kfree()) to all the required places.
>
> So a full subsystem wide code audit for every single use-site of these.
It would be much easier and much much less error prone to add a name
field (either a fixed size or kmalloced buffer) in drm_connector and
drm_encoder structs, and initialize them in connector/encoder
init. AFAICT the name does not change during the objects' lifetime. None
of the use-sites would need to be changed.
The question is whether (number of connectors + number of encoders) * 32
bytes is too high a price to pay for the implementation simplicity. I
think not.
Another alternative to returning kmalloced strings is:
diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index 16ca28ed5ee8..85c8ed191daa 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -277,11 +277,10 @@ EXPORT_SYMBOL(drm_get_encoder_name);
*
* FIXME: This isn't really multithreading safe.
*/
-const char *drm_get_connector_name(const struct drm_connector *connector)
+const char *drm_get_connector_name(char *buf, size_t bufsize,
+ const struct drm_connector *connector)
{
- static char buf[32];
-
- snprintf(buf, 32, "%s-%d",
+ snprintf(buf, bufsize, "%s-%d",
drm_connector_enum_list[connector->connector_type].name,
connector->connector_type_id);
return buf;
So the callers may use the kind of buffers they want. Something like
this may be needed for drm_get_format_name() anyway.
BR,
Jani.
--
Jani Nikula, Intel Open Source Technology Center
prev parent reply other threads:[~2014-03-25 10:43 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-03-24 12:06 [DRM] drm_get_connector_name internal static string buffer causes a race Dmitry Malkin
2014-03-24 20:31 ` Daniel Vetter
2014-03-25 8:08 ` Dmitry Malkin
2014-03-25 10:43 ` Daniel Vetter
2014-03-25 11:23 ` Dmitry Malkin
2014-03-25 12:36 ` Daniel Vetter
2014-03-25 10:44 ` Jani Nikula [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=87k3biimml.fsf@intel.com \
--to=jani.nikula@linux.intel.com \
--cc=DMalkin@ptsecurity.com \
--cc=daniel@ffwll.ch \
--cc=dri-devel@lists.freedesktop.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.