diff options
| author | Patrick McHardy <kaber@trash.net> | 2010-01-07 12:33:18 -0500 |
|---|---|---|
| committer | Patrick McHardy <kaber@trash.net> | 2010-01-07 12:33:18 -0500 |
| commit | aaff23a95aea5f000895f50d90e91f1e2f727002 (patch) | |
| tree | 54b592b3a7f05517a6ce9854c07b7f5b959d36fb /net | |
| parent | 04bcef2a83f40c6db24222b27a52892cba39dffb (diff) | |
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: Patrick McHardy <kaber@trash.net>
Diffstat (limited to 'net')
| -rw-r--r-- | net/netfilter/nf_conntrack_ftp.c | 18 |
1 files changed, 9 insertions, 9 deletions
diff --git a/net/netfilter/nf_conntrack_ftp.c b/net/netfilter/nf_conntrack_ftp.c index 38ea7ef3ccd2..f0732aa18e4f 100644 --- a/net/netfilter/nf_conntrack_ftp.c +++ b/net/netfilter/nf_conntrack_ftp.c | |||
| @@ -323,24 +323,24 @@ static void update_nl_seq(struct nf_conn *ct, u32 nl_seq, | |||
| 323 | struct nf_ct_ftp_master *info, int dir, | 323 | struct nf_ct_ftp_master *info, int dir, |
| 324 | struct sk_buff *skb) | 324 | struct sk_buff *skb) |
| 325 | { | 325 | { |
| 326 | unsigned int i, oldest = NUM_SEQ_TO_REMEMBER; | 326 | unsigned int i, oldest; |
| 327 | 327 | ||
| 328 | /* Look for oldest: if we find exact match, we're done. */ | 328 | /* Look for oldest: if we find exact match, we're done. */ |
| 329 | for (i = 0; i < info->seq_aft_nl_num[dir]; i++) { | 329 | for (i = 0; i < info->seq_aft_nl_num[dir]; i++) { |
| 330 | if (info->seq_aft_nl[dir][i] == nl_seq) | 330 | if (info->seq_aft_nl[dir][i] == nl_seq) |
| 331 | return; | 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])) | ||
| 336 | oldest = i; | ||
| 337 | } | 332 | } |
| 338 | 333 | ||
| 339 | if (info->seq_aft_nl_num[dir] < NUM_SEQ_TO_REMEMBER) { | 334 | if (info->seq_aft_nl_num[dir] < NUM_SEQ_TO_REMEMBER) { |
| 340 | info->seq_aft_nl[dir][info->seq_aft_nl_num[dir]++] = nl_seq; | 335 | info->seq_aft_nl[dir][info->seq_aft_nl_num[dir]++] = nl_seq; |
| 341 | } else if (oldest != NUM_SEQ_TO_REMEMBER && | 336 | } else { |
| 342 | after(nl_seq, info->seq_aft_nl[dir][oldest])) { | 337 | if (before(info->seq_aft_nl[dir][0], info->seq_aft_nl[dir][1])) |
| 343 | info->seq_aft_nl[dir][oldest] = nl_seq; | 338 | oldest = 0; |
| 339 | else | ||
| 340 | oldest = 1; | ||
| 341 | |||
| 342 | if (after(nl_seq, info->seq_aft_nl[dir][oldest])) | ||
| 343 | info->seq_aft_nl[dir][oldest] = nl_seq; | ||
| 344 | } | 344 | } |
| 345 | } | 345 | } |
| 346 | 346 | ||
