From: Patrick McHardy <kaber@trash.net>
To: Dan Carpenter <error27@gmail.com>
Cc: netfilter-devel@vger.kernel.org, netdev@vger.kernel.org
Subject: Re: off by one in update_nl_seq()
Date: Tue, 05 Jan 2010 08:43:24 +0100 [thread overview]
Message-ID: <4B42ED9C.6070304@trash.net> (raw)
In-Reply-To: <20091227131229.GH6075@bicker>
[-- Attachment #1: Type: text/plain, Size: 1328 bytes --]
Dan Carpenter wrote:
> net/netfilter/nf_conntrack_ftp.c
> 321 /* We don't update if it's older than what we have. */
> 322 static void update_nl_seq(struct nf_conn *ct, u32 nl_seq,
> 323 struct nf_ct_ftp_master *info, int dir,
> 324 struct sk_buff *skb)
> 325 {
> 326 unsigned int i, oldest = NUM_SEQ_TO_REMEMBER;
>
> Should this be oldest = NUM_SEQ_TO_REMEMBER - 1;? The array is
> defined as:
> u_int32_t seq_aft_nl[IP_CT_DIR_MAX][NUM_SEQ_TO_REMEMBER];
That would break the logic further down below.
> 327
> 328 /* Look for oldest: if we find exact match, we're done. */
> 329 for (i = 0; i < info->seq_aft_nl_num[dir]; i++) {
> 330 if (info->seq_aft_nl[dir][i] == nl_seq)
> 331 return;
> 332
> 333 if (oldest == info->seq_aft_nl_num[dir] ||
> 334 before(info->seq_aft_nl[dir][i],
> 335 info->seq_aft_nl[dir][oldest]))
>
> Line 335 has the possible array out of bounds I am concerned about.
Good catch, this is definitely a bug. The entire function seems
overly complicated to select one of two possible positions. I'll
commit the attached patch to fix this after some testing.
[-- Attachment #2: x --]
[-- Type: text/plain, Size: 1235 bytes --]
diff --git a/net/netfilter/nf_conntrack_ftp.c b/net/netfilter/nf_conntrack_ftp.c
index 38ea7ef..44b8d67 100644
--- a/net/netfilter/nf_conntrack_ftp.c
+++ b/net/netfilter/nf_conntrack_ftp.c
@@ -323,24 +323,25 @@ static void update_nl_seq(struct nf_conn *ct, u32 nl_seq,
struct nf_ct_ftp_master *info, int dir,
struct sk_buff *skb)
{
- unsigned int i, oldest = NUM_SEQ_TO_REMEMBER;
+ unsigned int i, oldest;
/* Look for oldest: if we find exact match, we're done. */
for (i = 0; i < info->seq_aft_nl_num[dir]; i++) {
if (info->seq_aft_nl[dir][i] == nl_seq)
return;
-
- if (oldest == info->seq_aft_nl_num[dir] ||
- before(info->seq_aft_nl[dir][i],
- info->seq_aft_nl[dir][oldest]))
- oldest = i;
}
if (info->seq_aft_nl_num[dir] < NUM_SEQ_TO_REMEMBER) {
info->seq_aft_nl[dir][info->seq_aft_nl_num[dir]++] = nl_seq;
- } else if (oldest != NUM_SEQ_TO_REMEMBER &&
- after(nl_seq, info->seq_aft_nl[dir][oldest])) {
- info->seq_aft_nl[dir][oldest] = nl_seq;
+ } else {
+ if (before(info->seq_aft_nl[dir][0],
+ info->seq_aft_nl[dir][1]))
+ oldest = 0;
+ else
+ oldest = 1;
+
+ if (after(nl_seq, info->seq_aft_nl[dir][oldest]))
+ info->seq_aft_nl[dir][oldest] = nl_seq;
}
}
prev parent reply other threads:[~2010-01-05 7:43 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-12-27 13:12 off by one in update_nl_seq() Dan Carpenter
2010-01-05 7:43 ` Patrick McHardy [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=4B42ED9C.6070304@trash.net \
--to=kaber@trash.net \
--cc=error27@gmail.com \
--cc=netdev@vger.kernel.org \
--cc=netfilter-devel@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.