Re: Uninline kcalloc

From: Xi Wang
Date: Wed Feb 15 2012 - 22:11:41 EST


On Feb 15, 2012, at 2:34 PM, Christoph Lameter wrote:
> Any allocation larger than MAX_ORDER << PAGE_SHIFT will fail since the
> page allocator cannot serve larger contigous pages.

Yes, any number larger than KMALLOC_MAX_SIZE would do the trick.
The question is whether people would like to adopt

kmalloc(ARRAY_BYTES(n, size), ...);

or

knalloc(n, size, ...);

Besides, I am worried that ARRAY_BYTES is error-prone because you
have to make sure that ARRAY_BYTES is used only in *alloc, not
elsewhere, not in forms like ARRAY_BYTES(n, size) + padding_size,
etc. If ARRAY_BYTES is mostly used with kmalloc(), and the only
safe form is kmalloc(ARRAY_BYTES(n, size), ...), then adding a new
allocator knalloc(n, size, ...) seems like a simpler choice.

BTW, here goes a partial list of places where the new allocator
could be used to simplify existing checks.

fs/cifs/cifsacl.c:912

if (num_aces > ULONG_MAX / sizeof(struct cifs_ace *))
return;
ppace = kmalloc(num_aces * sizeof(struct cifs_ace *),
GFP_KERNEL);

fs/cifs/asn1.c:428

if (size < 2 || size > UINT_MAX/sizeof(unsigned long))
return 0;

*oid = kmalloc(size * sizeof(unsigned long), GFP_ATOMIC);

fs/nfs/callback_xdr.c:308

if (n > ULONG_MAX / sizeof(*args->devs)) {
status = htonl(NFS4ERR_BADXDR);
goto out;
}

args->devs = kmalloc(n * sizeof(*args->devs), GFP_KERNEL);

net/ipv4/netfilter/nf_nat_snmp_basic.c:447

if (size < 2 || size > ULONG_MAX/sizeof(unsigned long))
return 0;

*oid = kmalloc(size * sizeof(unsigned long), GFP_ATOMIC);

drivers/staging/comedi/comedi_fops.c:673

insns =
kcalloc(insnlist.n_insns, sizeof(struct comedi_insn), GFP_KERNEL);

I believe there are more places without those checks, where the new
allocator can offer better security.

- xi

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/