Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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
Loading
Loading
Loading
Loading
+17 −12
Original line number Diff line number Diff line
@@ -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:
+6 −6
Original line number Diff line number Diff line
@@ -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;
+4 −6
Original line number Diff line number Diff line
@@ -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 */