isdnloop: several buffer overflows
[ Upstream commit 7563487cbf
]
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>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
64eb5b6911
commit
f9f80fa975
|
@ -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)
|
||||||
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)
|
||||||
{
|
{
|
||||||
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)
|
||||||
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)
|
||||||
} 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);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue