Commit 2f828fb2 authored by Finn Thain's avatar Finn Thain Committed by Geert Uytterhoeven

nubus: Avoid array underflow and overflow

Check array indices. Avoid sprintf. Use buffers of sufficient size.
Use appropriate types for array length parameters.
Tested-by: default avatarStan Johnson <userm57@yahoo.com>
Signed-off-by: default avatarFinn Thain <fthain@telegraphics.com.au>
Signed-off-by: default avatarGeert Uytterhoeven <geert@linux-m68k.org>
parent 955999c9
...@@ -161,7 +161,7 @@ static unsigned char *nubus_dirptr(const struct nubus_dirent *nd) ...@@ -161,7 +161,7 @@ static unsigned char *nubus_dirptr(const struct nubus_dirent *nd)
pointed to with offsets) out of the card ROM. */ pointed to with offsets) out of the card ROM. */
void nubus_get_rsrc_mem(void *dest, const struct nubus_dirent *dirent, 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 *t = (unsigned char *)dest;
unsigned char *p = nubus_dirptr(dirent); unsigned char *p = nubus_dirptr(dirent);
...@@ -173,18 +173,22 @@ void nubus_get_rsrc_mem(void *dest, const struct nubus_dirent *dirent, ...@@ -173,18 +173,22 @@ void nubus_get_rsrc_mem(void *dest, const struct nubus_dirent *dirent,
} }
EXPORT_SYMBOL(nubus_get_rsrc_mem); EXPORT_SYMBOL(nubus_get_rsrc_mem);
void nubus_get_rsrc_str(void *dest, const struct nubus_dirent *dirent, void nubus_get_rsrc_str(char *dest, const struct nubus_dirent *dirent,
int len) unsigned int len)
{ {
unsigned char *t = (unsigned char *)dest; char *t = dest;
unsigned char *p = nubus_dirptr(dirent); unsigned char *p = nubus_dirptr(dirent);
while (len) { while (len > 1) {
*t = nubus_get_rom(&p, 1, dirent->mask); unsigned char c = nubus_get_rom(&p, 1, dirent->mask);
if (!*t++)
if (!c)
break; break;
*t++ = c;
len--; len--;
} }
if (len > 0)
*t = '\0';
} }
EXPORT_SYMBOL(nubus_get_rsrc_str); EXPORT_SYMBOL(nubus_get_rsrc_str);
...@@ -468,7 +472,7 @@ nubus_get_functional_resource(struct nubus_board *board, int slot, ...@@ -468,7 +472,7 @@ nubus_get_functional_resource(struct nubus_board *board, int slot,
} }
case NUBUS_RESID_NAME: 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); pr_info(" name: %s\n", dev->name);
break; break;
} }
...@@ -528,7 +532,7 @@ static int __init nubus_get_vidnames(struct nubus_board *board, ...@@ -528,7 +532,7 @@ static int __init nubus_get_vidnames(struct nubus_board *board,
/* Don't know what this is yet */ /* Don't know what this is yet */
u16 id; u16 id;
/* Longest one I've seen so far is 26 characters */ /* Longest one I've seen so far is 26 characters */
char name[32]; char name[36];
}; };
pr_info(" video modes supported:\n"); pr_info(" video modes supported:\n");
...@@ -598,8 +602,8 @@ static int __init nubus_get_vendorinfo(struct nubus_board *board, ...@@ -598,8 +602,8 @@ static int __init nubus_get_vendorinfo(struct nubus_board *board,
char name[64]; char name[64];
/* These are all strings, we think */ /* These are all strings, we think */
nubus_get_rsrc_str(name, &ent, 64); nubus_get_rsrc_str(name, &ent, sizeof(name));
if (ent.type > 5) if (ent.type < 1 || ent.type > 5)
ent.type = 5; ent.type = 5;
pr_info(" %s: %s\n", vendor_fields[ent.type - 1], name); pr_info(" %s: %s\n", vendor_fields[ent.type - 1], name);
} }
...@@ -633,7 +637,8 @@ static int __init nubus_get_board_resource(struct nubus_board *board, int slot, ...@@ -633,7 +637,8 @@ static int __init nubus_get_board_resource(struct nubus_board *board, int slot,
break; break;
} }
case NUBUS_RESID_NAME: 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); pr_info(" name: %s\n", board->name);
break; break;
case NUBUS_RESID_ICON: case NUBUS_RESID_ICON:
......
...@@ -73,10 +73,10 @@ static void nubus_proc_subdir(struct nubus_dev* dev, ...@@ -73,10 +73,10 @@ static void nubus_proc_subdir(struct nubus_dev* dev,
/* Some of these are directories, others aren't */ /* Some of these are directories, others aren't */
while (nubus_readdir(dir, &ent) != -1) { while (nubus_readdir(dir, &ent) != -1) {
char name[8]; char name[9];
struct proc_dir_entry* e; 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, e = proc_create(name, S_IFREG | S_IRUGO | S_IWUSR, parent,
&nubus_proc_subdir_fops); &nubus_proc_subdir_fops);
if (!e) if (!e)
...@@ -95,11 +95,11 @@ static void nubus_proc_populate(struct nubus_dev* dev, ...@@ -95,11 +95,11 @@ static void nubus_proc_populate(struct nubus_dev* dev,
/* We know these are all directories (board resource + one or /* We know these are all directories (board resource + one or
more functional resources) */ more functional resources) */
while (nubus_readdir(root, &ent) != -1) { while (nubus_readdir(root, &ent) != -1) {
char name[8]; char name[9];
struct proc_dir_entry* e; struct proc_dir_entry* e;
struct nubus_dir dir; struct nubus_dir dir;
sprintf(name, "%x", ent.type); snprintf(name, sizeof(name), "%x", ent.type);
e = proc_mkdir(name, parent); e = proc_mkdir(name, parent);
if (!e) return; if (!e) return;
...@@ -119,7 +119,7 @@ int nubus_proc_attach_device(struct nubus_dev *dev) ...@@ -119,7 +119,7 @@ int nubus_proc_attach_device(struct nubus_dev *dev)
{ {
struct proc_dir_entry *e; struct proc_dir_entry *e;
struct nubus_dir root; struct nubus_dir root;
char name[8]; char name[9];
if (dev == NULL) { if (dev == NULL) {
printk(KERN_ERR printk(KERN_ERR
...@@ -135,7 +135,7 @@ int nubus_proc_attach_device(struct nubus_dev *dev) ...@@ -135,7 +135,7 @@ int nubus_proc_attach_device(struct nubus_dev *dev)
} }
/* Create a directory */ /* 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); e = dev->procdir = proc_mkdir(name, proc_bus_nubus_dir);
if (!e) if (!e)
return -ENOMEM; return -ENOMEM;
......
...@@ -126,10 +126,8 @@ int nubus_rewinddir(struct nubus_dir* dir); ...@@ -126,10 +126,8 @@ int nubus_rewinddir(struct nubus_dir* dir);
/* Things to do with directory entries */ /* Things to do with directory entries */
int nubus_get_subdir(const struct nubus_dirent* ent, int nubus_get_subdir(const struct nubus_dirent* ent,
struct nubus_dir* dir); struct nubus_dir* dir);
void nubus_get_rsrc_mem(void* dest, void nubus_get_rsrc_mem(void *dest, const struct nubus_dirent *dirent,
const struct nubus_dirent *dirent, unsigned int len);
int len); void nubus_get_rsrc_str(char *dest, const struct nubus_dirent *dirent,
void nubus_get_rsrc_str(void* dest, unsigned int maxlen);
const struct nubus_dirent *dirent,
int maxlen);
#endif /* LINUX_NUBUS_H */ #endif /* LINUX_NUBUS_H */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment