mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2025-01-01 02:36:02 +00:00
netfilter: nf_conntrack_irc: Tighten matching on DCC message
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>
This commit is contained in:
parent
25b327d4f8
commit
e8d5dfd1d8
@ -157,15 +157,37 @@ static int help(struct sk_buff *skb, unsigned int protoff,
|
||||
data = ib_ptr;
|
||||
data_limit = ib_ptr + datalen;
|
||||
|
||||
/* 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",
|
||||
@ -181,7 +203,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