lkml.org 
[lkml]   [2017]   [Nov]   [11]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 01/14] nubus: Avoid array underflow and overflow
    Date
    Check array indices. Avoid sprintf. Use buffers of sufficient size.
    Use appropriate types for the parameters to nubus_get_rsrc_{mem,str}()
    functions.

    Tested-by: Stan Johnson <userm57@yahoo.com>
    Signed-off-by: Finn Thain <fthain@telegraphics.com.au>
    ---
    drivers/nubus/nubus.c | 29 +++++++++++++++++------------
    drivers/nubus/proc.c | 12 ++++++------
    include/linux/nubus.h | 10 ++++------
    3 files changed, 27 insertions(+), 24 deletions(-)

    diff --git a/drivers/nubus/nubus.c b/drivers/nubus/nubus.c
    index 4f50f30650cd..afbea40512a3 100644
    --- a/drivers/nubus/nubus.c
    +++ b/drivers/nubus/nubus.c
    @@ -160,7 +160,7 @@ static unsigned char *nubus_dirptr(const struct nubus_dirent *nd)
    pointed to with offsets) out of the card ROM. */

    void nubus_get_rsrc_mem(void *dest, const struct nubus_dirent *dirent,
    - int len)
    + unsigned int len)
    {
    unsigned char *t = (unsigned char *)dest;
    unsigned char *p = nubus_dirptr(dirent);
    @@ -172,18 +172,22 @@ void nubus_get_rsrc_mem(void *dest, const struct nubus_dirent *dirent,
    }
    EXPORT_SYMBOL(nubus_get_rsrc_mem);

    -void nubus_get_rsrc_str(void *dest, const struct nubus_dirent *dirent,
    - int len)
    +void nubus_get_rsrc_str(char *dest, const struct nubus_dirent *dirent,
    + unsigned int len)
    {
    - unsigned char *t = (unsigned char *)dest;
    + char *t = dest;
    unsigned char *p = nubus_dirptr(dirent);

    - while (len) {
    - *t = nubus_get_rom(&p, 1, dirent->mask);
    - if (!*t++)
    + while (len > 1) {
    + unsigned char c = nubus_get_rom(&p, 1, dirent->mask);
    +
    + if (!c)
    break;
    + *t++ = c;
    len--;
    }
    + if (len > 0)
    + *t = '\0';
    }
    EXPORT_SYMBOL(nubus_get_rsrc_str);

    @@ -467,7 +471,7 @@ nubus_get_functional_resource(struct nubus_board *board, int slot,
    }
    case NUBUS_RESID_NAME:
    {
    - nubus_get_rsrc_str(dev->name, &ent, 64);
    + nubus_get_rsrc_str(dev->name, &ent, sizeof(dev->name));
    pr_info(" name: %s\n", dev->name);
    break;
    }
    @@ -527,7 +531,7 @@ static int __init nubus_get_vidnames(struct nubus_board *board,
    /* Don't know what this is yet */
    u16 id;
    /* Longest one I've seen so far is 26 characters */
    - char name[32];
    + char name[36];
    };

    pr_info(" video modes supported:\n");
    @@ -597,8 +601,8 @@ static int __init nubus_get_vendorinfo(struct nubus_board *board,
    char name[64];

    /* These are all strings, we think */
    - nubus_get_rsrc_str(name, &ent, 64);
    - if (ent.type > 5)
    + nubus_get_rsrc_str(name, &ent, sizeof(name));
    + if (ent.type < 1 || ent.type > 5)
    ent.type = 5;
    pr_info(" %s: %s\n", vendor_fields[ent.type - 1], name);
    }
    @@ -632,7 +636,8 @@ static int __init nubus_get_board_resource(struct nubus_board *board, int slot,
    break;
    }
    case NUBUS_RESID_NAME:
    - nubus_get_rsrc_str(board->name, &ent, 64);
    + nubus_get_rsrc_str(board->name, &ent,
    + sizeof(board->name));
    pr_info(" name: %s\n", board->name);
    break;
    case NUBUS_RESID_ICON:
    diff --git a/drivers/nubus/proc.c b/drivers/nubus/proc.c
    index e8f68f5732f1..a74e713a4f7f 100644
    --- a/drivers/nubus/proc.c
    +++ b/drivers/nubus/proc.c
    @@ -72,10 +72,10 @@ static void nubus_proc_subdir(struct nubus_dev* dev,

    /* Some of these are directories, others aren't */
    while (nubus_readdir(dir, &ent) != -1) {
    - char name[8];
    + char name[9];
    struct proc_dir_entry* e;

    - sprintf(name, "%x", ent.type);
    + snprintf(name, sizeof(name), "%x", ent.type);
    e = proc_create(name, S_IFREG | S_IRUGO | S_IWUSR, parent,
    &nubus_proc_subdir_fops);
    if (!e)
    @@ -94,11 +94,11 @@ static void nubus_proc_populate(struct nubus_dev* dev,
    /* We know these are all directories (board resource + one or
    more functional resources) */
    while (nubus_readdir(root, &ent) != -1) {
    - char name[8];
    + char name[9];
    struct proc_dir_entry* e;
    struct nubus_dir dir;

    - sprintf(name, "%x", ent.type);
    + snprintf(name, sizeof(name), "%x", ent.type);
    e = proc_mkdir(name, parent);
    if (!e) return;

    @@ -118,7 +118,7 @@ int nubus_proc_attach_device(struct nubus_dev *dev)
    {
    struct proc_dir_entry *e;
    struct nubus_dir root;
    - char name[8];
    + char name[9];

    if (dev == NULL) {
    printk(KERN_ERR
    @@ -134,7 +134,7 @@ int nubus_proc_attach_device(struct nubus_dev *dev)
    }

    /* Create a directory */
    - sprintf(name, "%x", dev->board->slot);
    + snprintf(name, sizeof(name), "%x", dev->board->slot);
    e = dev->procdir = proc_mkdir(name, proc_bus_nubus_dir);
    if (!e)
    return -ENOMEM;
    diff --git a/include/linux/nubus.h b/include/linux/nubus.h
    index 6165b2c62040..b5c4683737e3 100644
    --- a/include/linux/nubus.h
    +++ b/include/linux/nubus.h
    @@ -125,10 +125,8 @@ int nubus_rewinddir(struct nubus_dir* dir);
    /* Things to do with directory entries */
    int nubus_get_subdir(const struct nubus_dirent* ent,
    struct nubus_dir* dir);
    -void nubus_get_rsrc_mem(void* dest,
    - const struct nubus_dirent *dirent,
    - int len);
    -void nubus_get_rsrc_str(void* dest,
    - const struct nubus_dirent *dirent,
    - int maxlen);
    +void nubus_get_rsrc_mem(void *dest, const struct nubus_dirent *dirent,
    + unsigned int len);
    +void nubus_get_rsrc_str(char *dest, const struct nubus_dirent *dirent,
    + unsigned int maxlen);
    #endif /* LINUX_NUBUS_H */
    --
    2.13.6
    \
     
     \ /
      Last update: 2017-11-11 07:14    [W:4.409 / U:0.016 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site