@@ -88,7 +88,9 @@ static int parse_dcc(char *data, const char *data_end, __be32 *ip,
data++;
}
- *port = simple_strtoul(data, &data, 10);
+ if (nf_ct_helper_parse_port(data, data_end - data, port, &data))
+ return -1;
+
*ad_end_p = data;
return 0;
@@ -206,9 +208,8 @@ static int help(struct sk_buff *skb, unsigned int protoff,
/* dcc_ip can be the internal OR external (NAT'ed) IP */
tuple = &ct->tuplehash[dir].tuple;
- if ((tuple->src.u3.ip != dcc_ip &&
- ct->tuplehash[!dir].tuple.dst.u3.ip != dcc_ip) ||
- dcc_port == 0) {
+ if (tuple->src.u3.ip != dcc_ip &&
+ ct->tuplehash[!dir].tuple.dst.u3.ip != dcc_ip) {
net_warn_ratelimited("Forged DCC command from %pI4: %pI4:%u\n",
&tuple->src.u3.ip,
&dcc_ip, dcc_port);
parse_dcc() stores the result of simple_strtoul() directly into the u16 *port, so a DCC port above 65535 is silently truncated (e.g. 65537 becomes 1) and a conntrack expectation is created for a port that never appeared in the DCC command. Use nf_ct_helper_parse_port(), which parses the length-delimited buffer without relying on NUL termination and rejects port 0, values above 65535 and digit runs longer than five characters. Since parse_dcc() now fails for port 0, the dcc_port == 0 test in help() can no longer be true; remove it. A DCC command with port 0 is now dropped through the "unable to parse dcc command" debug path instead of the ratelimited "Forged DCC command" warning; no expectation is created in either case. Build-tested with allmodconfig and allyesconfig (W=1) and sparse, and cross-built for i386 and big-endian powerpc. It has not been run-time tested with IRC traffic. Fixes: 869f37d8e48f ("[NETFILTER]: nf_conntrack/nf_nat: add IRC helper port") Assisted-by: Claude-Code:claude-opus-5-5 sparse Signed-off-by: Rahul Chandelkar <rc@rexion.ai> --- net/netfilter/nf_conntrack_irc.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-)