From 802fb6db9fdc82cc0e0f2e4315a24b2171e6ef4f Mon Sep 17 00:00:00 2001 From: Peter Seiderer Date: Wed, 19 Feb 2025 09:45:21 +0100 Subject: [PATCH 1/7] net: pktgen: replace ENOTSUPP with EOPNOTSUPP Replace ENOTSUPP with EOPNOTSUPP, fixes checkpatch hint WARNING: ENOTSUPP is not a SUSV4 error code, prefer EOPNOTSUPP and e.g. $ echo "clone_skb 1" > /proc/net/pktgen/lo\@0 -bash: echo: write error: Unknown error 524 Signed-off-by: Peter Seiderer Reviewed-by: Simon Horman Link: https://patch.msgid.link/20250219084527.20488-2-ps.report@gmx.net Signed-off-by: Jakub Kicinski --- net/core/pktgen.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/net/core/pktgen.c b/net/core/pktgen.c index 82b6a2c3c141..496aa16773e7 100644 --- a/net/core/pktgen.c +++ b/net/core/pktgen.c @@ -1198,7 +1198,7 @@ static ssize_t pktgen_if_write(struct file *file, if ((value > 0) && ((pkt_dev->xmit_mode == M_NETIF_RECEIVE) || !(pkt_dev->odev->priv_flags & IFF_TX_SKB_SHARING))) - return -ENOTSUPP; + return -EOPNOTSUPP; if (value > 0 && (pkt_dev->n_imix_entries > 0 || !(pkt_dev->flags & F_SHARED))) return -EINVAL; @@ -1258,7 +1258,7 @@ static ssize_t pktgen_if_write(struct file *file, ((pkt_dev->xmit_mode == M_QUEUE_XMIT) || ((pkt_dev->xmit_mode == M_START_XMIT) && (!(pkt_dev->odev->priv_flags & IFF_TX_SKB_SHARING))))) - return -ENOTSUPP; + return -EOPNOTSUPP; if (value > 1 && !(pkt_dev->flags & F_SHARED)) return -EINVAL; @@ -1303,7 +1303,7 @@ static ssize_t pktgen_if_write(struct file *file, } else if (strcmp(f, "netif_receive") == 0) { /* clone_skb set earlier, not supported in this mode */ if (pkt_dev->clone_skb > 0) - return -ENOTSUPP; + return -EOPNOTSUPP; pkt_dev->xmit_mode = M_NETIF_RECEIVE; From 80604d19b5fc3bc309039670445c73ee418d7a01 Mon Sep 17 00:00:00 2001 From: Peter Seiderer Date: Wed, 19 Feb 2025 09:45:22 +0100 Subject: [PATCH 2/7] net: pktgen: enable 'param=value' parsing Enable more flexible parameters syntax, allowing 'param=value' in addition to the already supported 'param value' pattern (additional this gives the skipping '=' in count_trail_chars() a purpose). Tested with: $ echo "min_pkt_size 999" > /proc/net/pktgen/lo\@0 $ echo "min_pkt_size=999" > /proc/net/pktgen/lo\@0 $ echo "min_pkt_size =999" > /proc/net/pktgen/lo\@0 $ echo "min_pkt_size= 999" > /proc/net/pktgen/lo\@0 $ echo "min_pkt_size = 999" > /proc/net/pktgen/lo\@0 Signed-off-by: Peter Seiderer Reviewed-by: Simon Horman Link: https://patch.msgid.link/20250219084527.20488-3-ps.report@gmx.net Signed-off-by: Jakub Kicinski --- net/core/pktgen.c | 1 + 1 file changed, 1 insertion(+) diff --git a/net/core/pktgen.c b/net/core/pktgen.c index 496aa16773e7..4f8ec6c9bed4 100644 --- a/net/core/pktgen.c +++ b/net/core/pktgen.c @@ -823,6 +823,7 @@ static int strn_len(const char __user * user_buffer, unsigned int maxlen) case '\r': case '\t': case ' ': + case '=': goto done_str; default: break; From b38504346a2400c822cc57d0164521405fb12757 Mon Sep 17 00:00:00 2001 From: Peter Seiderer Date: Wed, 19 Feb 2025 09:45:23 +0100 Subject: [PATCH 3/7] net: pktgen: fix hex32_arg parsing for short reads Fix hex32_arg parsing for short reads (here 7 hex digits instead of the expected 8), shift result only on successful input parsing. - before the patch $ echo "mpls 0000123" > /proc/net/pktgen/lo\@0 $ grep mpls /proc/net/pktgen/lo\@0 mpls: 00001230 Result: OK: mpls=00001230 - with patch applied $ echo "mpls 0000123" > /proc/net/pktgen/lo\@0 $ grep mpls /proc/net/pktgen/lo\@0 mpls: 00000123 Result: OK: mpls=00000123 Signed-off-by: Peter Seiderer Reviewed-by: Simon Horman Link: https://patch.msgid.link/20250219084527.20488-4-ps.report@gmx.net Signed-off-by: Jakub Kicinski --- net/core/pktgen.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/net/core/pktgen.c b/net/core/pktgen.c index 4f8ec6c9bed4..28dbbf70e142 100644 --- a/net/core/pktgen.c +++ b/net/core/pktgen.c @@ -753,14 +753,15 @@ static int hex32_arg(const char __user *user_buffer, unsigned long maxlen, for (; i < maxlen; i++) { int value; char c; - *num <<= 4; if (get_user(c, &user_buffer[i])) return -EFAULT; value = hex_to_bin(c); - if (value >= 0) + if (value >= 0) { + *num <<= 4; *num |= value; - else + } else { break; + } } return i; } From 3ba38c25a8c03b77ed448220a6c93dd5552a264e Mon Sep 17 00:00:00 2001 From: Peter Seiderer Date: Wed, 19 Feb 2025 09:45:24 +0100 Subject: [PATCH 4/7] net: pktgen: fix 'rate 0' error handling (return -EINVAL) Given an invalid 'rate' command e.g. 'rate 0' the return value is '1', leading to the following misleading output: - the good case $ echo "rate 100" > /proc/net/pktgen/lo\@0 $ grep "Result:" /proc/net/pktgen/lo\@0 Result: OK: rate=100 - the bad case (before the patch) $ echo "rate 0" > /proc/net/pktgen/lo\@0" -bash: echo: write error: Invalid argument $ grep "Result:" /proc/net/pktgen/lo\@0 Result: No such parameter "ate" - with patch applied $ echo "rate 0" > /proc/net/pktgen/lo\@0 -bash: echo: write error: Invalid argument $ grep "Result:" /proc/net/pktgen/lo\@0 Result: Idle Signed-off-by: Peter Seiderer Reviewed-by: Simon Horman Link: https://patch.msgid.link/20250219084527.20488-5-ps.report@gmx.net Signed-off-by: Jakub Kicinski --- net/core/pktgen.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/core/pktgen.c b/net/core/pktgen.c index 28dbbf70e142..75c7511bf492 100644 --- a/net/core/pktgen.c +++ b/net/core/pktgen.c @@ -1115,7 +1115,7 @@ static ssize_t pktgen_if_write(struct file *file, i += len; if (!value) - return len; + return -EINVAL; pkt_dev->delay = pkt_dev->min_pkt_size*8*NSEC_PER_USEC/value; if (debug) pr_info("Delay set at: %llu ns\n", pkt_dev->delay); From 1c3bc2c325f89e21f52af4a5c940ed1d89e05229 Mon Sep 17 00:00:00 2001 From: Peter Seiderer Date: Wed, 19 Feb 2025 09:45:25 +0100 Subject: [PATCH 5/7] net: pktgen: fix 'ratep 0' error handling (return -EINVAL) Given an invalid 'ratep' command e.g. 'ratep 0' the return value is '1', leading to the following misleading output: - the good case $ echo "ratep 100" > /proc/net/pktgen/lo\@0 $ grep "Result:" /proc/net/pktgen/lo\@0 Result: OK: ratep=100 - the bad case (before the patch) $ echo "ratep 0" > /proc/net/pktgen/lo\@0" -bash: echo: write error: Invalid argument $ grep "Result:" /proc/net/pktgen/lo\@0 Result: No such parameter "atep" - with patch applied $ echo "ratep 0" > /proc/net/pktgen/lo\@0 -bash: echo: write error: Invalid argument $ grep "Result:" /proc/net/pktgen/lo\@0 Result: Idle Signed-off-by: Peter Seiderer Reviewed-by: Simon Horman Link: https://patch.msgid.link/20250219084527.20488-6-ps.report@gmx.net Signed-off-by: Jakub Kicinski --- net/core/pktgen.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/core/pktgen.c b/net/core/pktgen.c index 75c7511bf492..c8a5b4d17407 100644 --- a/net/core/pktgen.c +++ b/net/core/pktgen.c @@ -1130,7 +1130,7 @@ static ssize_t pktgen_if_write(struct file *file, i += len; if (!value) - return len; + return -EINVAL; pkt_dev->delay = NSEC_PER_SEC/value; if (debug) pr_info("Delay set at: %llu ns\n", pkt_dev->delay); From 1e5e511373fe1348ed24372cf2a81234b32ac935 Mon Sep 17 00:00:00 2001 From: Peter Seiderer Date: Wed, 19 Feb 2025 09:45:26 +0100 Subject: [PATCH 6/7] net: pktgen: fix ctrl interface command parsing Enable command writing without trailing '\n': - the good case $ echo "reset" > /proc/net/pktgen/pgctrl - the bad case (before the patch) $ echo -n "reset" > /proc/net/pktgen/pgctrl -bash: echo: write error: Invalid argument - with patch applied $ echo -n "reset" > /proc/net/pktgen/pgctrl Signed-off-by: Peter Seiderer Reviewed-by: Simon Horman Link: https://patch.msgid.link/20250219084527.20488-7-ps.report@gmx.net Signed-off-by: Jakub Kicinski --- net/core/pktgen.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/net/core/pktgen.c b/net/core/pktgen.c index c8a5b4d17407..f6e35ba035c7 100644 --- a/net/core/pktgen.c +++ b/net/core/pktgen.c @@ -517,21 +517,23 @@ static ssize_t pgctrl_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) { char data[128]; + size_t max; struct pktgen_net *pn = net_generic(current->nsproxy->net_ns, pg_net_id); if (!capable(CAP_NET_ADMIN)) return -EPERM; - if (count == 0) + if (count < 1) return -EINVAL; - if (count > sizeof(data)) - count = sizeof(data); - - if (copy_from_user(data, buf, count)) + max = min(count, sizeof(data) - 1); + if (copy_from_user(data, buf, max)) return -EFAULT; - data[count - 1] = 0; /* Strip trailing '\n' and terminate string */ + if (data[max - 1] == '\n') + data[max - 1] = 0; /* strip trailing '\n', terminate string */ + else + data[max] = 0; /* terminate string */ if (!strcmp(data, "stop")) pktgen_stop_all_threads(pn); From 425e64440ad0a2f03bdaf04be0ae53dededbaa77 Mon Sep 17 00:00:00 2001 From: Peter Seiderer Date: Wed, 19 Feb 2025 09:45:27 +0100 Subject: [PATCH 7/7] net: pktgen: fix access outside of user given buffer in pktgen_thread_write() Honour the user given buffer size for the strn_len() calls (otherwise strn_len() will access memory outside of the user given buffer). Signed-off-by: Peter Seiderer Reviewed-by: Simon Horman Link: https://patch.msgid.link/20250219084527.20488-8-ps.report@gmx.net Signed-off-by: Jakub Kicinski --- net/core/pktgen.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/net/core/pktgen.c b/net/core/pktgen.c index f6e35ba035c7..55064713223e 100644 --- a/net/core/pktgen.c +++ b/net/core/pktgen.c @@ -1900,8 +1900,8 @@ static ssize_t pktgen_thread_write(struct file *file, i = len; /* Read variable name */ - - len = strn_len(&user_buffer[i], sizeof(name) - 1); + max = min(sizeof(name) - 1, count - i); + len = strn_len(&user_buffer[i], max); if (len < 0) return len; @@ -1931,7 +1931,8 @@ static ssize_t pktgen_thread_write(struct file *file, if (!strcmp(name, "add_device")) { char f[32]; memset(f, 0, 32); - len = strn_len(&user_buffer[i], sizeof(f) - 1); + max = min(sizeof(f) - 1, count - i); + len = strn_len(&user_buffer[i], max); if (len < 0) { ret = len; goto out;