[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Message-ID: <f9f2ef979100a8809d7e3ac6106362f7a273e1e0.camel@ibm.com>
Date: Thu, 18 Dec 2025 19:11:31 +0000
From: Viacheslav Dubeyko <Slava.Dubeyko@....com>
To: "idryomov@...il.com" <idryomov@...il.com>, Xiubo Li <xiubli@...hat.com>,
"islituo@...il.com" <islituo@...il.com>
CC: "ceph-devel@...r.kernel.org" <ceph-devel@...r.kernel.org>,
"linux-kernel@...r.kernel.org" <linux-kernel@...r.kernel.org>
Subject: Re: [PATCH] net: ceph: Fix a possible null-pointer dereference in
decode_choose_args()
On Thu, 2025-12-18 at 15:56 +0800, Tuo Li wrote:
> In decode_choose_args(), arg_map->size is updated before memory is
> allocated for arg_map->args using kcalloc(). If kcalloc() fails, execution
> jumps to the fail label, where free_choose_arg_map() is called to release
> resources. However, free_choose_arg_map() unconditionally iterates over
> arg_map->args using arg_map->size, which can lead to a NULL pointer
> dereference when arg_map->args is NULL:
>
> for (i = 0; i < arg_map->size; i++) {
> struct crush_choose_arg *arg = &arg_map->args[i];
>
> for (j = 0; j < arg->weight_set_size; j++)
> kfree(arg->weight_set[j].weights);
> kfree(arg->weight_set);
> kfree(arg->ids);
> }
>
> To prevent this potential NULL pointer dereference, move the assignment to
> arg_map->size to after successful allocation of arg_map->args. This ensures
> that when allocation fails, arg_map->size remains zero and the loop in
> free_choose_arg_map() is not executed.
>
> Signed-off-by: Tuo Li <islituo@...il.com>
> ---
> net/ceph/osdmap.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/net/ceph/osdmap.c b/net/ceph/osdmap.c
> index d245fa508e1c..f67a87b3a7c8 100644
> --- a/net/ceph/osdmap.c
> +++ b/net/ceph/osdmap.c
> @@ -363,13 +363,13 @@ static int decode_choose_args(void **p, void *end, struct crush_map *c)
>
> ceph_decode_64_safe(p, end, arg_map->choose_args_index,
> e_inval);
> - arg_map->size = c->max_buckets;
The arg_map->size defines the size of memory allocation. If you remove the
assignment here, then which size kcalloc() will allocate. I assume we could have
two possible scenarios here: (1) arg_map->size is equal to zero -> no allocation
happens, (2) arg_map->size contains garbage value -> any failure could happen.
Have you reproduced the declared issue that you are trying to fix? Are you sure
that your patch can fix the issue? Have you tested your patch at all?
Thanks,
Slava.
> arg_map->args = kcalloc(arg_map->size, sizeof(*arg_map->args),
> GFP_NOIO);
> if (!arg_map->args) {
> ret = -ENOMEM;
> goto fail;
> }
> + arg_map->size = c->max_buckets;
>
> ceph_decode_32_safe(p, end, num_buckets, e_inval);
> while (num_buckets--) {
Powered by blists - more mailing lists