Commit 7563487c authored by Dan Carpenter's avatar Dan Carpenter Committed by David S. Miller

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: default avatarDan Carpenter <dan.carpenter@oracle.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 6859e7df
...@@ -518,9 +518,9 @@ static isdnloop_stat isdnloop_cmd_table[] = ...@@ -518,9 +518,9 @@ static isdnloop_stat isdnloop_cmd_table[] =
static void static void
isdnloop_fake_err(isdnloop_card *card) isdnloop_fake_err(isdnloop_card *card)
{ {
char buf[60]; char buf[64];
sprintf(buf, "E%s", card->omsg); snprintf(buf, sizeof(buf), "E%s", card->omsg);
isdnloop_fake(card, buf, -1); isdnloop_fake(card, buf, -1);
isdnloop_fake(card, "NAK", -1); isdnloop_fake(card, "NAK", -1);
} }
...@@ -903,6 +903,8 @@ isdnloop_parse_cmd(isdnloop_card *card) ...@@ -903,6 +903,8 @@ isdnloop_parse_cmd(isdnloop_card *card)
case 7: case 7:
/* 0x;EAZ */ /* 0x;EAZ */
p += 3; p += 3;
if (strlen(p) >= sizeof(card->eazlist[0]))
break;
strcpy(card->eazlist[ch - 1], p); strcpy(card->eazlist[ch - 1], p);
break; break;
case 8: case 8:
...@@ -1133,7 +1135,7 @@ isdnloop_command(isdn_ctrl *c, isdnloop_card *card) ...@@ -1133,7 +1135,7 @@ isdnloop_command(isdn_ctrl *c, isdnloop_card *card)
{ {
ulong a; ulong a;
int i; int i;
char cbuf[60]; char cbuf[80];
isdn_ctrl cmd; isdn_ctrl cmd;
isdnloop_cdef cdef; isdnloop_cdef cdef;
...@@ -1198,7 +1200,6 @@ isdnloop_command(isdn_ctrl *c, isdnloop_card *card) ...@@ -1198,7 +1200,6 @@ isdnloop_command(isdn_ctrl *c, isdnloop_card *card)
break; break;
if ((c->arg & 255) < ISDNLOOP_BCH) { if ((c->arg & 255) < ISDNLOOP_BCH) {
char *p; char *p;
char dial[50];
char dcode[4]; char dcode[4];
a = c->arg; a = c->arg;
...@@ -1210,9 +1211,9 @@ isdnloop_command(isdn_ctrl *c, isdnloop_card *card) ...@@ -1210,9 +1211,9 @@ isdnloop_command(isdn_ctrl *c, isdnloop_card *card)
} else } else
/* Normal Dial */ /* Normal Dial */
strcpy(dcode, "CAL"); strcpy(dcode, "CAL");
strcpy(dial, p); snprintf(cbuf, sizeof(cbuf),
sprintf(cbuf, "%02d;D%s_R%s,%02d,%02d,%s\n", (int) (a + 1), "%02d;D%s_R%s,%02d,%02d,%s\n", (int) (a + 1),
dcode, dial, c->parm.setup.si1, dcode, p, c->parm.setup.si1,
c->parm.setup.si2, c->parm.setup.eazmsn); c->parm.setup.si2, c->parm.setup.eazmsn);
i = isdnloop_writecmd(cbuf, strlen(cbuf), 0, card); i = isdnloop_writecmd(cbuf, strlen(cbuf), 0, card);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment