OSDN Git Service

tcp: warn if offset reach the maxlen limit when using snprintf
authorHangbin Liu <liuhangbin@gmail.com>
Wed, 20 Nov 2019 08:38:08 +0000 (16:38 +0800)
committerDavid S. Miller <davem@davemloft.net>
Thu, 21 Nov 2019 06:23:36 +0000 (22:23 -0800)
snprintf returns the number of chars that would be written, not number
of chars that were actually written. As such, 'offs' may get larger than
'tbl.maxlen', causing the 'tbl.maxlen - offs' being < 0, and since the
parameter is size_t, it would overflow.

Since using scnprintf may hide the limit error, while the buffer is still
enough now, let's just add a WARN_ON_ONCE in case it reach the limit
in future.

v2: Use WARN_ON_ONCE as Jiri and Eric suggested.

Suggested-by: Jiri Benc <jbenc@redhat.com>
Signed-off-by: Hangbin Liu <liuhangbin@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
net/ipv4/sysctl_net_ipv4.c
net/ipv4/tcp_cong.c
net/ipv4/tcp_ulp.c

index 59ded25..c9eaf92 100644 (file)
@@ -340,6 +340,10 @@ static int proc_tcp_fastopen_key(struct ctl_table *table, int write,
                                user_key[i * 4 + 1],
                                user_key[i * 4 + 2],
                                user_key[i * 4 + 3]);
+
+               if (WARN_ON_ONCE(off >= tbl.maxlen - 1))
+                       break;
+
                if (i + 1 < n_keys)
                        off += snprintf(tbl.data + off, tbl.maxlen - off, ",");
        }
index c445a81..3737ec0 100644 (file)
@@ -256,6 +256,9 @@ void tcp_get_available_congestion_control(char *buf, size_t maxlen)
                offs += snprintf(buf + offs, maxlen - offs,
                                 "%s%s",
                                 offs == 0 ? "" : " ", ca->name);
+
+               if (WARN_ON_ONCE(offs >= maxlen))
+                       break;
        }
        rcu_read_unlock();
 }
@@ -285,6 +288,9 @@ void tcp_get_allowed_congestion_control(char *buf, size_t maxlen)
                offs += snprintf(buf + offs, maxlen - offs,
                                 "%s%s",
                                 offs == 0 ? "" : " ", ca->name);
+
+               if (WARN_ON_ONCE(offs >= maxlen))
+                       break;
        }
        rcu_read_unlock();
 }
index 4849edb..12ab5db 100644 (file)
@@ -92,6 +92,9 @@ void tcp_get_available_ulp(char *buf, size_t maxlen)
                offs += snprintf(buf + offs, maxlen - offs,
                                 "%s%s",
                                 offs == 0 ? "" : " ", ulp_ops->name);
+
+               if (WARN_ON_ONCE(offs >= maxlen))
+                       break;
        }
        rcu_read_unlock();
 }