Commit f35ba45c authored by Takashi Iwai's avatar Takashi Iwai Committed by Kalle Valo

ipw2x00: Use scnprintf() for avoiding potential buffer overflow

Since snprintf() returns the would-be-output size instead of the
actual output size, the succeeding calls may go beyond the given
buffer limit.  Fix it by replacing with scnprintf().

Cc: Stanislav Yakovlev <stas.yakovlev@gmail.com>
Signed-off-by: default avatarTakashi Iwai <tiwai@suse.de>
Signed-off-by: default avatarKalle Valo <kvalo@codeaurora.org>
parent d3f8c708
...@@ -629,30 +629,30 @@ static char *snprint_line(char *buf, size_t count, ...@@ -629,30 +629,30 @@ static char *snprint_line(char *buf, size_t count,
int out, i, j, l; int out, i, j, l;
char c; char c;
out = snprintf(buf, count, "%08X", ofs); out = scnprintf(buf, count, "%08X", ofs);
for (l = 0, i = 0; i < 2; i++) { for (l = 0, i = 0; i < 2; i++) {
out += snprintf(buf + out, count - out, " "); out += scnprintf(buf + out, count - out, " ");
for (j = 0; j < 8 && l < len; j++, l++) for (j = 0; j < 8 && l < len; j++, l++)
out += snprintf(buf + out, count - out, "%02X ", out += scnprintf(buf + out, count - out, "%02X ",
data[(i * 8 + j)]); data[(i * 8 + j)]);
for (; j < 8; j++) for (; j < 8; j++)
out += snprintf(buf + out, count - out, " "); out += scnprintf(buf + out, count - out, " ");
} }
out += snprintf(buf + out, count - out, " "); out += scnprintf(buf + out, count - out, " ");
for (l = 0, i = 0; i < 2; i++) { for (l = 0, i = 0; i < 2; i++) {
out += snprintf(buf + out, count - out, " "); out += scnprintf(buf + out, count - out, " ");
for (j = 0; j < 8 && l < len; j++, l++) { for (j = 0; j < 8 && l < len; j++, l++) {
c = data[(i * 8 + j)]; c = data[(i * 8 + j)];
if (!isascii(c) || !isprint(c)) if (!isascii(c) || !isprint(c))
c = '.'; c = '.';
out += snprintf(buf + out, count - out, "%c", c); out += scnprintf(buf + out, count - out, "%c", c);
} }
for (; j < 8; j++) for (; j < 8; j++)
out += snprintf(buf + out, count - out, " "); out += scnprintf(buf + out, count - out, " ");
} }
return buf; return buf;
......
...@@ -223,30 +223,30 @@ static int snprint_line(char *buf, size_t count, ...@@ -223,30 +223,30 @@ static int snprint_line(char *buf, size_t count,
int out, i, j, l; int out, i, j, l;
char c; char c;
out = snprintf(buf, count, "%08X", ofs); out = scnprintf(buf, count, "%08X", ofs);
for (l = 0, i = 0; i < 2; i++) { for (l = 0, i = 0; i < 2; i++) {
out += snprintf(buf + out, count - out, " "); out += scnprintf(buf + out, count - out, " ");
for (j = 0; j < 8 && l < len; j++, l++) for (j = 0; j < 8 && l < len; j++, l++)
out += snprintf(buf + out, count - out, "%02X ", out += scnprintf(buf + out, count - out, "%02X ",
data[(i * 8 + j)]); data[(i * 8 + j)]);
for (; j < 8; j++) for (; j < 8; j++)
out += snprintf(buf + out, count - out, " "); out += scnprintf(buf + out, count - out, " ");
} }
out += snprintf(buf + out, count - out, " "); out += scnprintf(buf + out, count - out, " ");
for (l = 0, i = 0; i < 2; i++) { for (l = 0, i = 0; i < 2; i++) {
out += snprintf(buf + out, count - out, " "); out += scnprintf(buf + out, count - out, " ");
for (j = 0; j < 8 && l < len; j++, l++) { for (j = 0; j < 8 && l < len; j++, l++) {
c = data[(i * 8 + j)]; c = data[(i * 8 + j)];
if (!isascii(c) || !isprint(c)) if (!isascii(c) || !isprint(c))
c = '.'; c = '.';
out += snprintf(buf + out, count - out, "%c", c); out += scnprintf(buf + out, count - out, "%c", c);
} }
for (; j < 8; j++) for (; j < 8; j++)
out += snprintf(buf + out, count - out, " "); out += scnprintf(buf + out, count - out, " ");
} }
return out; return out;
...@@ -1279,12 +1279,12 @@ static ssize_t show_event_log(struct device *d, ...@@ -1279,12 +1279,12 @@ static ssize_t show_event_log(struct device *d,
log_len = log_size / sizeof(*log); log_len = log_size / sizeof(*log);
ipw_capture_event_log(priv, log_len, log); ipw_capture_event_log(priv, log_len, log);
len += snprintf(buf + len, PAGE_SIZE - len, "%08X", log_len); len += scnprintf(buf + len, PAGE_SIZE - len, "%08X", log_len);
for (i = 0; i < log_len; i++) for (i = 0; i < log_len; i++)
len += snprintf(buf + len, PAGE_SIZE - len, len += scnprintf(buf + len, PAGE_SIZE - len,
"\n%08X%08X%08X", "\n%08X%08X%08X",
log[i].time, log[i].event, log[i].data); log[i].time, log[i].event, log[i].data);
len += snprintf(buf + len, PAGE_SIZE - len, "\n"); len += scnprintf(buf + len, PAGE_SIZE - len, "\n");
kfree(log); kfree(log);
return len; return len;
} }
...@@ -1298,13 +1298,13 @@ static ssize_t show_error(struct device *d, ...@@ -1298,13 +1298,13 @@ static ssize_t show_error(struct device *d,
u32 len = 0, i; u32 len = 0, i;
if (!priv->error) if (!priv->error)
return 0; return 0;
len += snprintf(buf + len, PAGE_SIZE - len, len += scnprintf(buf + len, PAGE_SIZE - len,
"%08lX%08X%08X%08X", "%08lX%08X%08X%08X",
priv->error->jiffies, priv->error->jiffies,
priv->error->status, priv->error->status,
priv->error->config, priv->error->elem_len); priv->error->config, priv->error->elem_len);
for (i = 0; i < priv->error->elem_len; i++) for (i = 0; i < priv->error->elem_len; i++)
len += snprintf(buf + len, PAGE_SIZE - len, len += scnprintf(buf + len, PAGE_SIZE - len,
"\n%08X%08X%08X%08X%08X%08X%08X", "\n%08X%08X%08X%08X%08X%08X%08X",
priv->error->elem[i].time, priv->error->elem[i].time,
priv->error->elem[i].desc, priv->error->elem[i].desc,
...@@ -1314,15 +1314,15 @@ static ssize_t show_error(struct device *d, ...@@ -1314,15 +1314,15 @@ static ssize_t show_error(struct device *d,
priv->error->elem[i].link2, priv->error->elem[i].link2,
priv->error->elem[i].data); priv->error->elem[i].data);
len += snprintf(buf + len, PAGE_SIZE - len, len += scnprintf(buf + len, PAGE_SIZE - len,
"\n%08X", priv->error->log_len); "\n%08X", priv->error->log_len);
for (i = 0; i < priv->error->log_len; i++) for (i = 0; i < priv->error->log_len; i++)
len += snprintf(buf + len, PAGE_SIZE - len, len += scnprintf(buf + len, PAGE_SIZE - len,
"\n%08X%08X%08X", "\n%08X%08X%08X",
priv->error->log[i].time, priv->error->log[i].time,
priv->error->log[i].event, priv->error->log[i].event,
priv->error->log[i].data); priv->error->log[i].data);
len += snprintf(buf + len, PAGE_SIZE - len, "\n"); len += scnprintf(buf + len, PAGE_SIZE - len, "\n");
return len; return len;
} }
...@@ -1350,7 +1350,7 @@ static ssize_t show_cmd_log(struct device *d, ...@@ -1350,7 +1350,7 @@ static ssize_t show_cmd_log(struct device *d,
(i != priv->cmdlog_pos) && (len < PAGE_SIZE); (i != priv->cmdlog_pos) && (len < PAGE_SIZE);
i = (i + 1) % priv->cmdlog_len) { i = (i + 1) % priv->cmdlog_len) {
len += len +=
snprintf(buf + len, PAGE_SIZE - len, scnprintf(buf + len, PAGE_SIZE - len,
"\n%08lX%08X%08X%08X\n", priv->cmdlog[i].jiffies, "\n%08lX%08X%08X%08X\n", priv->cmdlog[i].jiffies,
priv->cmdlog[i].retcode, priv->cmdlog[i].cmd.cmd, priv->cmdlog[i].retcode, priv->cmdlog[i].cmd.cmd,
priv->cmdlog[i].cmd.len); priv->cmdlog[i].cmd.len);
...@@ -1358,9 +1358,9 @@ static ssize_t show_cmd_log(struct device *d, ...@@ -1358,9 +1358,9 @@ static ssize_t show_cmd_log(struct device *d,
snprintk_buf(buf + len, PAGE_SIZE - len, snprintk_buf(buf + len, PAGE_SIZE - len,
(u8 *) priv->cmdlog[i].cmd.param, (u8 *) priv->cmdlog[i].cmd.param,
priv->cmdlog[i].cmd.len); priv->cmdlog[i].cmd.len);
len += snprintf(buf + len, PAGE_SIZE - len, "\n"); len += scnprintf(buf + len, PAGE_SIZE - len, "\n");
} }
len += snprintf(buf + len, PAGE_SIZE - len, "\n"); len += scnprintf(buf + len, PAGE_SIZE - len, "\n");
return len; return len;
} }
...@@ -9608,24 +9608,24 @@ static int ipw_wx_get_powermode(struct net_device *dev, ...@@ -9608,24 +9608,24 @@ static int ipw_wx_get_powermode(struct net_device *dev,
int level = IPW_POWER_LEVEL(priv->power_mode); int level = IPW_POWER_LEVEL(priv->power_mode);
char *p = extra; char *p = extra;
p += snprintf(p, MAX_WX_STRING, "Power save level: %d ", level); p += scnprintf(p, MAX_WX_STRING, "Power save level: %d ", level);
switch (level) { switch (level) {
case IPW_POWER_AC: case IPW_POWER_AC:
p += snprintf(p, MAX_WX_STRING - (p - extra), "(AC)"); p += scnprintf(p, MAX_WX_STRING - (p - extra), "(AC)");
break; break;
case IPW_POWER_BATTERY: case IPW_POWER_BATTERY:
p += snprintf(p, MAX_WX_STRING - (p - extra), "(BATTERY)"); p += scnprintf(p, MAX_WX_STRING - (p - extra), "(BATTERY)");
break; break;
default: default:
p += snprintf(p, MAX_WX_STRING - (p - extra), p += scnprintf(p, MAX_WX_STRING - (p - extra),
"(Timeout %dms, Period %dms)", "(Timeout %dms, Period %dms)",
timeout_duration[level - 1] / 1000, timeout_duration[level - 1] / 1000,
period_duration[level - 1] / 1000); period_duration[level - 1] / 1000);
} }
if (!(priv->power_mode & IPW_POWER_ENABLED)) if (!(priv->power_mode & IPW_POWER_ENABLED))
p += snprintf(p, MAX_WX_STRING - (p - extra), " OFF"); p += scnprintf(p, MAX_WX_STRING - (p - extra), " OFF");
wrqu->data.length = p - extra + 1; wrqu->data.length = p - extra + 1;
......
...@@ -1156,7 +1156,7 @@ static int libipw_parse_info_param(struct libipw_info_element ...@@ -1156,7 +1156,7 @@ static int libipw_parse_info_param(struct libipw_info_element
for (i = 0; i < network->rates_len; i++) { for (i = 0; i < network->rates_len; i++) {
network->rates[i] = info_element->data[i]; network->rates[i] = info_element->data[i];
#ifdef CONFIG_LIBIPW_DEBUG #ifdef CONFIG_LIBIPW_DEBUG
p += snprintf(p, sizeof(rates_str) - p += scnprintf(p, sizeof(rates_str) -
(p - rates_str), "%02X ", (p - rates_str), "%02X ",
network->rates[i]); network->rates[i]);
#endif #endif
...@@ -1183,7 +1183,7 @@ static int libipw_parse_info_param(struct libipw_info_element ...@@ -1183,7 +1183,7 @@ static int libipw_parse_info_param(struct libipw_info_element
for (i = 0; i < network->rates_ex_len; i++) { for (i = 0; i < network->rates_ex_len; i++) {
network->rates_ex[i] = info_element->data[i]; network->rates_ex[i] = info_element->data[i];
#ifdef CONFIG_LIBIPW_DEBUG #ifdef CONFIG_LIBIPW_DEBUG
p += snprintf(p, sizeof(rates_str) - p += scnprintf(p, sizeof(rates_str) -
(p - rates_str), "%02X ", (p - rates_str), "%02X ",
network->rates_ex[i]); network->rates_ex[i]);
#endif #endif
......
...@@ -213,7 +213,7 @@ static char *libipw_translate_scan(struct libipw_device *ieee, ...@@ -213,7 +213,7 @@ static char *libipw_translate_scan(struct libipw_device *ieee,
* for given network. */ * for given network. */
iwe.cmd = IWEVCUSTOM; iwe.cmd = IWEVCUSTOM;
p = custom; p = custom;
p += snprintf(p, MAX_CUSTOM_LEN - (p - custom), p += scnprintf(p, MAX_CUSTOM_LEN - (p - custom),
" Last beacon: %ums ago", " Last beacon: %ums ago",
elapsed_jiffies_msecs(network->last_scanned)); elapsed_jiffies_msecs(network->last_scanned));
iwe.u.data.length = p - custom; iwe.u.data.length = p - custom;
...@@ -223,18 +223,18 @@ static char *libipw_translate_scan(struct libipw_device *ieee, ...@@ -223,18 +223,18 @@ static char *libipw_translate_scan(struct libipw_device *ieee,
/* Add spectrum management information */ /* Add spectrum management information */
iwe.cmd = -1; iwe.cmd = -1;
p = custom; p = custom;
p += snprintf(p, MAX_CUSTOM_LEN - (p - custom), " Channel flags: "); p += scnprintf(p, MAX_CUSTOM_LEN - (p - custom), " Channel flags: ");
if (libipw_get_channel_flags(ieee, network->channel) & if (libipw_get_channel_flags(ieee, network->channel) &
LIBIPW_CH_INVALID) { LIBIPW_CH_INVALID) {
iwe.cmd = IWEVCUSTOM; iwe.cmd = IWEVCUSTOM;
p += snprintf(p, MAX_CUSTOM_LEN - (p - custom), "INVALID "); p += scnprintf(p, MAX_CUSTOM_LEN - (p - custom), "INVALID ");
} }
if (libipw_get_channel_flags(ieee, network->channel) & if (libipw_get_channel_flags(ieee, network->channel) &
LIBIPW_CH_RADAR_DETECT) { LIBIPW_CH_RADAR_DETECT) {
iwe.cmd = IWEVCUSTOM; iwe.cmd = IWEVCUSTOM;
p += snprintf(p, MAX_CUSTOM_LEN - (p - custom), "DFS "); p += scnprintf(p, MAX_CUSTOM_LEN - (p - custom), "DFS ");
} }
if (iwe.cmd == IWEVCUSTOM) { if (iwe.cmd == IWEVCUSTOM) {
......
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