diff options
author | Dan Carpenter <dan.carpenter@oracle.com> | 2014-04-16 07:25:16 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2014-04-16 15:24:15 -0400 |
commit | b7a314054eb55e3745a9409beaa5d8be5cd2d273 (patch) | |
tree | eaae9916a4c66d1f81c31d5b876dd04fffea6260 | |
parent | 74462f0d4a734274a04dbbe58099134cbe7a5522 (diff) |
isdn: icn: buffer overflow in icn_command()
This buffer over was detected using static analysis:
drivers/isdn/icn/icn.c:1325 icn_command()
error: format string overflow. buf_size: 60 length: 98
The calculation for the length of the string is off because it assumes
that the dial[] buffer holds a 50 character string, but actually it is
at most 31 characters and NUL. I have removed the dial[] buffer because
it isn't needed.
The maximum length of the string is actually 79 characters and a NUL. I
have made the cbuf[] array large enough to hold it and changed the
sprintf() to an snprintf() as a further safety enhancement.
Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | drivers/isdn/icn/icn.c | 11 |
1 files changed, 5 insertions, 6 deletions
diff --git a/drivers/isdn/icn/icn.c b/drivers/isdn/icn/icn.c index 53d487f0c79d..6a7447c304ac 100644 --- a/drivers/isdn/icn/icn.c +++ b/drivers/isdn/icn/icn.c | |||
@@ -1155,7 +1155,7 @@ icn_command(isdn_ctrl *c, icn_card *card) | |||
1155 | ulong a; | 1155 | ulong a; |
1156 | ulong flags; | 1156 | ulong flags; |
1157 | int i; | 1157 | int i; |
1158 | char cbuf[60]; | 1158 | char cbuf[80]; |
1159 | isdn_ctrl cmd; | 1159 | isdn_ctrl cmd; |
1160 | icn_cdef cdef; | 1160 | icn_cdef cdef; |
1161 | char __user *arg; | 1161 | char __user *arg; |
@@ -1309,7 +1309,6 @@ icn_command(isdn_ctrl *c, icn_card *card) | |||
1309 | break; | 1309 | break; |
1310 | if ((c->arg & 255) < ICN_BCH) { | 1310 | if ((c->arg & 255) < ICN_BCH) { |
1311 | char *p; | 1311 | char *p; |
1312 | char dial[50]; | ||
1313 | char dcode[4]; | 1312 | char dcode[4]; |
1314 | 1313 | ||
1315 | a = c->arg; | 1314 | a = c->arg; |
@@ -1321,10 +1320,10 @@ icn_command(isdn_ctrl *c, icn_card *card) | |||
1321 | } else | 1320 | } else |
1322 | /* Normal Dial */ | 1321 | /* Normal Dial */ |
1323 | strcpy(dcode, "CAL"); | 1322 | strcpy(dcode, "CAL"); |
1324 | strcpy(dial, p); | 1323 | snprintf(cbuf, sizeof(cbuf), |
1325 | sprintf(cbuf, "%02d;D%s_R%s,%02d,%02d,%s\n", (int) (a + 1), | 1324 | "%02d;D%s_R%s,%02d,%02d,%s\n", (int) (a + 1), |
1326 | dcode, dial, c->parm.setup.si1, | 1325 | dcode, p, c->parm.setup.si1, |
1327 | c->parm.setup.si2, c->parm.setup.eazmsn); | 1326 | c->parm.setup.si2, c->parm.setup.eazmsn); |
1328 | i = icn_writecmd(cbuf, strlen(cbuf), 0, card); | 1327 | i = icn_writecmd(cbuf, strlen(cbuf), 0, card); |
1329 | } | 1328 | } |
1330 | break; | 1329 | break; |