netfilter: nf_conntrack_irc: Tighten matching on DCC message
[ Upstream commit e8d5dfd1d8747b56077d02664a8838c71ced948e ]
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:
parent
369ec4dab0
commit
9a5d7e0acb
@ -148,15 +148,37 @@ static int help(struct sk_buff *skb, unsigned int protoff,
|
||||
data = ib_ptr;
|
||||
data_limit = ib_ptr + skb->len - dataoff;
|
||||
|
||||
/* strlen("\1DCC SENT t AAAAAAAA P\1\n")=24
|
||||
* 5+MINMATCHLEN+strlen("t AAAAAAAA P\1\n")=14 */
|
||||
while (data < data_limit - (19 + MINMATCHLEN)) {
|
||||
if (memcmp(data, "\1DCC ", 5)) {
|
||||
/* Skip any whitespace */
|
||||
while (data < data_limit - 10) {
|
||||
if (*data == ' ' || *data == '\r' || *data == '\n')
|
||||
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++;
|
||||
continue;
|
||||
}
|
||||
data += 2;
|
||||
|
||||
/* then check that place only for the DCC command */
|
||||
if (memcmp(data, "\1DCC ", 5))
|
||||
goto out;
|
||||
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);
|
||||
pr_debug("DCC found in master %pI4:%u %pI4:%u\n",
|
||||
@ -172,7 +194,7 @@ static int help(struct sk_buff *skb, unsigned int protoff,
|
||||
pr_debug("DCC %s detected\n", dccprotos[i]);
|
||||
|
||||
/* 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) */
|
||||
if (parse_dcc(data, data_limit, &dcc_ip,
|
||||
&dcc_port, &addr_beg_p, &addr_end_p)) {
|
||||
|
Loading…
Reference in New Issue
Block a user