OSDN Git Service

ipw2x00: Use scnprintf() for avoiding potential buffer overflow
authorTakashi Iwai <tiwai@suse.de>
Wed, 11 Mar 2020 08:47:12 +0000 (09:47 +0100)
committerKalle Valo <kvalo@codeaurora.org>
Thu, 12 Mar 2020 13:43:40 +0000 (15:43 +0200)
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: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
drivers/net/wireless/intel/ipw2x00/ipw2100.c
drivers/net/wireless/intel/ipw2x00/ipw2200.c
drivers/net/wireless/intel/ipw2x00/libipw_rx.c
drivers/net/wireless/intel/ipw2x00/libipw_wx.c

index 536cd72..7b78554 100644 (file)
@@ -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;
index 5ef6f87..60b5e08 100644 (file)
@@ -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;
 
index 0cb36d1..5a2a723 100644 (file)
@@ -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
index 3d558b4..a0cf78c 100644 (file)
@@ -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) {