From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id E448ECD4F35 for ; Tue, 12 May 2026 09:12:00 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 3073410E9E3; Tue, 12 May 2026 09:12:00 +0000 (UTC) Authentication-Results: gabe.freedesktop.org; dkim=pass (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.b="Qypah4gp"; dkim-atps=neutral Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by gabe.freedesktop.org (Postfix) with ESMTPS id CB67410E9D9 for ; Tue, 12 May 2026 09:11:58 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1778577118; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=8s97gg0KoIjyQjky3n/0eDgAUHfrfiLBh9jEOqvVQQM=; b=Qypah4gpjvgfcoH7L+MPBkb3JsOSIM75BiE0/UBu9Zi7dVfThn7wtuTBMqUJZ/6JG2jq/7 N0tmRWCH8S4Ffl9jRbYtK2zC0Q6ZBDAf6YoR2q945z4iS31eL+xpPkDfWA12jf7cpMOXWP +HcqB32ZAIA5DKyHwCB4wwDW9x2wsRQ= Received: from mx-prod-mc-06.mail-002.prod.us-west-2.aws.redhat.com (ec2-35-165-154-97.us-west-2.compute.amazonaws.com [35.165.154.97]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-401-WtDMzp2iMUq5SL-zKZ9ffw-1; Tue, 12 May 2026 05:11:56 -0400 X-MC-Unique: WtDMzp2iMUq5SL-zKZ9ffw-1 X-Mimecast-MFC-AGG-ID: WtDMzp2iMUq5SL-zKZ9ffw_1778577113 Received: from mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.4]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-06.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 9C1D51800283; Tue, 12 May 2026 09:11:52 +0000 (UTC) Received: from [192.168.1.153] (headnet01.pony-001.prod.iad2.dc.redhat.com [10.2.32.101]) by mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id DD95330001BB; Tue, 12 May 2026 09:11:44 +0000 (UTC) From: Albert Esteve Date: Tue, 12 May 2026 11:10:45 +0200 Subject: [PATCH RFC 3/5] security: dma-heap: Add dma_heap_alloc LSM hook MIME-Version: 1.0 Message-Id: <20260512-v2_20230123_tjmercier_google_com-v1-3-6326701c3691@redhat.com> References: <20260512-v2_20230123_tjmercier_google_com-v1-0-6326701c3691@redhat.com> In-Reply-To: <20260512-v2_20230123_tjmercier_google_com-v1-0-6326701c3691@redhat.com> To: Tejun Heo , Johannes Weiner , =?utf-8?q?Michal_Koutn=C3=BD?= , Jonathan Corbet , Shuah Khan , Sumit Semwal , =?utf-8?q?Christian_K=C3=B6nig?= , Michal Hocko , Roman Gushchin , Shakeel Butt , Muchun Song , Andrew Morton , Benjamin Gaignard , Brian Starkey , John Stultz , "T.J. Mercier" , Christian Brauner , Paul Moore , James Morris , "Serge E. Hallyn" , Stephen Smalley , Ondrej Mosnacek , Shuah Khan Cc: cgroups@vger.kernel.org, linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, linux-media@vger.kernel.org, dri-devel@lists.freedesktop.org, linaro-mm-sig@lists.linaro.org, linux-mm@kvack.org, linux-security-module@vger.kernel.org, selinux@vger.kernel.org, linux-kselftest@vger.kernel.org, Albert Esteve , mripard@kernel.org, echanude@redhat.com X-Developer-Signature: v=1; a=ed25519-sha256; t=1778577077; l=5081; i=aesteve@redhat.com; s=20260303; h=from:subject:message-id; bh=dcNJV4lWmLSoMBN8niB4WIZmayqAaNgAMtglbZ4TQOM=; b=fpOoquy0dwzfC7CEdNg5OVIQDBr8hGp0UelCRqsMuNme9Fe3xsZMLOjlm3w9G+6wEyl+SvFVo UZ2m/SG8t4ICmEzyhKMvwnHt+6gBKEk4vLcSbpEz3Ovn68s3VAyPQmI X-Developer-Key: i=aesteve@redhat.com; a=ed25519; pk=YSFz6sOHd2L45+Fr8DIvHTi6lSIjhLZ5T+rkxspJt1s= X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.4 X-Mimecast-MFC-PROC-ID: QvLIm9hJITII_bpQLxqLaTAe1PdNkmVfLj7EKG_SbK4_1778577113 X-Mimecast-Originator: redhat.com Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" DMA_HEAP_IOCTL_ALLOC accepts a charge_pid_fd field that, when set, causes the allocation to be charged to an arbitrary process's cgroup rather than the caller's. Without an access-control point, any process that holds a handle to a dma-heap device node can charge unlimited memory to any other process's cgroup, potentially exhausting that cgroup's limit and triggering OOM kills independent of the victim's own activity or privileges. Add security_dma_heap_alloc(), called in dma_heap_ioctl_allocate() when charge_pid_fd refers to another process. The hook receives the credentials of the allocating process (from) and the credentials of the process whose cgroup will be charged (to), giving security modules a controlled enforcement point for cross-cgroup dma-buf attribution policy. When CONFIG_SECURITY is not set the hook compiles to an inline returning 0, adding no overhead to the fast path. Signed-off-by: Albert Esteve --- drivers/dma-buf/dma-heap.c | 12 +++++++++++- include/linux/lsm_hook_defs.h | 1 + include/linux/security.h | 7 +++++++ security/security.c | 16 ++++++++++++++++ 4 files changed, 35 insertions(+), 1 deletion(-) diff --git a/drivers/dma-buf/dma-heap.c b/drivers/dma-buf/dma-heap.c index ff6e259afcdc0..e8ffb1031955e 100644 --- a/drivers/dma-buf/dma-heap.c +++ b/drivers/dma-buf/dma-heap.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include @@ -122,12 +123,13 @@ static int dma_heap_open(struct inode *inode, struct file *file) static long dma_heap_ioctl_allocate(struct file *file, void *data) { + const struct cred *tcred; struct dma_heap_allocation_data *heap_allocation = data; struct dma_heap *heap = file->private_data; struct mem_cgroup *memcg = NULL; struct task_struct *task; unsigned int pidfd_flags; - int fd; + int fd, ret; if (heap_allocation->fd) return -EINVAL; @@ -143,6 +145,14 @@ static long dma_heap_ioctl_allocate(struct file *file, void *data) if (IS_ERR(task)) return PTR_ERR(task); + tcred = get_task_cred(task); + ret = security_dma_heap_alloc(current_cred(), tcred); + put_cred(tcred); + if (ret) { + put_task_struct(task); + return ret; + } + memcg = get_mem_cgroup_from_mm(task->mm); put_task_struct(task); } diff --git a/include/linux/lsm_hook_defs.h b/include/linux/lsm_hook_defs.h index 2b8dfb35caed3..6a91656f97e1e 100644 --- a/include/linux/lsm_hook_defs.h +++ b/include/linux/lsm_hook_defs.h @@ -43,6 +43,7 @@ LSM_HOOK(int, 0, capset, struct cred *new, const struct cred *old, const kernel_cap_t *permitted) LSM_HOOK(int, 0, capable, const struct cred *cred, struct user_namespace *ns, int cap, unsigned int opts) +LSM_HOOK(int, 0, dma_heap_alloc, const struct cred *from, const struct cred *to) LSM_HOOK(int, 0, quotactl, int cmds, int type, int id, const struct super_block *sb) LSM_HOOK(int, 0, quota_on, struct dentry *dentry) LSM_HOOK(int, 0, syslog, int type) diff --git a/include/linux/security.h b/include/linux/security.h index 41d7367cf4036..f1dad1eabe754 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -350,6 +350,7 @@ int security_capable(const struct cred *cred, struct user_namespace *ns, int cap, unsigned int opts); +int security_dma_heap_alloc(const struct cred *from, const struct cred *to); int security_quotactl(int cmds, int type, int id, const struct super_block *sb); int security_quota_on(struct dentry *dentry); int security_syslog(int type); @@ -701,6 +702,12 @@ static inline int security_capable(const struct cred *cred, return cap_capable(cred, ns, cap, opts); } +static inline int security_dma_heap_alloc(const struct cred *from, + const struct cred *to) +{ + return 0; +} + static inline int security_quotactl(int cmds, int type, int id, const struct super_block *sb) { diff --git a/security/security.c b/security/security.c index 4e999f0236516..4adacef73c507 100644 --- a/security/security.c +++ b/security/security.c @@ -660,6 +660,22 @@ int security_capable(const struct cred *cred, return call_int_hook(capable, cred, ns, cap, opts); } +/** + * security_dma_heap_alloc() - Check if cross-cgroup dma-heap charging is allowed + * @from: credentials of the allocating process + * @to: credentials of the process to charge + * + * Check whether the process with credentials @from is allowed to allocate + * dma-heap memory and charge it to the cgroup of the process with credentials + * @to. + * + * Return: Returns 0 if permission is granted. + */ +int security_dma_heap_alloc(const struct cred *from, const struct cred *to) +{ + return call_int_hook(dma_heap_alloc, from, to); +} + /** * security_quotactl() - Check if a quotactl() syscall is allowed for this fs * @cmds: commands -- 2.53.0