drivers/gpu/drm/drm_file.c | 1 + drivers/gpu/drm/drm_property.c | 8 ++++++++ include/drm/drm_file.h | 6 ++++++ 3 files changed, 15 insertions(+)
DRM_IOCTL_MODE_CREATEPROPBLOB allows userspace to create property blobs
whose lifetime is scoped to a drm_file.
Currently, a single drm_file may create an unbounded number of blobs.
Repeated ioctl calls can trigger unbounded kernel memory allocation and
lead to OOM, resulting in a denial-of-service.
Introduce a per-drm_file limit on the number of user-created property
blobs. The limit is enforced at the point where a blob becomes associated
with a drm_file, matching the existing ownership and lifetime model.
This bounds per-file allocations while the total number of DRM file
descriptors remains constrained by existing kernel limits.
Signed-off-by: Xiao Kan <814091656@qq.com>
Signed-off-by: Xiao Kan <xiao.kan@samsung.com>
---
drivers/gpu/drm/drm_file.c | 1 +
drivers/gpu/drm/drm_property.c | 8 ++++++++
include/drm/drm_file.h | 6 ++++++
3 files changed, 15 insertions(+)
diff --git a/drivers/gpu/drm/drm_file.c b/drivers/gpu/drm/drm_file.c
index eebd1a05e..873bf6248 100755
--- a/drivers/gpu/drm/drm_file.c
+++ b/drivers/gpu/drm/drm_file.c
@@ -152,6 +152,7 @@ struct drm_file *drm_file_alloc(struct drm_minor *minor)
INIT_LIST_HEAD(&file->fbs);
mutex_init(&file->fbs_lock);
INIT_LIST_HEAD(&file->blobs);
+ file->blob_count = 0;
INIT_LIST_HEAD(&file->pending_event_list);
INIT_LIST_HEAD(&file->event_list);
init_waitqueue_head(&file->event_wait);
diff --git a/drivers/gpu/drm/drm_property.c b/drivers/gpu/drm/drm_property.c
index 596272149..00eac336a 100755
--- a/drivers/gpu/drm/drm_property.c
+++ b/drivers/gpu/drm/drm_property.c
@@ -618,6 +618,7 @@ void drm_property_destroy_user_blobs(struct drm_device *dev,
*/
list_for_each_entry_safe(blob, bt, &file_priv->blobs, head_file) {
list_del_init(&blob->head_file);
+ file_priv->blob_count--;
drm_property_blob_put(blob);
}
}
@@ -864,8 +865,14 @@ int drm_mode_createblob_ioctl(struct drm_device *dev,
* as only the same file_priv can remove the blob; at this point, it is
* not associated with any file_priv. */
mutex_lock(&dev->mode_config.blob_lock);
+ if (file_priv->blob_count >= DRM_FILE_MAX_PROPBLOBS) {
+ mutex_unlock(&dev->mode_config.blob_lock);
+ drm_property_blob_put(blob);
+ return -ENOSPC;
+ }
out_resp->blob_id = blob->base.id;
list_add_tail(&blob->head_file, &file_priv->blobs);
+ file_priv->blob_count++;
mutex_unlock(&dev->mode_config.blob_lock);
return 0;
@@ -907,6 +914,7 @@ int drm_mode_destroyblob_ioctl(struct drm_device *dev,
/* We must drop head_file here, because we may not be the last
* reference on the blob. */
list_del_init(&blob->head_file);
+ file_priv->blob_count--;
mutex_unlock(&dev->mode_config.blob_lock);
/* One reference from lookup, and one from the filp. */
diff --git a/include/drm/drm_file.h b/include/drm/drm_file.h
index 115763799..211c4284f 100755
--- a/include/drm/drm_file.h
+++ b/include/drm/drm_file.h
@@ -38,6 +38,9 @@
#include <drm/drm_prime.h>
+/* Maximum number of user-created property blobs per drm_file */
+#define DRM_FILE_MAX_PROPBLOBS 256
+
struct dma_fence;
struct drm_file;
struct drm_device;
@@ -349,6 +352,9 @@ struct drm_file {
*/
struct list_head blobs;
+ /* Number of property blobs owned by this file */
+ unsigned int blob_count;
+
/** @event_wait: Waitqueue for new events added to @event_list. */
wait_queue_head_t event_wait;
--
2.51.0
Hi, On Sat, Jan 03, 2026 at 10:25:29AM -0500, Xiao Kan wrote: > DRM_IOCTL_MODE_CREATEPROPBLOB allows userspace to create property blobs > whose lifetime is scoped to a drm_file. > > Currently, a single drm_file may create an unbounded number of blobs. > Repeated ioctl calls can trigger unbounded kernel memory allocation and > lead to OOM, resulting in a denial-of-service. > > Introduce a per-drm_file limit on the number of user-created property > blobs. The limit is enforced at the point where a blob becomes associated > with a drm_file, matching the existing ownership and lifetime model. > This bounds per-file allocations while the total number of DRM file > descriptors remains constrained by existing kernel limits. > > Signed-off-by: Xiao Kan <814091656@qq.com> > Signed-off-by: Xiao Kan <xiao.kan@samsung.com> Wouldn't it make more sense to account the allocation in memcg by passing GFP_ACCOUNT to the kvzalloc call in drm_property_create_blob? Maxime
DRM_IOCTL_MODE_CREATEPROPBLOB allows userspace to allocate arbitrary-sized
property blobs backed by kernel memory.
Currently, the blob data allocation is not accounted to the allocating
process's memory cgroup, allowing unprivileged users to trigger unbounded
kernel memory consumption and potentially cause system-wide OOM.
Mark the property blob data allocation with GFP_ACCOUNT so that the memory
is properly charged to the caller's memcg. This ensures existing cgroup
memory limits apply and prevents uncontrolled kernel memory growth without
introducing additional policy or per-file limits.
Changes since v1:
- Drop the per-drm_file blob count limit.
- Account blob data allocations to memcg via GFP_KERNEL_ACCOUNT instead.
Signed-off-by: Xiao Kan <814091656@qq.com>
Signed-off-by: Xiao Kan <xiao.kan@samsung.com>
---
drivers/gpu/drm/drm_property.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/drm_property.c b/drivers/gpu/drm/drm_property.c
index 596272149..a34758712 100755
--- a/drivers/gpu/drm/drm_property.c
+++ b/drivers/gpu/drm/drm_property.c
@@ -562,7 +562,7 @@ drm_property_create_blob(struct drm_device *dev, size_t length,
if (!length || length > INT_MAX - sizeof(struct drm_property_blob))
return ERR_PTR(-EINVAL);
- blob = kvzalloc(sizeof(struct drm_property_blob)+length, GFP_KERNEL);
+ blob = kvzalloc(sizeof(struct drm_property_blob)+length, GFP_KERNEL_ACCOUNT);
if (!blob)
return ERR_PTR(-ENOMEM);
--
2.51.0
Hi, On Mon, Jan 05, 2026 at 11:14:13AM -0500, Xiao Kan wrote: > DRM_IOCTL_MODE_CREATEPROPBLOB allows userspace to allocate arbitrary-sized > property blobs backed by kernel memory. > > Currently, the blob data allocation is not accounted to the allocating > process's memory cgroup, allowing unprivileged users to trigger unbounded > kernel memory consumption and potentially cause system-wide OOM. > > Mark the property blob data allocation with GFP_ACCOUNT so that the memory > is properly charged to the caller's memcg. This ensures existing cgroup > memory limits apply and prevents uncontrolled kernel memory growth without > introducing additional policy or per-file limits. > > Changes since v1: > - Drop the per-drm_file blob count limit. > - Account blob data allocations to memcg via GFP_KERNEL_ACCOUNT instead. > > Signed-off-by: Xiao Kan <814091656@qq.com> > Signed-off-by: Xiao Kan <xiao.kan@samsung.com> It looks like you sent two different patches labelled v2? Sending a new version in itself is not a problem (and even encourage), but you should always bump the version number. Maxime
DRM_IOCTL_MODE_CREATEPROPBLOB allows userspace to allocate arbitrary-sized
property blobs backed by kernel memory.
Currently, the blob data allocation is not accounted to the allocating
process's memory cgroup, allowing unprivileged users to trigger unbounded
kernel memory consumption and potentially cause system-wide OOM.
Mark the property blob data allocation with GFP_KERNEL_ACCOUNT so that the memory
is properly charged to the caller's memcg. This ensures existing cgroup
memory limits apply and prevents uncontrolled kernel memory growth without
introducing additional policy or per-file limits.
Signed-off-by: Xiao Kan <814091656@qq.com>
Signed-off-by: Xiao Kan <xiao.kan@samsung.com>
---
drivers/gpu/drm/drm_property.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/drm_property.c b/drivers/gpu/drm/drm_property.c
index 596272149..3c88b5fbd 100755
--- a/drivers/gpu/drm/drm_property.c
+++ b/drivers/gpu/drm/drm_property.c
@@ -562,7 +562,7 @@ drm_property_create_blob(struct drm_device *dev, size_t length,
if (!length || length > INT_MAX - sizeof(struct drm_property_blob))
return ERR_PTR(-EINVAL);
- blob = kvzalloc(sizeof(struct drm_property_blob)+length, GFP_KERNEL);
+ blob = kvzalloc(sizeof(struct drm_property_blob) + length, GFP_KERNEL_ACCOUNT);
if (!blob)
return ERR_PTR(-ENOMEM);
--
2.51.0
On Wed, 14 Jan 2026 08:22:26 -0500, Xiao Kan wrote: > DRM_IOCTL_MODE_CREATEPROPBLOB allows userspace to allocate arbitrary-sized > property blobs backed by kernel memory. > > Currently, the blob data allocation is not accounted to the allocating > process's memory cgroup, allowing unprivileged users to trigger unbounded > kernel memory consumption and potentially cause system-wide OOM. > > [...] Applied to misc/kernel.git (drm-misc-next). Thanks! Maxime
DRM_IOCTL_MODE_CREATEPROPBLOB allows userspace to allocate arbitrary-sized
property blobs backed by kernel memory.
Currently, the blob data allocation is not accounted to the allocating
process's memory cgroup, allowing unprivileged users to trigger unbounded
kernel memory consumption and potentially cause system-wide OOM.
Mark the property blob data allocation with GFP_ACCOUNT so that the memory
is properly charged to the caller's memcg. This ensures existing cgroup
memory limits apply and prevents uncontrolled kernel memory growth without
introducing additional policy or per-file limits.
Changes since v1:
- Drop the per-drm_file blob count limit.
- Account blob data allocations to memcg via GFP_ACCOUNT instead.
Signed-off-by: Xiao Kan <814091656@qq.com>
Signed-off-by: Xiao Kan <xiao.kan@samsung.com>
---
drivers/gpu/drm/drm_property.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/drm_property.c b/drivers/gpu/drm/drm_property.c
index 596272149..c5c91b88f 100755
--- a/drivers/gpu/drm/drm_property.c
+++ b/drivers/gpu/drm/drm_property.c
@@ -562,7 +562,7 @@ drm_property_create_blob(struct drm_device *dev, size_t length,
if (!length || length > INT_MAX - sizeof(struct drm_property_blob))
return ERR_PTR(-EINVAL);
- blob = kvzalloc(sizeof(struct drm_property_blob)+length, GFP_KERNEL);
+ blob = kvzalloc(sizeof(struct drm_property_blob)+length, GFP_KERNEL | GFP_ACCOUNT);
if (!blob)
return ERR_PTR(-ENOMEM);
--
2.51.0
© 2016 - 2026 Red Hat, Inc.