All of lore.kernel.org
 help / color / mirror / Atom feed
From: linux@arm.linux.org.uk (Russell King - ARM Linux)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH RFC 2/8] DRM: Armada: Add Armada DRM driver
Date: Thu, 13 Jun 2013 00:00:57 +0100	[thread overview]
Message-ID: <20130612230057.GY18614@n2100.arm.linux.org.uk> (raw)
In-Reply-To: <20130612194021.GX18614@n2100.arm.linux.org.uk>

And here's another one - look carefully at this path:

                buf = dev->driver->gem_prime_export(dev, obj, flags);
                if (IS_ERR(buf)) {
                        /* normally the created dma-buf takes ownership of the ref,
                         * but if that fails then drop the ref
                         */
                        drm_gem_object_unreference_unlocked(obj);
                        mutex_unlock(&file_priv->prime.lock);
                        return PTR_ERR(buf);
                }
                obj->export_dma_buf = buf;
                *prime_fd = dma_buf_fd(buf, flags);
        }
        /* if we've exported this buffer the cheat and add it to the import list
         * so we get the correct handle back
         */
        ret = drm_prime_add_imported_buf_handle(&file_priv->prime,
                        obj->export_dma_buf, handle);
        if (ret) {
                drm_gem_object_unreference_unlocked(obj);
                mutex_unlock(&file_priv->prime.lock);
                return ret;
        }

So in the event of drm_prime_add_imported_buf_handle() returning an error,
we return that error to our caller (which will eventually be userspace)
saying that we failed.

However, we've already setup the export and obtained an fd for it, which
we resultingly now leak in that situation.

Now, second problem here - consider what happens if you ask for the same
object to be exported a second (or more) times.  Note that
obj->export_dma_buf will now be set, so we take a different path through
this code:

        if (obj->export_dma_buf) {
                get_dma_buf(obj->export_dma_buf);
                *prime_fd = dma_buf_fd(obj->export_dma_buf, flags);
                drm_gem_object_unreference_unlocked(obj);
	} else {
	}
        /* if we've exported this buffer the cheat and add it to the import list
         * so we get the correct handle back
         */
        ret = drm_prime_add_imported_buf_handle(&file_priv->prime,
                        obj->export_dma_buf, handle);
        if (ret) {
                drm_gem_object_unreference_unlocked(obj);
                mutex_unlock(&file_priv->prime.lock);
                return ret;
        }

Now, if I in a loop in userspace doing this:

	do {
		drmPrimeHandleToFD(..., &fd);
		close(fd);
	} while (1);

How long do you think it might take to exhaust the kmalloc() inside
drm_prime_add_imported_buf_handle() ?

It's not even trivially fixable, because drm_gem_dmabuf_release() doesn't
call drm_prime_remove_imported_buf_handle() because it has no knowledge
of the drm_prime_file_private structure to search for these things...

WARNING: multiple messages have this Message-ID (diff)
From: Russell King - ARM Linux <linux@arm.linux.org.uk>
To: Rob Clark <robdclark@gmail.com>
Cc: dri-devel@lists.freedesktop.org, Dave Airlie <airlied@gmail.com>,
	Jason Cooper <jason@lakedaemon.net>,
	linux-arm-kernel@lists.infradead.org,
	Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
Subject: Re: [PATCH RFC 2/8] DRM: Armada: Add Armada DRM driver
Date: Thu, 13 Jun 2013 00:00:57 +0100	[thread overview]
Message-ID: <20130612230057.GY18614@n2100.arm.linux.org.uk> (raw)
In-Reply-To: <20130612194021.GX18614@n2100.arm.linux.org.uk>

And here's another one - look carefully at this path:

                buf = dev->driver->gem_prime_export(dev, obj, flags);
                if (IS_ERR(buf)) {
                        /* normally the created dma-buf takes ownership of the ref,
                         * but if that fails then drop the ref
                         */
                        drm_gem_object_unreference_unlocked(obj);
                        mutex_unlock(&file_priv->prime.lock);
                        return PTR_ERR(buf);
                }
                obj->export_dma_buf = buf;
                *prime_fd = dma_buf_fd(buf, flags);
        }
        /* if we've exported this buffer the cheat and add it to the import list
         * so we get the correct handle back
         */
        ret = drm_prime_add_imported_buf_handle(&file_priv->prime,
                        obj->export_dma_buf, handle);
        if (ret) {
                drm_gem_object_unreference_unlocked(obj);
                mutex_unlock(&file_priv->prime.lock);
                return ret;
        }

So in the event of drm_prime_add_imported_buf_handle() returning an error,
we return that error to our caller (which will eventually be userspace)
saying that we failed.

However, we've already setup the export and obtained an fd for it, which
we resultingly now leak in that situation.

Now, second problem here - consider what happens if you ask for the same
object to be exported a second (or more) times.  Note that
obj->export_dma_buf will now be set, so we take a different path through
this code:

        if (obj->export_dma_buf) {
                get_dma_buf(obj->export_dma_buf);
                *prime_fd = dma_buf_fd(obj->export_dma_buf, flags);
                drm_gem_object_unreference_unlocked(obj);
	} else {
	}
        /* if we've exported this buffer the cheat and add it to the import list
         * so we get the correct handle back
         */
        ret = drm_prime_add_imported_buf_handle(&file_priv->prime,
                        obj->export_dma_buf, handle);
        if (ret) {
                drm_gem_object_unreference_unlocked(obj);
                mutex_unlock(&file_priv->prime.lock);
                return ret;
        }

Now, if I in a loop in userspace doing this:

	do {
		drmPrimeHandleToFD(..., &fd);
		close(fd);
	} while (1);

How long do you think it might take to exhaust the kmalloc() inside
drm_prime_add_imported_buf_handle() ?

It's not even trivially fixable, because drm_gem_dmabuf_release() doesn't
call drm_prime_remove_imported_buf_handle() because it has no knowledge
of the drm_prime_file_private structure to search for these things...

  reply	other threads:[~2013-06-12 23:00 UTC|newest]

Thread overview: 120+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-06-09 19:06 [RFC v2 0/8] rmk's Dove DRM/TDA19988 Cubox driver Russell King - ARM Linux
2013-06-09 19:06 ` Russell King - ARM Linux
2013-06-09 19:29 ` [PATCH RFC 2/8] DRM: Armada: Add Armada DRM driver Russell King
2013-06-09 19:32   ` Russell King
2013-06-10 11:10   ` Sebastian Hesselbarth
2013-06-10 11:10     ` Sebastian Hesselbarth
2013-06-10 21:48     ` Russell King - ARM Linux
2013-06-10 21:48       ` Russell King - ARM Linux
2013-06-10 21:56       ` Sebastian Hesselbarth
2013-06-10 21:56         ` Sebastian Hesselbarth
2013-06-10 15:57   ` Rob Clark
2013-06-10 15:57     ` Rob Clark
2013-06-10 17:06     ` Russell King - ARM Linux
2013-06-10 17:06       ` Russell King - ARM Linux
2013-06-10 19:59       ` Rob Clark
2013-06-10 19:59         ` Rob Clark
2013-06-10 20:08         ` Russell King - ARM Linux
2013-06-10 20:08           ` Russell King - ARM Linux
2013-06-10 21:01           ` Rob Clark
2013-06-10 21:01             ` Rob Clark
2013-06-10 21:15             ` Russell King - ARM Linux
2013-06-10 21:15               ` Russell King - ARM Linux
2013-06-10 22:49               ` Rob Clark
2013-06-10 22:49                 ` Rob Clark
2013-06-10 22:56                 ` Russell King - ARM Linux
2013-06-10 22:56                   ` Russell King - ARM Linux
2013-06-10 23:17                   ` Rob Clark
2013-06-10 23:17                     ` Rob Clark
2013-06-10 23:24                     ` Dave Airlie
2013-06-10 23:24                       ` Dave Airlie
2013-06-10 23:35                       ` Rob Clark
2013-06-10 23:35                         ` Rob Clark
2013-06-10 23:36                       ` Russell King - ARM Linux
2013-06-10 23:36                         ` Russell King - ARM Linux
2013-06-10 23:48                         ` Dave Airlie
2013-06-10 23:48                           ` Dave Airlie
2013-06-10 23:56                           ` Russell King - ARM Linux
2013-06-10 23:56                             ` Russell King - ARM Linux
2013-06-12 13:48                           ` Russell King - ARM Linux
2013-06-12 13:48                             ` Russell King - ARM Linux
2013-06-12 13:56                             ` Rob Clark
2013-06-12 13:56                               ` Rob Clark
2013-06-12 16:49                               ` Russell King - ARM Linux
2013-06-12 16:49                                 ` Russell King - ARM Linux
2013-06-12 17:05                                 ` Russell King - ARM Linux
2013-06-12 17:05                                   ` Russell King - ARM Linux
2013-06-12 19:40                                   ` Russell King - ARM Linux
2013-06-12 19:40                                     ` Russell King - ARM Linux
2013-06-12 23:00                                     ` Russell King - ARM Linux [this message]
2013-06-12 23:00                                       ` Russell King - ARM Linux
2013-06-13  0:17                                       ` Rob Clark
2013-06-13  0:17                                         ` Rob Clark
2013-06-13 11:19                                       ` Russell King - ARM Linux
2013-06-13 11:19                                         ` Russell King - ARM Linux
2013-06-13 11:50                                         ` Russell King - ARM Linux
2013-06-13 11:50                                           ` Russell King - ARM Linux
2013-06-13 13:03                                           ` Russell King - ARM Linux
2013-06-13 13:03                                             ` Russell King - ARM Linux
2013-06-14 14:23                                             ` Daniel Vetter
2013-06-14 14:23                                               ` Daniel Vetter
2013-06-14 14:42                                               ` Russell King - ARM Linux
2013-06-14 14:42                                                 ` Russell King - ARM Linux
2013-06-14 19:50                                                 ` Daniel Vetter
2013-06-14 19:50                                                   ` Daniel Vetter
2013-06-14 22:15                                                   ` Russell King - ARM Linux
2013-06-14 22:15                                                     ` Russell King - ARM Linux
2013-06-14 22:36                                                     ` Daniel Vetter
2013-06-14 22:36                                                       ` Daniel Vetter
2013-06-14 13:53                                           ` Daniel Vetter
2013-06-14 13:53                                             ` Daniel Vetter
2013-06-14 14:27                                             ` Russell King - ARM Linux
2013-06-14 14:27                                               ` Russell King - ARM Linux
2013-06-13 12:52                                         ` Rob Clark
2013-06-13 12:52                                           ` Rob Clark
2013-06-13 12:58                                           ` Daniel Vetter
2013-06-13 12:58                                             ` Daniel Vetter
2013-06-12 20:04                                   ` Rob Clark
2013-06-12 20:04                                     ` Rob Clark
2013-06-10 23:38                     ` Russell King - ARM Linux
2013-06-10 23:38                       ` Russell King - ARM Linux
2013-06-10 23:49                       ` Rob Clark
2013-06-10 23:49                         ` Rob Clark
2013-06-10 22:01         ` Daniel Vetter
2013-06-10 22:01           ` Daniel Vetter
2013-06-10 22:32           ` Russell King - ARM Linux
2013-06-10 22:32             ` Russell King - ARM Linux
2013-06-10 23:12             ` Rob Clark
2013-06-10 23:12               ` Rob Clark
2013-06-11  7:33             ` Daniel Vetter
2013-06-11  7:33               ` Daniel Vetter
2013-06-11  8:08           ` Ville Syrjälä
2013-06-11  8:08             ` Ville Syrjälä
2013-06-10 21:38     ` Russell King - ARM Linux
2013-06-10 21:38       ` Russell King - ARM Linux
2013-06-09 19:30 ` [PATCH RFC 3/8] drm/i2c: nxp-tda998x: fix EDID reading on TDA19988 devices Russell King
2013-06-09 19:30   ` Russell King
2013-06-09 19:31 ` [PATCH RFC 4/8] drm/i2c: nxp-tda998x: ensure VIP output mux is properly set Russell King
2013-06-09 19:31   ` Russell King
2013-06-09 19:32 ` [PATCH RFC 5/8] drm/i2c: nxp-tda998x: fix npix/nline programming Russell King
2013-06-09 19:32   ` Russell King
2013-06-09 20:02   ` Sebastian Hesselbarth
2013-06-09 20:02     ` Sebastian Hesselbarth
2013-06-09 19:34 ` [PATCH RFC 6/8] drm/i2c: nxp-tda998x: prepare for video input configuration Russell King
2013-06-09 19:34   ` Russell King
2013-06-09 19:35 ` [PATCH RFC 7/8] drm/i2c: nxp-tda998x: add video and audio " Russell King
2013-06-09 19:35   ` Russell King
2013-06-09 19:36 ` [PATCH RFC 8/8] DRM: Armada: add support for drm tda19988 driver Russell King
2013-06-09 19:36   ` Russell King
2013-06-09 19:43 ` [RFC v2 0/8] rmk's Dove DRM/TDA19988 Cubox driver Russell King - ARM Linux
2013-06-09 19:43   ` Russell King - ARM Linux
2013-06-10 22:47 ` [RFC v3 0/4] " Russell King - ARM Linux
2013-06-10 22:47   ` Russell King - ARM Linux
2013-06-10 22:48 ` [PATCH RFC v3 1/4] DRM: Armada: Add Armada DRM driver Russell King
2013-06-10 22:51   ` Russell King
2013-06-10 22:49 ` [PATCH RFC v3 2/4] DRM: Armada: Add support for hardware cursors Russell King
2013-06-10 22:49   ` Russell King
2013-06-10 22:50 ` [PATCH RFC v3 3/4] DRM: Armada: convert Armada hardware cursor support to RGB+transparency Russell King
2013-06-10 22:50   ` Russell King
2013-06-10 22:51 ` [PATCH RFC v3 4/4] DRM: Armada: convert hardware cursor support to 64x32 or 32x64 ARGB Russell King
2013-06-10 22:51   ` Russell King

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=20130612230057.GY18614@n2100.arm.linux.org.uk \
    --to=linux@arm.linux.org.uk \
    --cc=linux-arm-kernel@lists.infradead.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.