[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Message-ID: <6f9de6c4-a2e0-4423-b581-dc15822fc641@googlemail.com>
Date: Tue, 6 May 2025 10:14:06 +0200 (GMT+02:00)
From: Christian Göttsche <cgzones@...glemail.com>
To: Cai Xinchen <caixinchen1@...wei.com>
Cc: linux-kernel@...r.kernel.org, selinux@...r.kernel.org,
paul@...l-moore.com, stephen.smalley.work@...il.com,
omosnace@...hat.com, ericsu@...ux.microsoft.com
Subject: Re: [PATCH] SELinux: Add check for the user data passed to kcalloc
in hashtab_init
May 6, 2025 09:20:51 Cai Xinchen <caixinchen1@...wei.com>:
> When the user writes some data to the file /sys/fs/selinux/policy,
> there is no check for the user buf passed to kcalloc. Syzkaller shows
> this warning:
> WARNING: CPU: 1 PID: 6642 at mm/page_alloc.c
>
> __alloc_pages_noprof
> ___kmalloc_large_node
> __kmalloc_large_node_noprof
> __kmalloc_noprof
> hashtab_init
> common_read
> policydb_read
> security_load_policy
> sel_write_load
> vfs_write
> ksys_write
> do_syscall_64
>
> This warning can be reproduced by writing this content to
> /sys/fs/selinux/policy
> 8cff7cf9 08000000 5345204c 696e7578 15000000 e0ff962a 08000000 07000000
> 4cf523cd 7eec2688 6d70a6b7 c78b496f 1a0a192c ea34ff41 70581a74 3ff0cfb9
> 7ea0f0d1 70d1fe14 41c2f7c8 ea1c78dd 17a19249 35210081 a83c30ec 4171450b
> fc1de12c fe1ff342 a887
>
> Add check to prevent the size passed to kcalloc larger than MAX_PAGE_ORDER
> after get_order.
This might be similar to https://lore.kernel.org/selinux/20241216164055.96267-12-cgoettsche@seltendoof.de/
I'll try to respin that patch set in time.
> Signed-off-by: Cai Xinchen <caixinchen1@...wei.com>
> ---
> security/selinux/ss/hashtab.c | 18 ++++++++++++++++++
> 1 file changed, 18 insertions(+)
>
> diff --git a/security/selinux/ss/hashtab.c b/security/selinux/ss/hashtab.c
> index 383fd2d70878..18bcf3978c9e 100644
> --- a/security/selinux/ss/hashtab.c
> +++ b/security/selinux/ss/hashtab.c
> @@ -30,6 +30,21 @@ static u32 hashtab_compute_size(u32 nel)
> return nel == 0 ? 0 : roundup_pow_of_two(nel);
> }
>
> +static bool is_order_out_of_range(u32 size, struct hashtab *h)
> +{
> + size_t bytes;
> + u32 order;
> +
> + if (unlikely(check_mul_overflow(size, sizeof(*h->htable), &bytes)))
> + return true;
> +
> + order = get_order(bytes);
> + if (order > MAX_PAGE_ORDER)
> + return true;
> +
> + return false;
> +}
> +
> int hashtab_init(struct hashtab *h, u32 nel_hint)
> {
> u32 size = hashtab_compute_size(nel_hint);
> @@ -40,6 +55,9 @@ int hashtab_init(struct hashtab *h, u32 nel_hint)
> h->htable = NULL;
>
> if (size) {
> + if (is_order_out_of_range(size, h))
> + return -ENOMEM;
> +
> h->htable = kcalloc(size, sizeof(*h->htable), GFP_KERNEL);
> if (!h->htable)
> return -ENOMEM;
> --
> 2.34.1
Powered by blists - more mailing lists