[PATCH] pccardctl 014 crash

Robert Varga nite at hq.alert.sk
Wed Jan 23 17:52:26 EST 2008


Hi,

invoking 'pccardctl ident' from pcmciatools-014 on a Compaq 8710p
running Linux 2.6.24-rc8 results in a crash:

nite at nitebug ~ $ /sbin/pccardctl ident
Socket 0:
  no product info available
Socket 1:
  product info: "RICOH", "Bay8Controller", "", ""
  manfid: 0x0000, 0x0000
Segmentation fault

this crash is caused by the following code (src/pccardctl.c:252):

        if (!pccardctl_get_one(socket_no, "func_id", &manf_id))
                printf("  function: %d (%s)\n", manf_id, fn[manf_id]);

which is quite obviously missing bounds checking when accessing fn array.
After adding the checks, the result seems more correct:

nite at nitebug ~/pcmciautils-014 $ ./pccardctl ident
Socket 0:
  no product info available
Socket 1:
  product info: "RICOH", "Bay8Controller", "", ""
  manfid: 0x0000, 0x0000
  function: 254 (???)

The attached patch fixes the issue, as well as a couple of other
warnings I saw during compilation. Please consider applying.

-- 
Bye,
Robert Varga

Reality continues to ruin my life. -- Calvin
-------------- next part --------------
diff -ur pcmciautils-014/src/pccardctl.c pcmciautils-014-patched/src/pccardctl.c
--- pcmciautils-014/src/pccardctl.c	2006-06-01 11:07:52.000000000 +0200
+++ pcmciautils-014-patched/src/pccardctl.c	2008-01-23 23:14:52.000000000 +0100
@@ -26,7 +26,7 @@
 
 #define MAX_SOCKET 8
 
-static char *fn[] = {
+static const char * const fn[] = {
 	"multifunction",
 	"memory",
 	"serial",
@@ -79,7 +79,7 @@
         char file[SYSFS_PATH_MAX];
         struct sysfs_attribute *attr;
 
-	if (!file)
+	if (!in_file)
 		return -EINVAL;
 
         snprintf(file, SYSFS_PATH_MAX, "/sys/class/pcmcia_socket/pcmcia_socket%lu/%s",
@@ -249,8 +249,12 @@
 		if (!pccardctl_get_one(socket_no, "card_id", &card_id))
 			printf("  manfid: 0x%04x, 0x%04x\n", manf_id, card_id);
 
-	if (!pccardctl_get_one(socket_no, "func_id", &manf_id))
-		printf("  function: %d (%s)\n", manf_id, fn[manf_id]);
+	if (!pccardctl_get_one(socket_no, "func_id", &manf_id)) {
+		const char *s = "???";
+		if (manf_id < sizeof(fn)/sizeof(*fn))
+			s = fn[manf_id];
+		printf("  function: %d (%s)\n", manf_id, s);
+	}
 
 
 	return 0;
diff -ur pcmciautils-014/src/pcmcia-check-broken-cis.c pcmciautils-014-patched/src/pcmcia-check-broken-cis.c
--- pcmciautils-014/src/pcmcia-check-broken-cis.c	2006-06-01 11:07:52.000000000 +0200
+++ pcmciautils-014-patched/src/pcmcia-check-broken-cis.c	2008-01-23 23:11:26.000000000 +0100
@@ -42,12 +42,12 @@
 #define NEEDS_CIS_ENTRY(_code, _ofs, _info, _cisfile) \
 { .code = _code, .ofs = _ofs, .info = _info, .cisfile = _cisfile, }
 
-static struct needs_cis cis_table[] = {
+static const struct needs_cis cis_table[] = {
 	/* "D-Link DE-650 Ethernet" */
 	NEEDS_CIS_ENTRY(0x40, 0x0009, "D-Link PC Ethernet Card", "D-Link.cis"),
 	/* "Linksys Ethernet E-CARD PC Ethernet Card */
 	NEEDS_CIS_ENTRY(0x40, 0x0009, "E-CARD PC Ethernet Card", "E-CARD.cis"),
-	{ },
+	{ 0, 0, NULL, NULL, },
 };
 
 int device_has_driver() {
@@ -161,7 +161,7 @@
 	int ret;
 	char *socket;
 	unsigned int socket_no;
-	struct needs_cis * entry = NULL;
+	const struct needs_cis * entry = NULL;
 	tuple_t tuple;
 	unsigned char buf[256];
 	int opt;
diff -ur pcmciautils-014/src/startup.c pcmciautils-014-patched/src/startup.c
--- pcmciautils-014/src/startup.c	2006-06-01 11:07:52.000000000 +0200
+++ pcmciautils-014-patched/src/startup.c	2008-01-23 23:09:26.000000000 +0100
@@ -93,7 +93,7 @@
 	if (!attr)
 		return -ENODEV;
 
-	dprintf("open, len %d\n", len);
+	dprintf("open, len %zu\n", len);
 
 	ret = sysfs_write_attribute(attr, content, len);
 
@@ -148,7 +148,7 @@
 	if (!attr)
 		return -ENODEV;
 
-	dprintf("open, len %d\n", len);
+	dprintf("open, len %zu\n", len);
 
 	ret = sysfs_read_attribute(attr);
 	if (ret) {


More information about the linux-pcmcia mailing list