From nobody Mon Sep 15 23:28:27 2025 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 vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id BFFFEC05027 for ; Mon, 23 Jan 2023 19:18:07 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232242AbjAWTSG (ORCPT ); Mon, 23 Jan 2023 14:18:06 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:54802 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231674AbjAWTR7 (ORCPT ); Mon, 23 Jan 2023 14:17:59 -0500 Received: from mail-yb1-xb49.google.com (mail-yb1-xb49.google.com [IPv6:2607:f8b0:4864:20::b49]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 5F737CA11 for ; Mon, 23 Jan 2023 11:17:57 -0800 (PST) Received: by mail-yb1-xb49.google.com with SMTP id h136-20020a25d08e000000b007e1b1a30d5dso14016604ybg.15 for ; Mon, 23 Jan 2023 11:17:57 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=29eNHuXkN4Biw7YjDro7DKxD9MLgh2JPpCUKKyMlqpA=; b=Subdt7mbpSJ3q++6bJrXZjJZZw2B5aXVhcYIOjpWp1e7w65W6r5oAUZpnmuhuuxtGC m6yHwVIfAM74kNHnxjivy2kMGAg6vCfv+3hhWBYw2BJN0Dja1Y7NQKOgWr6COa+8oUkk rUnUidJgv1sRL2Bt6YdHCPqVzpfizdrAy9YnM1stYfRMcfzP4DXyiUe0ObHRm1rO0ZdX Z1ZA/fI74arWwHwvDOYrrcmDZGCsMH3Nq+OQolvzt4CNc9tJFsaB0vn3Yw+H2aqetp8n bmppFH7vBRP4aW++HEHSq4uD8ir3GpzrY/G/loULfk/4Fe0e7jWIDY4IGgw0L9zKW6Fz 9YCg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=29eNHuXkN4Biw7YjDro7DKxD9MLgh2JPpCUKKyMlqpA=; b=jJS8yYr4diGvuhLTBqYrpqFvGt9Egrzn+FgPuyEO/xWqbPks9dAJEnuilBDjdZyH8D fIXeqtdFe1dAVW+ddtWMPfaPmqCGDW7J3e0aJaymMLkd3Ky5ceECJqeDOalsDX+fgQf9 v2tFRNfQPBg+bJcOG1LpYJKZMtAVHtgs+ga4x4SKvkXH0kcA08LkjZT12LyVoZLSVneM hleDSkeT2HhAm+bZxP1unLLegDm2l587SJY7v/WxlD+J+PdJ2IbH0AafKgiH1fkFLOGg vWPMDUSaiAkABDFZI70cTcZ8HKnM1r5GCPT+6sYltloJFpE0ZRjQBXC2rk+v6xR2pn/6 o+rw== X-Gm-Message-State: AFqh2kogE23N81IjUvllOPXI9BrqyEo4S1KCRf2DQ+SSHGWhdNVAgBgx 8tLqPPIQu7upn1lE8EQXL+sIOLr3ZLqvttU= X-Google-Smtp-Source: AMrXdXuIEmBCRRQ29mCX2Lz8F60RAV61DpR49m4PqdkPLl3Fou0sh8htd5KZF+eNK2HXmLDFr4FD/qKGK/2gVtE= X-Received: from tj.c.googlers.com ([fda3:e722:ac3:cc00:20:ed76:c0a8:53a]) (user=tjmercier job=sendgmr) by 2002:a81:5553:0:b0:4d1:959d:fa49 with SMTP id j80-20020a815553000000b004d1959dfa49mr3602848ywb.33.1674501476646; Mon, 23 Jan 2023 11:17:56 -0800 (PST) Date: Mon, 23 Jan 2023 19:17:23 +0000 In-Reply-To: <20230123191728.2928839-1-tjmercier@google.com> Mime-Version: 1.0 References: <20230123191728.2928839-1-tjmercier@google.com> X-Mailer: git-send-email 2.39.0.246.g2a6d74b583-goog Message-ID: <20230123191728.2928839-2-tjmercier@google.com> Subject: [PATCH v2 1/4] memcg: Track exported dma-buffers From: "T.J. Mercier" To: tjmercier@google.com, Tejun Heo , Zefan Li , Johannes Weiner , Jonathan Corbet , Sumit Semwal , "=?UTF-8?q?Christian=20K=C3=B6nig?=" , Michal Hocko , Roman Gushchin , Shakeel Butt , Muchun Song , Andrew Morton Cc: daniel.vetter@ffwll.ch, android-mm@google.com, jstultz@google.com, jeffv@google.com, cmllamas@google.com, linux-security-module@vger.kernel.org, selinux@vger.kernel.org, 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 Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" When a buffer is exported to userspace, use memcg to attribute the buffer to the allocating cgroup until all buffer references are released. Unlike the dmabuf sysfs stats implementation, this memcg accounting avoids contention over the kernfs_rwsem incurred when creating or removing nodes. Signed-off-by: T.J. Mercier --- Documentation/admin-guide/cgroup-v2.rst | 4 +++ drivers/dma-buf/dma-buf.c | 13 +++++++++ include/linux/dma-buf.h | 3 ++ include/linux/memcontrol.h | 38 +++++++++++++++++++++++++ mm/memcontrol.c | 19 +++++++++++++ 5 files changed, 77 insertions(+) diff --git a/Documentation/admin-guide/cgroup-v2.rst b/Documentation/admin-= guide/cgroup-v2.rst index c8ae7c897f14..538ae22bc514 100644 --- a/Documentation/admin-guide/cgroup-v2.rst +++ b/Documentation/admin-guide/cgroup-v2.rst @@ -1455,6 +1455,10 @@ PAGE_SIZE multiple when read back. Amount of memory used for storing in-kernel data structures. =20 + dmabuf (npn) + Amount of memory used for exported DMA buffers allocated by the cgroup. + Stays with the allocating cgroup regardless of how the buffer is shared. + workingset_refault_anon Number of refaults of previously evicted anonymous pages. =20 diff --git a/drivers/dma-buf/dma-buf.c b/drivers/dma-buf/dma-buf.c index e6528767efc7..a6a8cb5cb32d 100644 --- a/drivers/dma-buf/dma-buf.c +++ b/drivers/dma-buf/dma-buf.c @@ -75,6 +75,9 @@ static void dma_buf_release(struct dentry *dentry) */ BUG_ON(dmabuf->cb_in.active || dmabuf->cb_out.active); =20 + mem_cgroup_uncharge_dmabuf(dmabuf->memcg, PAGE_ALIGN(dmabuf->size) / PAGE= _SIZE); + mem_cgroup_put(dmabuf->memcg); + dma_buf_stats_teardown(dmabuf); dmabuf->ops->release(dmabuf); =20 @@ -673,6 +676,13 @@ struct dma_buf *dma_buf_export(const struct dma_buf_ex= port_info *exp_info) if (ret) goto err_dmabuf; =20 + dmabuf->memcg =3D get_mem_cgroup_from_mm(current->mm); + if (!mem_cgroup_charge_dmabuf(dmabuf->memcg, PAGE_ALIGN(dmabuf->size) / P= AGE_SIZE, + GFP_KERNEL)) { + ret =3D -ENOMEM; + goto err_memcg; + } + file->private_data =3D dmabuf; file->f_path.dentry->d_fsdata =3D dmabuf; dmabuf->file =3D file; @@ -683,6 +693,9 @@ struct dma_buf *dma_buf_export(const struct dma_buf_exp= ort_info *exp_info) =20 return dmabuf; =20 +err_memcg: + mem_cgroup_put(dmabuf->memcg); + dma_buf_stats_teardown(dmabuf); err_dmabuf: if (!resv) dma_resv_fini(dmabuf->resv); diff --git a/include/linux/dma-buf.h b/include/linux/dma-buf.h index 6fa8d4e29719..1f0ffb8e4bf5 100644 --- a/include/linux/dma-buf.h +++ b/include/linux/dma-buf.h @@ -22,6 +22,7 @@ #include #include #include +#include =20 struct device; struct dma_buf; @@ -446,6 +447,8 @@ struct dma_buf { struct dma_buf *dmabuf; } *sysfs_entry; #endif + /* The cgroup to which this buffer is currently attributed */ + struct mem_cgroup *memcg; }; =20 /** diff --git a/include/linux/memcontrol.h b/include/linux/memcontrol.h index d3c8203cab6c..c10b8565fdbf 100644 --- a/include/linux/memcontrol.h +++ b/include/linux/memcontrol.h @@ -37,6 +37,7 @@ enum memcg_stat_item { MEMCG_KMEM, MEMCG_ZSWAP_B, MEMCG_ZSWAPPED, + MEMCG_DMABUF, MEMCG_NR_STAT, }; =20 @@ -673,6 +674,25 @@ static inline int mem_cgroup_charge(struct folio *foli= o, struct mm_struct *mm, =20 int mem_cgroup_swapin_charge_folio(struct folio *folio, struct mm_struct *= mm, gfp_t gfp, swp_entry_t entry); + +/** + * mem_cgroup_charge_dmabuf - Charge dma-buf memory to a cgroup and update= stat counter + * @memcg: memcg to charge + * @nr_pages: number of pages to charge + * @gfp_mask: reclaim mode + * + * Charges @nr_pages to @memcg. Returns %true if the charge fit within + * @memcg's configured limit, %false if it doesn't. + */ +bool __mem_cgroup_charge_dmabuf(struct mem_cgroup *memcg, unsigned int nr_= pages, gfp_t gfp_mask); +static inline bool mem_cgroup_charge_dmabuf(struct mem_cgroup *memcg, unsi= gned int nr_pages, + gfp_t gfp_mask) +{ + if (mem_cgroup_disabled()) + return 0; + return __mem_cgroup_charge_dmabuf(memcg, nr_pages, gfp_mask); +} + void mem_cgroup_swapin_uncharge_swap(swp_entry_t entry); =20 void __mem_cgroup_uncharge(struct folio *folio); @@ -690,6 +710,14 @@ static inline void mem_cgroup_uncharge(struct folio *f= olio) __mem_cgroup_uncharge(folio); } =20 +void __mem_cgroup_uncharge_dmabuf(struct mem_cgroup *memcg, unsigned int n= r_pages); +static inline void mem_cgroup_uncharge_dmabuf(struct mem_cgroup *memcg, un= signed int nr_pages) +{ + if (mem_cgroup_disabled()) + return; + __mem_cgroup_uncharge_dmabuf(memcg, nr_pages); +} + void __mem_cgroup_uncharge_list(struct list_head *page_list); static inline void mem_cgroup_uncharge_list(struct list_head *page_list) { @@ -1242,6 +1270,12 @@ static inline int mem_cgroup_swapin_charge_folio(str= uct folio *folio, return 0; } =20 +static inline bool mem_cgroup_charge_dmabuf(struct mem_cgroup *memcg, unsi= gned int nr_pages, + gfp_t gfp_mask) +{ + return true; +} + static inline void mem_cgroup_swapin_uncharge_swap(swp_entry_t entry) { } @@ -1250,6 +1284,10 @@ static inline void mem_cgroup_uncharge(struct folio = *folio) { } =20 +static inline void mem_cgroup_uncharge_dmabuf(struct mem_cgroup *memcg, un= signed int nr_pages) +{ +} + static inline void mem_cgroup_uncharge_list(struct list_head *page_list) { } diff --git a/mm/memcontrol.c b/mm/memcontrol.c index ab457f0394ab..375d18370f4b 100644 --- a/mm/memcontrol.c +++ b/mm/memcontrol.c @@ -1502,6 +1502,7 @@ static const struct memory_stat memory_stats[] =3D { { "unevictable", NR_UNEVICTABLE }, { "slab_reclaimable", NR_SLAB_RECLAIMABLE_B }, { "slab_unreclaimable", NR_SLAB_UNRECLAIMABLE_B }, + { "dmabuf", MEMCG_DMABUF }, =20 /* The memory events */ { "workingset_refault_anon", WORKINGSET_REFAULT_ANON }, @@ -4042,6 +4043,7 @@ static const unsigned int memcg1_stats[] =3D { WORKINGSET_REFAULT_ANON, WORKINGSET_REFAULT_FILE, MEMCG_SWAP, + MEMCG_DMABUF, }; =20 static const char *const memcg1_stat_names[] =3D { @@ -4057,6 +4059,7 @@ static const char *const memcg1_stat_names[] =3D { "workingset_refault_anon", "workingset_refault_file", "swap", + "dmabuf", }; =20 /* Universal VM events cgroup1 shows, original sort order */ @@ -7299,6 +7302,22 @@ void mem_cgroup_uncharge_skmem(struct mem_cgroup *me= mcg, unsigned int nr_pages) refill_stock(memcg, nr_pages); } =20 +bool __mem_cgroup_charge_dmabuf(struct mem_cgroup *memcg, unsigned int nr_= pages, gfp_t gfp_mask) +{ + if (try_charge(memcg, gfp_mask, nr_pages) =3D=3D 0) { + mod_memcg_state(memcg, MEMCG_DMABUF, nr_pages); + return true; + } + + return false; +} + +void __mem_cgroup_uncharge_dmabuf(struct mem_cgroup *memcg, unsigned int n= r_pages) +{ + mod_memcg_state(memcg, MEMCG_DMABUF, -nr_pages); + refill_stock(memcg, nr_pages); +} + static int __init cgroup_memory(char *s) { char *token; --=20 2.39.0.246.g2a6d74b583-goog From nobody Mon Sep 15 23:28:27 2025 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 vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id C4AD9C38142 for ; Mon, 23 Jan 2023 19:18:17 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232588AbjAWTSQ (ORCPT ); Mon, 23 Jan 2023 14:18:16 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:54914 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232387AbjAWTSF (ORCPT ); Mon, 23 Jan 2023 14:18:05 -0500 Received: from mail-yb1-xb4a.google.com (mail-yb1-xb4a.google.com [IPv6:2607:f8b0:4864:20::b4a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 97F78D50C for ; Mon, 23 Jan 2023 11:18:03 -0800 (PST) Received: by mail-yb1-xb4a.google.com with SMTP id m187-20020a2558c4000000b007f17c91f06fso13971175ybb.6 for ; Mon, 23 Jan 2023 11:18:03 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=9WOZzSEfhu/PT9TWBWMQDCCNsrofWV34oFDU/0sj1mQ=; b=CLJ2JxK/Tm4oa2T67r1/7AoCewa4cPoaCpXx/gVHbZ1m+FYlbdBISpcie92wke9qiT ywnZGTRRWgUyvtV2GeIN6CSF1A1BpACoPsOvCJSqkdka36IG7lwA9jHJB0/1Y37BiDn6 UZyz4QR44eh7OHGKOjLnRuXG7qELlMRlfRNYaxnDlTMYAnQZZAKF7GLGFraikV5q7pPa PqEGE55YfXGgQoOaL42PCJmSLM5OLIrr2pXTamoSK+ZBJQZ3xablgI1e6ZxykShX+C1V OGCeujU9/+VSQurUIb0N4LKyFw0PX0Xvt3l2bOlWDy6qNiZqzVXsJcA5m/zeCrF4rUUR ohNg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=9WOZzSEfhu/PT9TWBWMQDCCNsrofWV34oFDU/0sj1mQ=; b=1WlvW4hhFdy5L6EjegEaD9HB009XPP5WfaD/8WcM9HTWaHXrhoQRTZgEty9NsWLrUA hxB1Iu7JkhWO02oGE1Lsh5WToogoH/Ciuby93M871g7/m2y+sI2zYS5EXHgI2qkmu9Z1 5yiprA3DrlPd1X8L96cKqK5tq8VaQmGU+S3OjjfJD7vedtYFQGPKHU5l5O4X1PMkfE0I uEngC/BtQOc6x8oSbYlHt2TkVtA7v5/aOILgG5Q5H+AI8KdppNkwGBZn99z3T7mCnQwG DjqsAru2w5Las9yAtdxrV3xhf7xd/YX2Sy93hOxcYpeUyTI64oFjlFaVlO5tPjaynUUF ZiMA== X-Gm-Message-State: AFqh2koDzwPuEXNP0Cc9JSxkbC3uDf6hM+wysdmWKMD8QNv8oHFi1Tj0 XOOyvj9EiWJu088HEakWoER1UrSipchKE+0= X-Google-Smtp-Source: AMrXdXt5UsJV8XnGROzCqwUjMEtxGJTY0AAa2SUnm4rAwiP8wDQKiwcGvs1ceYITQIG6UCVtpU2h3/VNxLbuwi8= X-Received: from tj.c.googlers.com ([fda3:e722:ac3:cc00:20:ed76:c0a8:53a]) (user=tjmercier job=sendgmr) by 2002:a25:dc92:0:b0:7b0:3379:9c00 with SMTP id y140-20020a25dc92000000b007b033799c00mr3149691ybe.359.1674501483256; Mon, 23 Jan 2023 11:18:03 -0800 (PST) Date: Mon, 23 Jan 2023 19:17:24 +0000 In-Reply-To: <20230123191728.2928839-1-tjmercier@google.com> Mime-Version: 1.0 References: <20230123191728.2928839-1-tjmercier@google.com> X-Mailer: git-send-email 2.39.0.246.g2a6d74b583-goog Message-ID: <20230123191728.2928839-3-tjmercier@google.com> Subject: [PATCH v2 2/4] dmabuf: Add cgroup charge transfer function From: "T.J. Mercier" To: tjmercier@google.com, Sumit Semwal , "=?UTF-8?q?Christian=20K=C3=B6nig?=" Cc: hannes@cmpxchg.org, daniel.vetter@ffwll.ch, android-mm@google.com, jstultz@google.com, jeffv@google.com, cmllamas@google.com, linux-security-module@vger.kernel.org, selinux@vger.kernel.org, cgroups@vger.kernel.org, linux-media@vger.kernel.org, dri-devel@lists.freedesktop.org, linaro-mm-sig@lists.linaro.org, linux-kernel@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" The dma_buf_transfer_charge function provides a way for processes to transfer charge of a buffer to a different cgroup. This is essential for the cases where a central allocator process does allocations for various subsystems, hands over the fd to the client who requested the memory, and drops all references to the allocated memory. Signed-off-by: T.J. Mercier --- drivers/dma-buf/dma-buf.c | 56 ++++++++++++++++++++++++++++++++++++++ include/linux/dma-buf.h | 1 + include/linux/memcontrol.h | 5 ++++ 3 files changed, 62 insertions(+) diff --git a/drivers/dma-buf/dma-buf.c b/drivers/dma-buf/dma-buf.c index a6a8cb5cb32d..ac3d02a7ecf8 100644 --- a/drivers/dma-buf/dma-buf.c +++ b/drivers/dma-buf/dma-buf.c @@ -11,6 +11,7 @@ * refining of this idea. */ =20 +#include #include #include #include @@ -1626,6 +1627,61 @@ void dma_buf_vunmap_unlocked(struct dma_buf *dmabuf,= struct iosys_map *map) } EXPORT_SYMBOL_NS_GPL(dma_buf_vunmap_unlocked, DMA_BUF); =20 +/** + * dma_buf_transfer_charge - Change the cgroup to which the provided dma_b= uf is charged. + * @dmabuf_file: [in] file for buffer whose charge will be migrated to a d= ifferent cgroup + * @target: [in] the task_struct of the destination process for the cgrou= p charge + * + * Only tasks that belong to the same cgroup the buffer is currently charg= ed to + * may call this function, otherwise it will return -EPERM. + * + * Returns 0 on success, or a negative errno code otherwise. + */ +int dma_buf_transfer_charge(struct file *dmabuf_file, struct task_struct *= target) +{ + struct mem_cgroup *current_cg, *target_cg; + struct dma_buf *dmabuf; + unsigned int nr_pages; + int ret =3D 0; + + if (!IS_ENABLED(CONFIG_MEMCG)) + return 0; + + if (WARN_ON(!dmabuf_file) || WARN_ON(!target)) + return -EINVAL; + + if (!is_dma_buf_file(dmabuf_file)) + return -EBADF; + dmabuf =3D dmabuf_file->private_data; + + nr_pages =3D PAGE_ALIGN(dmabuf->size) / PAGE_SIZE; + current_cg =3D mem_cgroup_from_task(current); + target_cg =3D get_mem_cgroup_from_mm(target->mm); + + if (current_cg =3D=3D target_cg) + goto skip_transfer; + + if (!mem_cgroup_charge_dmabuf(target_cg, nr_pages, GFP_KERNEL)) { + ret =3D -ENOMEM; + goto skip_transfer; + } + + if (cmpxchg(&dmabuf->memcg, current_cg, target_cg) !=3D current_cg) { + /* Only the current owner can transfer the charge */ + ret =3D -EPERM; + mem_cgroup_uncharge_dmabuf(target_cg, nr_pages); + goto skip_transfer; + } + + mem_cgroup_uncharge_dmabuf(current_cg, nr_pages); + mem_cgroup_put(current_cg); /* unref from buffer - buffer keeps new ref t= o target_cg */ + return 0; + +skip_transfer: + mem_cgroup_put(target_cg); + return ret; +} + #ifdef CONFIG_DEBUG_FS static int dma_buf_debug_show(struct seq_file *s, void *unused) { diff --git a/include/linux/dma-buf.h b/include/linux/dma-buf.h index 1f0ffb8e4bf5..f25eb8e60fb2 100644 --- a/include/linux/dma-buf.h +++ b/include/linux/dma-buf.h @@ -634,4 +634,5 @@ int dma_buf_vmap(struct dma_buf *dmabuf, struct iosys_m= ap *map); void dma_buf_vunmap(struct dma_buf *dmabuf, struct iosys_map *map); int dma_buf_vmap_unlocked(struct dma_buf *dmabuf, struct iosys_map *map); void dma_buf_vunmap_unlocked(struct dma_buf *dmabuf, struct iosys_map *map= ); +int dma_buf_transfer_charge(struct file *dmabuf_file, struct task_struct *= target); #endif /* __DMA_BUF_H__ */ diff --git a/include/linux/memcontrol.h b/include/linux/memcontrol.h index c10b8565fdbf..009298a446fe 100644 --- a/include/linux/memcontrol.h +++ b/include/linux/memcontrol.h @@ -1335,6 +1335,11 @@ struct mem_cgroup *mem_cgroup_from_css(struct cgroup= _subsys_state *css) return NULL; } =20 +static inline struct mem_cgroup *mem_cgroup_from_task(struct task_struct *= p) +{ + return NULL; +} + static inline void obj_cgroup_put(struct obj_cgroup *objcg) { } --=20 2.39.0.246.g2a6d74b583-goog From nobody Mon Sep 15 23:28:27 2025 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 vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 005B0C54EAA for ; Mon, 23 Jan 2023 19:18:31 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232075AbjAWTSa (ORCPT ); Mon, 23 Jan 2023 14:18:30 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:55382 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232546AbjAWTSP (ORCPT ); Mon, 23 Jan 2023 14:18:15 -0500 Received: from mail-yw1-x114a.google.com (mail-yw1-x114a.google.com [IPv6:2607:f8b0:4864:20::114a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 830923526C for ; Mon, 23 Jan 2023 11:18:10 -0800 (PST) Received: by mail-yw1-x114a.google.com with SMTP id 00721157ae682-434eb7c6fa5so130084567b3.14 for ; Mon, 23 Jan 2023 11:18:10 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=5uKa2lBHkhi3cIuqVADqg4JwiGk7kXGvgzwjkWXPE30=; b=W0GJMmHqgH5AoPhdtj4CAeCrYtY8GW3G/CAVad1venyoBNsN9Q1u1ny7d3YNrbDrX6 2BJ/naxrnGYyQcG5u/LYD5lYPICUpmEuGtaCgLd09b0hiKMEBkEhzkpCo92aFUE72mxt wsSZBTh330ffstOMaagAGWLewdFLJkz4kcp+uBm72eUonuRtJ9vX9rVhthQsnyAVzYlu iN1QmHf5YtRpEebOM4lqG2MYpp3k85ysDLGCBcR/rODLDxFI3E98qrh20kAZDHIESJgE wApwTkeyf9oNVXsCGPzvBblcp2jLeZfzFFUQxFy3ZcMruw2tvteqL6NtHd22ChWHFNxb wNrw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=5uKa2lBHkhi3cIuqVADqg4JwiGk7kXGvgzwjkWXPE30=; b=KCzcMaKtxIoWis+zcTWrO+f2g09umdCcrDW5hcvtml1Ymv8KbD8BTaipnkUHRJk7uT 7FSDmPF8JjoOzN+SprPPVMS8+K2+xn1nEU0JNJDvOWEmdr3LJFCT1yO6QB34G3sdfR7y bdbk6Bv2Ajb2xizJYZmh8NnTzenNo6wpej7ZYVAsF2zlbjB2VyCXVoocFwV/NF4lw/Qx SFmOpr3l8WRNSI+ZFQ98wyFGynIHKGlM4NJAqlZ+1oTPhP8LDSywaJ6uWFoRcyX9KZNj pWwkXIrNKye8jwmZHX/lGtLZw5uWt3sKuUGbJ+r46EelIb/3Uc0YuTNXuIdxv4m+f+Ij zS5Q== X-Gm-Message-State: AFqh2kogW2EhDcmsshMTAlFfBoMZRz6FIbGqZu7pxvUrBPWTWWMd4d/m q3LFjYisFX7T3lbzaRGS0meHsf9W4R4/0xk= X-Google-Smtp-Source: AMrXdXsgB/R4Nu6aLZQnR3OqZyEGCVfjM272aoGgeWzL2xg1LYpkMP0ZYqsm24H+c0JiKdVTnaFcW0ScKQ/s73o= X-Received: from tj.c.googlers.com ([fda3:e722:ac3:cc00:20:ed76:c0a8:53a]) (user=tjmercier job=sendgmr) by 2002:a25:bf8e:0:b0:7d7:ec44:7cdc with SMTP id l14-20020a25bf8e000000b007d7ec447cdcmr2680514ybk.598.1674501489786; Mon, 23 Jan 2023 11:18:09 -0800 (PST) Date: Mon, 23 Jan 2023 19:17:25 +0000 In-Reply-To: <20230123191728.2928839-1-tjmercier@google.com> Mime-Version: 1.0 References: <20230123191728.2928839-1-tjmercier@google.com> X-Mailer: git-send-email 2.39.0.246.g2a6d74b583-goog Message-ID: <20230123191728.2928839-4-tjmercier@google.com> Subject: [PATCH v2 3/4] binder: Add flags to relinquish ownership of fds From: "T.J. Mercier" To: tjmercier@google.com, Tejun Heo , Zefan Li , Johannes Weiner , Jonathan Corbet , Greg Kroah-Hartman , "=?UTF-8?q?Arve=20Hj=C3=B8nnev=C3=A5g?=" , Todd Kjos , Martijn Coenen , Joel Fernandes , Christian Brauner , Carlos Llamas , Suren Baghdasaryan Cc: daniel.vetter@ffwll.ch, android-mm@google.com, jstultz@google.com, jeffv@google.com, linux-security-module@vger.kernel.org, selinux@vger.kernel.org, cgroups@vger.kernel.org, Hridya Valsaraju , linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Hridya Valsaraju This patch introduces flag BINDER_FD_FLAG_XFER_CHARGE that a process sending an individual fd or fd array to another process over binder IPC can set to relinquish ownership of the fd(s) being sent for memory accounting purposes. If the flag is found to be set during the fd or fd array translation and the fd is for a DMA-BUF, the buffer is uncharged from the sender's cgroup and charged to the receiving process's cgroup instead. It is up to the sending process to ensure that it closes the fds regardless of whether the transfer failed or succeeded. Most graphics shared memory allocations in Android are done by the graphics allocator HAL process. On requests from clients, the HAL process allocates memory and sends the fds to the clients over binder IPC. The graphics allocator HAL will not retain any references to the buffers. When the HAL sets BINDER_FD_FLAG_XFER_CHARGE, binder will transfer the charge for the buffer from the allocator process cgroup to the client process cgroup. The pad [1] and pad_flags [2] fields of binder_fd_object and binder_fda_array_object come from alignment with flat_binder_object and have never been exposed for use from userspace. This new flags use follows the pattern set by binder_buffer_object. [1] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/comm= it/include/uapi/linux/android/binder.h?id=3Dfeba3900cabb8e7c87368faa28e7a69= 36809ba22 [2] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/comm= it/include/uapi/linux/android/binder.h?id=3D5cdcf4c6a638591ec0e98c57404a19e= 7f9997567 Signed-off-by: Hridya Valsaraju Signed-off-by: T.J. Mercier Acked-by: Carlos Llamas --- Documentation/admin-guide/cgroup-v2.rst | 3 ++- drivers/android/binder.c | 25 +++++++++++++++++++++---- include/uapi/linux/android/binder.h | 19 +++++++++++++++---- 3 files changed, 38 insertions(+), 9 deletions(-) diff --git a/Documentation/admin-guide/cgroup-v2.rst b/Documentation/admin-= guide/cgroup-v2.rst index 538ae22bc514..d225295932c0 100644 --- a/Documentation/admin-guide/cgroup-v2.rst +++ b/Documentation/admin-guide/cgroup-v2.rst @@ -1457,7 +1457,8 @@ PAGE_SIZE multiple when read back. =20 dmabuf (npn) Amount of memory used for exported DMA buffers allocated by the cgroup. - Stays with the allocating cgroup regardless of how the buffer is shared. + Stays with the allocating cgroup regardless of how the buffer is shared + unless explicitly transferred. =20 workingset_refault_anon Number of refaults of previously evicted anonymous pages. diff --git a/drivers/android/binder.c b/drivers/android/binder.c index 880224ec6abb..5e707974793f 100644 --- a/drivers/android/binder.c +++ b/drivers/android/binder.c @@ -42,6 +42,7 @@ =20 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt =20 +#include #include #include #include @@ -2237,7 +2238,7 @@ static int binder_translate_handle(struct flat_binder= _object *fp, return ret; } =20 -static int binder_translate_fd(u32 fd, binder_size_t fd_offset, +static int binder_translate_fd(u32 fd, binder_size_t fd_offset, __u32 flag= s, struct binder_transaction *t, struct binder_thread *thread, struct binder_transaction *in_reply_to) @@ -2275,6 +2276,20 @@ static int binder_translate_fd(u32 fd, binder_size_t= fd_offset, goto err_security; } =20 + if (IS_ENABLED(CONFIG_MEMCG) && (flags & BINDER_FD_FLAG_XFER_CHARGE)) { + ret =3D dma_buf_transfer_charge(file, target_proc->tsk); + if (unlikely(ret =3D=3D -EBADF)) { + binder_user_error( + "%d:%d got transaction with XFER_CHARGE for non-DMA-BUF fd, %d\n", + proc->pid, thread->pid, fd); + goto err_dmabuf; + } else if (ret) { + pr_warn("%d:%d Unable to transfer DMA-BUF fd charge to %d\n", + proc->pid, thread->pid, target_proc->pid); + goto err_xfer; + } + } + /* * Add fixup record for this transaction. The allocation * of the fd in the target needs to be done from a @@ -2294,6 +2309,8 @@ static int binder_translate_fd(u32 fd, binder_size_t = fd_offset, return ret; =20 err_alloc: +err_xfer: +err_dmabuf: err_security: fput(file); err_fget: @@ -2604,7 +2621,7 @@ static int binder_translate_fd_array(struct list_head= *pf_head, =20 ret =3D copy_from_user(&fd, sender_ufda_base + sender_uoffset, sizeof(fd= )); if (!ret) - ret =3D binder_translate_fd(fd, offset, t, thread, + ret =3D binder_translate_fd(fd, offset, fda->flags, t, thread, in_reply_to); if (ret) return ret > 0 ? -EINVAL : ret; @@ -3383,8 +3400,8 @@ static void binder_transaction(struct binder_proc *pr= oc, struct binder_fd_object *fp =3D to_binder_fd_object(hdr); binder_size_t fd_offset =3D object_offset + (uintptr_t)&fp->fd - (uintptr_t)fp; - int ret =3D binder_translate_fd(fp->fd, fd_offset, t, - thread, in_reply_to); + int ret =3D binder_translate_fd(fp->fd, fd_offset, fp->flags, + t, thread, in_reply_to); =20 fp->pad_binder =3D 0; if (ret < 0 || diff --git a/include/uapi/linux/android/binder.h b/include/uapi/linux/andro= id/binder.h index e72e4de8f452..4b20dd1dccb1 100644 --- a/include/uapi/linux/android/binder.h +++ b/include/uapi/linux/android/binder.h @@ -91,14 +91,14 @@ struct flat_binder_object { /** * struct binder_fd_object - describes a filedescriptor to be fixed up. * @hdr: common header structure - * @pad_flags: padding to remain compatible with old userspace code + * @flags: One or more BINDER_FD_FLAG_* flags * @pad_binder: padding to remain compatible with old userspace code * @fd: file descriptor * @cookie: opaque data, used by user-space */ struct binder_fd_object { struct binder_object_header hdr; - __u32 pad_flags; + __u32 flags; union { binder_uintptr_t pad_binder; __u32 fd; @@ -107,6 +107,17 @@ struct binder_fd_object { binder_uintptr_t cookie; }; =20 +enum { + /** + * @BINDER_FD_FLAG_XFER_CHARGE + * + * When set, the sender of a binder_fd_object wishes to relinquish owners= hip of the fd for + * memory accounting purposes. If the fd is for a DMA-BUF, the buffer is = uncharged from the + * sender's cgroup and charged to the receiving process's cgroup instead. + */ + BINDER_FD_FLAG_XFER_CHARGE =3D 0x01, +}; + /* struct binder_buffer_object - object describing a userspace buffer * @hdr: common header structure * @flags: one or more BINDER_BUFFER_* flags @@ -141,7 +152,7 @@ enum { =20 /* struct binder_fd_array_object - object describing an array of fds in a = buffer * @hdr: common header structure - * @pad: padding to ensure correct alignment + * @flags: One or more BINDER_FD_FLAG_* flags * @num_fds: number of file descriptors in the buffer * @parent: index in offset array to buffer holding the fd array * @parent_offset: start offset of fd array in the buffer @@ -162,7 +173,7 @@ enum { */ struct binder_fd_array_object { struct binder_object_header hdr; - __u32 pad; + __u32 flags; binder_size_t num_fds; binder_size_t parent; binder_size_t parent_offset; --=20 2.39.0.246.g2a6d74b583-goog From nobody Mon Sep 15 23:28:27 2025 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 vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 12FBEC54EAA for ; Mon, 23 Jan 2023 19:19:08 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230489AbjAWTTG (ORCPT ); Mon, 23 Jan 2023 14:19:06 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:54934 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232159AbjAWTSa (ORCPT ); Mon, 23 Jan 2023 14:18:30 -0500 Received: from mail-pj1-x1049.google.com (mail-pj1-x1049.google.com [IPv6:2607:f8b0:4864:20::1049]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 1B07333466 for ; Mon, 23 Jan 2023 11:18:17 -0800 (PST) Received: by mail-pj1-x1049.google.com with SMTP id h2-20020a17090a580200b0022bbc8d6b6bso2639069pji.8 for ; Mon, 23 Jan 2023 11:18:17 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=z2WhRnZzQgS7vry+Z+wffN8GNT/+GwBkd2a3cKemc3A=; b=qIoHkzSJgScPAOmXRPybmkkxLYzr2DadvdaoU+21L1WVU3YW/Hmjf98YSxQck6Cojl hSJIB90Oc/J5PhcPthu37nMpMkmKvUecOx+8XcN0o61N3c9FSHsypWEcnKqeCpO8oZn5 5t2GLdXEZE6+Kn1L/RgqPV6+knFah8Sty5ttQeslTrfM6XTfbVGpIJuSS4JTguGrEf+K 02GyI8CR+Za0guqiCqlg7dAfcw68H5UFF1O5CbDXUC7fdVcQj+I00pYkk/UsWsyDil4n wMUZxRBLOsVMt7lEWJwwaO1NERbypePie8xI/PldXEjxtDPpICffELsttwq1JrA5YUun L0Tw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=z2WhRnZzQgS7vry+Z+wffN8GNT/+GwBkd2a3cKemc3A=; b=WgAvfkpjvfqcOpdBKvqiKq++ydRiKDowIIbjzhi0jCLU9Auju7tzngGX5H61Zk5PtL zvgkdi1A+CShnCRBO0AkOwncMcWA8D4mRjdI9elsawLW0EX+ZL7TmfU0WNr0my9QToFi ubNTlnqTmXuTiDzI21duRCUJYiu6lj4JwawkKuMWdWp4uG8TJ7ZDE8kQ4iAV9cYtIOBt Ce/YfycbZIXno9Wo8DOqOgrbPQJ6iwK1CfL3UyYBt7JhFFZCRsVGAw41p59Pk06KGejg ukY+a9LFosZAp7BZV+5KOU7ZzsSgLTcCj+0MQ5OBVgQQt/il2EAWu5u+x+gZ9y6cLUDH 4SLw== X-Gm-Message-State: AFqh2konq/Jhj+BWAFt8qHhmd16T4P7XQ7IuQutXJFULADMyAciVjUyK BuidwdnODZKOJoKgyWlMwQvoJ3g8KxiOaXo= X-Google-Smtp-Source: AMrXdXsNa09AO4Arg6ZBRXKwo+WF/qUZjQHNXFX5rA6KWe8BFUhOpIiYlW4PW5subPRyzOFWH3Ah7qsET8UrWsU= X-Received: from tj.c.googlers.com ([fda3:e722:ac3:cc00:20:ed76:c0a8:53a]) (user=tjmercier job=sendgmr) by 2002:aa7:8a0b:0:b0:58d:bffa:db35 with SMTP id m11-20020aa78a0b000000b0058dbffadb35mr2968935pfa.34.1674501496540; Mon, 23 Jan 2023 11:18:16 -0800 (PST) Date: Mon, 23 Jan 2023 19:17:26 +0000 In-Reply-To: <20230123191728.2928839-1-tjmercier@google.com> Mime-Version: 1.0 References: <20230123191728.2928839-1-tjmercier@google.com> X-Mailer: git-send-email 2.39.0.246.g2a6d74b583-goog Message-ID: <20230123191728.2928839-5-tjmercier@google.com> Subject: [PATCH v2 4/4] security: binder: Add binder object flags to selinux_binder_transfer_file From: "T.J. Mercier" To: tjmercier@google.com, Greg Kroah-Hartman , "=?UTF-8?q?Arve=20Hj=C3=B8nnev=C3=A5g?=" , Todd Kjos , Martijn Coenen , Joel Fernandes , Christian Brauner , Carlos Llamas , Suren Baghdasaryan , Paul Moore , James Morris , "Serge E. Hallyn" , Stephen Smalley , Eric Paris Cc: hannes@cmpxchg.org, daniel.vetter@ffwll.ch, android-mm@google.com, jstultz@google.com, jeffv@google.com, linux-security-module@vger.kernel.org, selinux@vger.kernel.org, cgroups@vger.kernel.org, linux-kernel@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Any process can cause a memory charge transfer to occur to any other process when transmitting a file descriptor through binder. This should only be possible for central allocator processes, so the binder object flags are added to the security_binder_transfer_file hook so that LSMs can enforce restrictions on charge transfers. Signed-off-by: T.J. Mercier --- drivers/android/binder.c | 2 +- include/linux/lsm_hook_defs.h | 2 +- include/linux/lsm_hooks.h | 5 ++++- include/linux/security.h | 6 ++++-- security/security.c | 4 ++-- security/selinux/hooks.c | 13 ++++++++++++- security/selinux/include/classmap.h | 2 +- 7 files changed, 25 insertions(+), 9 deletions(-) diff --git a/drivers/android/binder.c b/drivers/android/binder.c index 5e707974793f..7b1bb23b6b79 100644 --- a/drivers/android/binder.c +++ b/drivers/android/binder.c @@ -2270,7 +2270,7 @@ static int binder_translate_fd(u32 fd, binder_size_t = fd_offset, __u32 flags, ret =3D -EBADF; goto err_fget; } - ret =3D security_binder_transfer_file(proc->cred, target_proc->cred, file= ); + ret =3D security_binder_transfer_file(proc->cred, target_proc->cred, file= , flags); if (ret < 0) { ret =3D -EPERM; goto err_security; diff --git a/include/linux/lsm_hook_defs.h b/include/linux/lsm_hook_defs.h index ed6cb2ac55fa..84ee61089f7b 100644 --- a/include/linux/lsm_hook_defs.h +++ b/include/linux/lsm_hook_defs.h @@ -32,7 +32,7 @@ LSM_HOOK(int, 0, binder_transaction, const struct cred *f= rom, LSM_HOOK(int, 0, binder_transfer_binder, const struct cred *from, const struct cred *to) LSM_HOOK(int, 0, binder_transfer_file, const struct cred *from, - const struct cred *to, struct file *file) + const struct cred *to, struct file *file, u32 binder_object_flags) LSM_HOOK(int, 0, ptrace_access_check, struct task_struct *child, unsigned int mode) LSM_HOOK(int, 0, ptrace_traceme, struct task_struct *parent) diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h index 0a5ba81f7367..d57977336ae8 100644 --- a/include/linux/lsm_hooks.h +++ b/include/linux/lsm_hooks.h @@ -1381,9 +1381,12 @@ * Return 0 if permission is granted. * @binder_transfer_file: * Check whether @from is allowed to transfer @file to @to. + * If @binder_object_flags indicates a memory charge transfer for @file, t= hen + * permission for the charge transfer can be checked as well. * @from contains the struct cred for the sending process. - * @file contains the struct file being transferred. * @to contains the struct cred for the receiving process. + * @file contains the struct file being transferred. + * @binder_object_flags contains the flags associated with the binder obje= ct. * Return 0 if permission is granted. * * @ptrace_access_check: diff --git a/include/linux/security.h b/include/linux/security.h index 5b67f208f7de..c4b80fc8d104 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -269,7 +269,8 @@ int security_binder_transaction(const struct cred *from, int security_binder_transfer_binder(const struct cred *from, const struct cred *to); int security_binder_transfer_file(const struct cred *from, - const struct cred *to, struct file *file); + const struct cred *to, struct file *file, + u32 binder_object_flags); int security_ptrace_access_check(struct task_struct *child, unsigned int m= ode); int security_ptrace_traceme(struct task_struct *parent); int security_capget(struct task_struct *target, @@ -542,7 +543,8 @@ static inline int security_binder_transfer_binder(const= struct cred *from, =20 static inline int security_binder_transfer_file(const struct cred *from, const struct cred *to, - struct file *file) + struct file *file, + u32 binder_object_flags) { return 0; } diff --git a/security/security.c b/security/security.c index d1571900a8c7..12ccaca744c0 100644 --- a/security/security.c +++ b/security/security.c @@ -796,9 +796,9 @@ int security_binder_transfer_binder(const struct cred *= from, } =20 int security_binder_transfer_file(const struct cred *from, - const struct cred *to, struct file *file) + const struct cred *to, struct file *file, u32 binder_object_flags) { - return call_int_hook(binder_transfer_file, 0, from, to, file); + return call_int_hook(binder_transfer_file, 0, from, to, file, binder_obje= ct_flags); } =20 int security_ptrace_access_check(struct task_struct *child, unsigned int m= ode) diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 3c5be76a9199..d4cfca3c9a3b 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -88,6 +88,7 @@ #include #include #include /* for hashlen_string() */ +#include #include #include #include @@ -2029,7 +2030,8 @@ static int selinux_binder_transfer_binder(const struc= t cred *from, =20 static int selinux_binder_transfer_file(const struct cred *from, const struct cred *to, - struct file *file) + struct file *file, + u32 binder_object_flags) { u32 sid =3D cred_sid(to); struct file_security_struct *fsec =3D selinux_file(file); @@ -2038,6 +2040,15 @@ static int selinux_binder_transfer_file(const struct= cred *from, struct common_audit_data ad; int rc; =20 + if (binder_object_flags & BINDER_FD_FLAG_XFER_CHARGE) { + rc =3D avc_has_perm(&selinux_state, + cred_sid(from), sid, + SECCLASS_BINDER, BINDER__TRANSFER_CHARGE, + NULL); + if (rc) + return rc; + } + ad.type =3D LSM_AUDIT_DATA_PATH; ad.u.path =3D file->f_path; =20 diff --git a/security/selinux/include/classmap.h b/security/selinux/include= /classmap.h index a3c380775d41..2eef180d10d7 100644 --- a/security/selinux/include/classmap.h +++ b/security/selinux/include/classmap.h @@ -172,7 +172,7 @@ const struct security_class_mapping secclass_map[] =3D { { "tun_socket", { COMMON_SOCK_PERMS, "attach_queue", NULL } }, { "binder", { "impersonate", "call", "set_context_mgr", "transfer", - NULL } }, + "transfer_charge", NULL } }, { "cap_userns", { COMMON_CAP_PERMS, NULL } }, { "cap2_userns", --=20 2.39.0.246.g2a6d74b583-goog