netfilter: nf_conntrack_irc: Tighten matching on DCC message
[ Upstream commite8d5dfd1d8
] CTCP messages should only be at the start of an IRC message, not anywhere within it. While the helper only decodes packes in the ORIGINAL direction, its possible to make a client send a CTCP message back by empedding one into a PING request. As-is, thats enough to make the helper believe that it saw a CTCP message. Fixes:869f37d8e4
("[NETFILTER]: nf_conntrack/nf_nat: add IRC helper port") Signed-off-by: David Leadbeater <dgl@dgl.cx> Signed-off-by: Florian Westphal <fw@strlen.de> Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:
committed by
Greg Kroah-Hartman
parent
0606c5d5fe
commit
dc33ffbc36
@ -151,15 +151,37 @@ static int help(struct sk_buff *skb, unsigned int protoff,
|
|||||||
data = ib_ptr;
|
data = ib_ptr;
|
||||||
data_limit = ib_ptr + skb->len - dataoff;
|
data_limit = ib_ptr + skb->len - dataoff;
|
||||||
|
|
||||||
/* strlen("\1DCC SENT t AAAAAAAA P\1\n")=24
|
/* Skip any whitespace */
|
||||||
* 5+MINMATCHLEN+strlen("t AAAAAAAA P\1\n")=14 */
|
while (data < data_limit - 10) {
|
||||||
while (data < data_limit - (19 + MINMATCHLEN)) {
|
if (*data == ' ' || *data == '\r' || *data == '\n')
|
||||||
if (memcmp(data, "\1DCC ", 5)) {
|
data++;
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* strlen("PRIVMSG x ")=10 */
|
||||||
|
if (data < data_limit - 10) {
|
||||||
|
if (strncasecmp("PRIVMSG ", data, 8))
|
||||||
|
goto out;
|
||||||
|
data += 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* strlen(" :\1DCC SENT t AAAAAAAA P\1\n")=26
|
||||||
|
* 7+MINMATCHLEN+strlen("t AAAAAAAA P\1\n")=26
|
||||||
|
*/
|
||||||
|
while (data < data_limit - (21 + MINMATCHLEN)) {
|
||||||
|
/* Find first " :", the start of message */
|
||||||
|
if (memcmp(data, " :", 2)) {
|
||||||
data++;
|
data++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
data += 2;
|
||||||
|
|
||||||
|
/* then check that place only for the DCC command */
|
||||||
|
if (memcmp(data, "\1DCC ", 5))
|
||||||
|
goto out;
|
||||||
data += 5;
|
data += 5;
|
||||||
/* we have at least (19+MINMATCHLEN)-5 bytes valid data left */
|
/* we have at least (21+MINMATCHLEN)-(2+5) bytes valid data left */
|
||||||
|
|
||||||
iph = ip_hdr(skb);
|
iph = ip_hdr(skb);
|
||||||
pr_debug("DCC found in master %pI4:%u %pI4:%u\n",
|
pr_debug("DCC found in master %pI4:%u %pI4:%u\n",
|
||||||
@ -175,7 +197,7 @@ static int help(struct sk_buff *skb, unsigned int protoff,
|
|||||||
pr_debug("DCC %s detected\n", dccprotos[i]);
|
pr_debug("DCC %s detected\n", dccprotos[i]);
|
||||||
|
|
||||||
/* we have at least
|
/* we have at least
|
||||||
* (19+MINMATCHLEN)-5-dccprotos[i].matchlen bytes valid
|
* (21+MINMATCHLEN)-7-dccprotos[i].matchlen bytes valid
|
||||||
* data left (== 14/13 bytes) */
|
* data left (== 14/13 bytes) */
|
||||||
if (parse_dcc(data, data_limit, &dcc_ip,
|
if (parse_dcc(data, data_limit, &dcc_ip,
|
||||||
&dcc_port, &addr_beg_p, &addr_end_p)) {
|
&dcc_port, &addr_beg_p, &addr_end_p)) {
|
||||||
|
Reference in New Issue
Block a user