Skip to content
  • Kees Cook's avatar
    treewide: Use struct_size() for kmalloc()-family · acafe7e3
    Kees Cook authored
    
    
    One of the more common cases of allocation size calculations is finding
    the size of a structure that has a zero-sized array at the end, along
    with memory for some number of elements for that array. For example:
    
    struct foo {
        int stuff;
        void *entry[];
    };
    
    instance = kmalloc(sizeof(struct foo) + sizeof(void *) * count, GFP_KERNEL);
    
    Instead of leaving these open-coded and prone to type mistakes, we can
    now use the new struct_size() helper:
    
    instance = kmalloc(struct_size(instance, entry, count), GFP_KERNEL);
    
    This patch makes the changes for kmalloc()-family (and kvmalloc()-family)
    uses. It was done via automatic conversion with manual review for the
    "CHECKME" non-standard cases noted below, using the following Coccinelle
    script:
    
    // pkey_cache = kmalloc(sizeof *pkey_cache + tprops->pkey_tbl_len *
    //                      sizeof *pkey_cache->table, GFP_KERNEL);
    @@
    identifier alloc =~ "kmalloc|kzalloc|kvmalloc|kvzalloc";
    expression GFP;
    identifier VAR, ELEMENT;
    expression COUNT;
    @@
    
    - alloc(sizeof(*VAR) + COUNT * sizeof(*VAR->ELEMENT), GFP)
    + alloc(struct_size(VAR, ELEMENT, COUNT), GFP)
    
    // mr = kzalloc(sizeof(*mr) + m * sizeof(mr->map[0]), GFP_KERNEL);
    @@
    identifier alloc =~ "kmalloc|kzalloc|kvmalloc|kvzalloc";
    expression GFP;
    identifier VAR, ELEMENT;
    expression COUNT;
    @@
    
    - alloc(sizeof(*VAR) + COUNT * sizeof(VAR->ELEMENT[0]), GFP)
    + alloc(struct_size(VAR, ELEMENT, COUNT), GFP)
    
    // Same pattern, but can't trivially locate the trailing element name,
    // or variable name.
    @@
    identifier alloc =~ "kmalloc|kzalloc|kvmalloc|kvzalloc";
    expression GFP;
    expression SOMETHING, COUNT, ELEMENT;
    @@
    
    - alloc(sizeof(SOMETHING) + COUNT * sizeof(ELEMENT), GFP)
    + alloc(CHECKME_struct_size(&SOMETHING, ELEMENT, COUNT), GFP)
    
    Signed-off-by: default avatarKees Cook <keescook@chromium.org>
    acafe7e3