aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/isdn/isdnloop/isdnloop.c
diff options
context:
space:
mode:
authorDan Carpenter <dan.carpenter@oracle.com>2014-04-08 05:23:09 -0400
committerDavid S. Miller <davem@davemloft.net>2014-04-08 12:41:13 -0400
commit7563487cbf865284dcd35e9ef5a95380da046737 (patch)
tree2310eddf3a9aa21aa7b2a0fb1e5d9fec83c1b2a5 /drivers/isdn/isdnloop/isdnloop.c
parent6859e7df6d9045a461412777e63bd8cef12f9705 (diff)
isdnloop: several buffer overflows
There are three buffer overflows addressed in this patch. 1) In isdnloop_fake_err() we add an 'E' to a 60 character string and then copy it into a 60 character buffer. I have made the destination buffer 64 characters and I'm changed the sprintf() to a snprintf(). 2) In isdnloop_parse_cmd(), p points to a 6 characters into a 60 character buffer so we have 54 characters. The ->eazlist[] is 11 characters long. I have modified the code to return if the source buffer is too long. 3) In isdnloop_command() the cbuf[] array was 60 characters long but the max length of the string then can be up to 79 characters. I made the cbuf array 80 characters long and changed the sprintf() to snprintf(). I also removed the temporary "dial" buffer and changed it to use "p" directly. Unfortunately, we pass the "cbuf" string from isdnloop_command() to isdnloop_writecmd() which truncates anything over 60 characters to make it fit in card->omsg[]. (It can accept values up to 255 characters so long as there is a '\n' character every 60 characters). For now I have just fixed the memory corruption bug and left the other problems in this driver alone. Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/isdn/isdnloop/isdnloop.c')
-rw-r--r--drivers/isdn/isdnloop/isdnloop.c17
1 files changed, 9 insertions, 8 deletions
diff --git a/drivers/isdn/isdnloop/isdnloop.c b/drivers/isdn/isdnloop/isdnloop.c
index e1f8748ff25d..5a4da94aefb0 100644
--- a/drivers/isdn/isdnloop/isdnloop.c
+++ b/drivers/isdn/isdnloop/isdnloop.c
@@ -518,9 +518,9 @@ static isdnloop_stat isdnloop_cmd_table[] =
518static void 518static void
519isdnloop_fake_err(isdnloop_card *card) 519isdnloop_fake_err(isdnloop_card *card)
520{ 520{
521 char buf[60]; 521 char buf[64];
522 522
523 sprintf(buf, "E%s", card->omsg); 523 snprintf(buf, sizeof(buf), "E%s", card->omsg);
524 isdnloop_fake(card, buf, -1); 524 isdnloop_fake(card, buf, -1);
525 isdnloop_fake(card, "NAK", -1); 525 isdnloop_fake(card, "NAK", -1);
526} 526}
@@ -903,6 +903,8 @@ isdnloop_parse_cmd(isdnloop_card *card)
903 case 7: 903 case 7:
904 /* 0x;EAZ */ 904 /* 0x;EAZ */
905 p += 3; 905 p += 3;
906 if (strlen(p) >= sizeof(card->eazlist[0]))
907 break;
906 strcpy(card->eazlist[ch - 1], p); 908 strcpy(card->eazlist[ch - 1], p);
907 break; 909 break;
908 case 8: 910 case 8:
@@ -1133,7 +1135,7 @@ isdnloop_command(isdn_ctrl *c, isdnloop_card *card)
1133{ 1135{
1134 ulong a; 1136 ulong a;
1135 int i; 1137 int i;
1136 char cbuf[60]; 1138 char cbuf[80];
1137 isdn_ctrl cmd; 1139 isdn_ctrl cmd;
1138 isdnloop_cdef cdef; 1140 isdnloop_cdef cdef;
1139 1141
@@ -1198,7 +1200,6 @@ isdnloop_command(isdn_ctrl *c, isdnloop_card *card)
1198 break; 1200 break;
1199 if ((c->arg & 255) < ISDNLOOP_BCH) { 1201 if ((c->arg & 255) < ISDNLOOP_BCH) {
1200 char *p; 1202 char *p;
1201 char dial[50];
1202 char dcode[4]; 1203 char dcode[4];
1203 1204
1204 a = c->arg; 1205 a = c->arg;
@@ -1210,10 +1211,10 @@ isdnloop_command(isdn_ctrl *c, isdnloop_card *card)
1210 } else 1211 } else
1211 /* Normal Dial */ 1212 /* Normal Dial */
1212 strcpy(dcode, "CAL"); 1213 strcpy(dcode, "CAL");
1213 strcpy(dial, p); 1214 snprintf(cbuf, sizeof(cbuf),
1214 sprintf(cbuf, "%02d;D%s_R%s,%02d,%02d,%s\n", (int) (a + 1), 1215 "%02d;D%s_R%s,%02d,%02d,%s\n", (int) (a + 1),
1215 dcode, dial, c->parm.setup.si1, 1216 dcode, p, c->parm.setup.si1,
1216 c->parm.setup.si2, c->parm.setup.eazmsn); 1217 c->parm.setup.si2, c->parm.setup.eazmsn);
1217 i = isdnloop_writecmd(cbuf, strlen(cbuf), 0, card); 1218 i = isdnloop_writecmd(cbuf, strlen(cbuf), 0, card);
1218 } 1219 }
1219 break; 1220 break;