summaryrefslogtreecommitdiffstats
path: root/drivers/nubus
diff options
context:
space:
mode:
authorFinn Thain <fthain@telegraphics.com.au>2018-01-13 17:37:13 -0500
committerGeert Uytterhoeven <geert@linux-m68k.org>2018-01-16 10:47:29 -0500
commit2f828fb21df42058084b16d5e07cecdc30dbc3a5 (patch)
treee4dd00df654ccc5b3119ea6b93ef94f326daf1c0 /drivers/nubus
parent955999c9023290da18230b57df1f04187a43a4c0 (diff)
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>
Diffstat (limited to 'drivers/nubus')
-rw-r--r--drivers/nubus/nubus.c29
-rw-r--r--drivers/nubus/proc.c12
2 files changed, 23 insertions, 18 deletions
diff --git a/drivers/nubus/nubus.c b/drivers/nubus/nubus.c
index b793727cd4f7..b6c97e07f15e 100644
--- a/drivers/nubus/nubus.c
+++ b/drivers/nubus/nubus.c
@@ -161,7 +161,7 @@ static unsigned char *nubus_dirptr(const struct nubus_dirent *nd)
161 pointed to with offsets) out of the card ROM. */ 161 pointed to with offsets) out of the card ROM. */
162 162
163void nubus_get_rsrc_mem(void *dest, const struct nubus_dirent *dirent, 163void nubus_get_rsrc_mem(void *dest, const struct nubus_dirent *dirent,
164 int len) 164 unsigned int len)
165{ 165{
166 unsigned char *t = (unsigned char *)dest; 166 unsigned char *t = (unsigned char *)dest;
167 unsigned char *p = nubus_dirptr(dirent); 167 unsigned char *p = nubus_dirptr(dirent);
@@ -173,18 +173,22 @@ void nubus_get_rsrc_mem(void *dest, const struct nubus_dirent *dirent,
173} 173}
174EXPORT_SYMBOL(nubus_get_rsrc_mem); 174EXPORT_SYMBOL(nubus_get_rsrc_mem);
175 175
176void nubus_get_rsrc_str(void *dest, const struct nubus_dirent *dirent, 176void nubus_get_rsrc_str(char *dest, const struct nubus_dirent *dirent,
177 int len) 177 unsigned int len)
178{ 178{
179 unsigned char *t = (unsigned char *)dest; 179 char *t = dest;
180 unsigned char *p = nubus_dirptr(dirent); 180 unsigned char *p = nubus_dirptr(dirent);
181 181
182 while (len) { 182 while (len > 1) {
183 *t = nubus_get_rom(&p, 1, dirent->mask); 183 unsigned char c = nubus_get_rom(&p, 1, dirent->mask);
184 if (!*t++) 184
185 if (!c)
185 break; 186 break;
187 *t++ = c;
186 len--; 188 len--;
187 } 189 }
190 if (len > 0)
191 *t = '\0';
188} 192}
189EXPORT_SYMBOL(nubus_get_rsrc_str); 193EXPORT_SYMBOL(nubus_get_rsrc_str);
190 194
@@ -468,7 +472,7 @@ nubus_get_functional_resource(struct nubus_board *board, int slot,
468 } 472 }
469 case NUBUS_RESID_NAME: 473 case NUBUS_RESID_NAME:
470 { 474 {
471 nubus_get_rsrc_str(dev->name, &ent, 64); 475 nubus_get_rsrc_str(dev->name, &ent, sizeof(dev->name));
472 pr_info(" name: %s\n", dev->name); 476 pr_info(" name: %s\n", dev->name);
473 break; 477 break;
474 } 478 }
@@ -528,7 +532,7 @@ static int __init nubus_get_vidnames(struct nubus_board *board,
528 /* Don't know what this is yet */ 532 /* Don't know what this is yet */
529 u16 id; 533 u16 id;
530 /* Longest one I've seen so far is 26 characters */ 534 /* Longest one I've seen so far is 26 characters */
531 char name[32]; 535 char name[36];
532 }; 536 };
533 537
534 pr_info(" video modes supported:\n"); 538 pr_info(" video modes supported:\n");
@@ -598,8 +602,8 @@ static int __init nubus_get_vendorinfo(struct nubus_board *board,
598 char name[64]; 602 char name[64];
599 603
600 /* These are all strings, we think */ 604 /* These are all strings, we think */
601 nubus_get_rsrc_str(name, &ent, 64); 605 nubus_get_rsrc_str(name, &ent, sizeof(name));
602 if (ent.type > 5) 606 if (ent.type < 1 || ent.type > 5)
603 ent.type = 5; 607 ent.type = 5;
604 pr_info(" %s: %s\n", vendor_fields[ent.type - 1], name); 608 pr_info(" %s: %s\n", vendor_fields[ent.type - 1], name);
605 } 609 }
@@ -633,7 +637,8 @@ static int __init nubus_get_board_resource(struct nubus_board *board, int slot,
633 break; 637 break;
634 } 638 }
635 case NUBUS_RESID_NAME: 639 case NUBUS_RESID_NAME:
636 nubus_get_rsrc_str(board->name, &ent, 64); 640 nubus_get_rsrc_str(board->name, &ent,
641 sizeof(board->name));
637 pr_info(" name: %s\n", board->name); 642 pr_info(" name: %s\n", board->name);
638 break; 643 break;
639 case NUBUS_RESID_ICON: 644 case NUBUS_RESID_ICON:
diff --git a/drivers/nubus/proc.c b/drivers/nubus/proc.c
index 004a122ac0ff..fc20dbcd3b9a 100644
--- a/drivers/nubus/proc.c
+++ b/drivers/nubus/proc.c
@@ -73,10 +73,10 @@ static void nubus_proc_subdir(struct nubus_dev* dev,
73 73
74 /* Some of these are directories, others aren't */ 74 /* Some of these are directories, others aren't */
75 while (nubus_readdir(dir, &ent) != -1) { 75 while (nubus_readdir(dir, &ent) != -1) {
76 char name[8]; 76 char name[9];
77 struct proc_dir_entry* e; 77 struct proc_dir_entry* e;
78 78
79 sprintf(name, "%x", ent.type); 79 snprintf(name, sizeof(name), "%x", ent.type);
80 e = proc_create(name, S_IFREG | S_IRUGO | S_IWUSR, parent, 80 e = proc_create(name, S_IFREG | S_IRUGO | S_IWUSR, parent,
81 &nubus_proc_subdir_fops); 81 &nubus_proc_subdir_fops);
82 if (!e) 82 if (!e)
@@ -95,11 +95,11 @@ static void nubus_proc_populate(struct nubus_dev* dev,
95 /* We know these are all directories (board resource + one or 95 /* We know these are all directories (board resource + one or
96 more functional resources) */ 96 more functional resources) */
97 while (nubus_readdir(root, &ent) != -1) { 97 while (nubus_readdir(root, &ent) != -1) {
98 char name[8]; 98 char name[9];
99 struct proc_dir_entry* e; 99 struct proc_dir_entry* e;
100 struct nubus_dir dir; 100 struct nubus_dir dir;
101 101
102 sprintf(name, "%x", ent.type); 102 snprintf(name, sizeof(name), "%x", ent.type);
103 e = proc_mkdir(name, parent); 103 e = proc_mkdir(name, parent);
104 if (!e) return; 104 if (!e) return;
105 105
@@ -119,7 +119,7 @@ int nubus_proc_attach_device(struct nubus_dev *dev)
119{ 119{
120 struct proc_dir_entry *e; 120 struct proc_dir_entry *e;
121 struct nubus_dir root; 121 struct nubus_dir root;
122 char name[8]; 122 char name[9];
123 123
124 if (dev == NULL) { 124 if (dev == NULL) {
125 printk(KERN_ERR 125 printk(KERN_ERR
@@ -135,7 +135,7 @@ int nubus_proc_attach_device(struct nubus_dev *dev)
135 } 135 }
136 136
137 /* Create a directory */ 137 /* Create a directory */
138 sprintf(name, "%x", dev->board->slot); 138 snprintf(name, sizeof(name), "%x", dev->board->slot);
139 e = dev->procdir = proc_mkdir(name, proc_bus_nubus_dir); 139 e = dev->procdir = proc_mkdir(name, proc_bus_nubus_dir);
140 if (!e) 140 if (!e)
141 return -ENOMEM; 141 return -ENOMEM;