Commit aaff23a9 authored by Patrick McHardy's avatar Patrick McHardy

netfilter: nf_ct_ftp: fix out of bounds read in update_nl_seq()

As noticed by Dan Carpenter <error27@gmail.com>, update_nl_seq()
currently contains an out of bounds read of the seq_aft_nl array
when looking for the oldest sequence number position.

Fix it to only compare valid positions.

Cc: stable@kernel.org
Signed-off-by: default avatarPatrick McHardy <kaber@trash.net>
parent 04bcef2a
...@@ -323,24 +323,24 @@ static void update_nl_seq(struct nf_conn *ct, u32 nl_seq, ...@@ -323,24 +323,24 @@ static void update_nl_seq(struct nf_conn *ct, u32 nl_seq,
struct nf_ct_ftp_master *info, int dir, struct nf_ct_ftp_master *info, int dir,
struct sk_buff *skb) 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. */ /* Look for oldest: if we find exact match, we're done. */
for (i = 0; i < info->seq_aft_nl_num[dir]; i++) { for (i = 0; i < info->seq_aft_nl_num[dir]; i++) {
if (info->seq_aft_nl[dir][i] == nl_seq) if (info->seq_aft_nl[dir][i] == nl_seq)
return; 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) { if (info->seq_aft_nl_num[dir] < NUM_SEQ_TO_REMEMBER) {
info->seq_aft_nl[dir][info->seq_aft_nl_num[dir]++] = nl_seq; info->seq_aft_nl[dir][info->seq_aft_nl_num[dir]++] = nl_seq;
} else if (oldest != NUM_SEQ_TO_REMEMBER && } else {
after(nl_seq, info->seq_aft_nl[dir][oldest])) { if (before(info->seq_aft_nl[dir][0], info->seq_aft_nl[dir][1]))
info->seq_aft_nl[dir][oldest] = nl_seq; oldest = 0;
else
oldest = 1;
if (after(nl_seq, info->seq_aft_nl[dir][oldest]))
info->seq_aft_nl[dir][oldest] = nl_seq;
} }
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment