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

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
Loading
Loading
Loading
Loading
+8 −8
Original line number Diff line number Diff line
@@ -629,30 +629,30 @@ static char *snprint_line(char *buf, size_t count,
	int out, i, j, l;
	char c;

	out = snprintf(buf, count, "%08X", ofs);
	out = scnprintf(buf, count, "%08X", ofs);

	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++)
			out += snprintf(buf + out, count - out, "%02X ",
			out += scnprintf(buf + out, count - out, "%02X ",
					data[(i * 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++) {
		out += snprintf(buf + out, count - out, " ");
		out += scnprintf(buf + out, count - out, " ");
		for (j = 0; j < 8 && l < len; j++, l++) {
			c = data[(i * 8 + j)];
			if (!isascii(c) || !isprint(c))
				c = '.';

			out += snprintf(buf + out, count - out, "%c", c);
			out += scnprintf(buf + out, count - out, "%c", c);
		}

		for (; j < 8; j++)
			out += snprintf(buf + out, count - out, " ");
			out += scnprintf(buf + out, count - out, " ");
	}

	return buf;
+24 −24
Original line number Diff line number Diff line
@@ -223,30 +223,30 @@ static int snprint_line(char *buf, size_t count,
	int out, i, j, l;
	char c;

	out = snprintf(buf, count, "%08X", ofs);
	out = scnprintf(buf, count, "%08X", ofs);

	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++)
			out += snprintf(buf + out, count - out, "%02X ",
			out += scnprintf(buf + out, count - out, "%02X ",
					data[(i * 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++) {
		out += snprintf(buf + out, count - out, " ");
		out += scnprintf(buf + out, count - out, " ");
		for (j = 0; j < 8 && l < len; j++, l++) {
			c = data[(i * 8 + j)];
			if (!isascii(c) || !isprint(c))
				c = '.';

			out += snprintf(buf + out, count - out, "%c", c);
			out += scnprintf(buf + out, count - out, "%c", c);
		}

		for (; j < 8; j++)
			out += snprintf(buf + out, count - out, " ");
			out += scnprintf(buf + out, count - out, " ");
	}

	return out;
@@ -1279,12 +1279,12 @@ static ssize_t show_event_log(struct device *d,
	log_len = log_size / sizeof(*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++)
		len += snprintf(buf + len, PAGE_SIZE - len,
		len += scnprintf(buf + len, PAGE_SIZE - len,
				"\n%08X%08X%08X",
				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);
	return len;
}
@@ -1298,13 +1298,13 @@ static ssize_t show_error(struct device *d,
	u32 len = 0, i;
	if (!priv->error)
		return 0;
	len += snprintf(buf + len, PAGE_SIZE - len,
	len += scnprintf(buf + len, PAGE_SIZE - len,
			"%08lX%08X%08X%08X",
			priv->error->jiffies,
			priv->error->status,
			priv->error->config, priv->error->elem_len);
	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",
				priv->error->elem[i].time,
				priv->error->elem[i].desc,
@@ -1314,15 +1314,15 @@ static ssize_t show_error(struct device *d,
				priv->error->elem[i].link2,
				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);
	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",
				priv->error->log[i].time,
				priv->error->log[i].event,
				priv->error->log[i].data);
	len += snprintf(buf + len, PAGE_SIZE - len, "\n");
	len += scnprintf(buf + len, PAGE_SIZE - len, "\n");
	return len;
}

@@ -1350,7 +1350,7 @@ static ssize_t show_cmd_log(struct device *d,
	     (i != priv->cmdlog_pos) && (len < PAGE_SIZE);
	     i = (i + 1) % priv->cmdlog_len) {
		len +=
		    snprintf(buf + len, PAGE_SIZE - len,
		    scnprintf(buf + len, PAGE_SIZE - len,
			     "\n%08lX%08X%08X%08X\n", priv->cmdlog[i].jiffies,
			     priv->cmdlog[i].retcode, priv->cmdlog[i].cmd.cmd,
			     priv->cmdlog[i].cmd.len);
@@ -1358,9 +1358,9 @@ static ssize_t show_cmd_log(struct device *d,
		    snprintk_buf(buf + len, PAGE_SIZE - len,
				 (u8 *) priv->cmdlog[i].cmd.param,
				 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;
}

@@ -9608,24 +9608,24 @@ static int ipw_wx_get_powermode(struct net_device *dev,
	int level = IPW_POWER_LEVEL(priv->power_mode);
	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) {
	case IPW_POWER_AC:
		p += snprintf(p, MAX_WX_STRING - (p - extra), "(AC)");
		p += scnprintf(p, MAX_WX_STRING - (p - extra), "(AC)");
		break;
	case IPW_POWER_BATTERY:
		p += snprintf(p, MAX_WX_STRING - (p - extra), "(BATTERY)");
		p += scnprintf(p, MAX_WX_STRING - (p - extra), "(BATTERY)");
		break;
	default:
		p += snprintf(p, MAX_WX_STRING - (p - extra),
		p += scnprintf(p, MAX_WX_STRING - (p - extra),
			      "(Timeout %dms, Period %dms)",
			      timeout_duration[level - 1] / 1000,
			      period_duration[level - 1] / 1000);
	}

	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;

+2 −2
Original line number Diff line number Diff line
@@ -1156,7 +1156,7 @@ static int libipw_parse_info_param(struct libipw_info_element
			for (i = 0; i < network->rates_len; i++) {
				network->rates[i] = info_element->data[i];
#ifdef CONFIG_LIBIPW_DEBUG
				p += snprintf(p, sizeof(rates_str) -
				p += scnprintf(p, sizeof(rates_str) -
					      (p - rates_str), "%02X ",
					      network->rates[i]);
#endif
@@ -1183,7 +1183,7 @@ static int libipw_parse_info_param(struct libipw_info_element
			for (i = 0; i < network->rates_ex_len; i++) {
				network->rates_ex[i] = info_element->data[i];
#ifdef CONFIG_LIBIPW_DEBUG
				p += snprintf(p, sizeof(rates_str) -
				p += scnprintf(p, sizeof(rates_str) -
					      (p - rates_str), "%02X ",
					      network->rates_ex[i]);
#endif
+4 −4
Original line number Diff line number Diff line
@@ -213,7 +213,7 @@ static char *libipw_translate_scan(struct libipw_device *ieee,
	 * for given network. */
	iwe.cmd = IWEVCUSTOM;
	p = custom;
	p += snprintf(p, MAX_CUSTOM_LEN - (p - custom),
	p += scnprintf(p, MAX_CUSTOM_LEN - (p - custom),
		      " Last beacon: %ums ago",
		      elapsed_jiffies_msecs(network->last_scanned));
	iwe.u.data.length = p - custom;
@@ -223,18 +223,18 @@ static char *libipw_translate_scan(struct libipw_device *ieee,
	/* Add spectrum management information */
	iwe.cmd = -1;
	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) &
	    LIBIPW_CH_INVALID) {
		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) &
	    LIBIPW_CH_RADAR_DETECT) {
		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) {