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: Stan Johnson <userm57@yahoo.com> Signed-off-by: Finn Thain <fthain@telegraphics.com.au> Signed-off-by: Geert Uytterhoeven <geert@linux-m68k.org>
This commit is contained in:
parent
955999c902
commit
2f828fb21d
3 changed files with 27 additions and 24 deletions
|
@ -161,7 +161,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);
|
||||
|
@ -173,18 +173,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);
|
||||
|
||||
|
@ -468,7 +472,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;
|
||||
}
|
||||
|
@ -528,7 +532,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");
|
||||
|
@ -598,8 +602,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);
|
||||
}
|
||||
|
@ -633,7 +637,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:
|
||||
|
|
|
@ -73,10 +73,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)
|
||||
|
@ -95,11 +95,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;
|
||||
|
||||
|
@ -119,7 +119,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
|
||||
|
@ -135,7 +135,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;
|
||||
|
|
|
@ -126,10 +126,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 */
|
||||
|
|
Loading…
Reference in a new issue