| From 4c04b9cbce9c59461ff5c9b32a8c5473f3cfeaf6 Mon Sep 17 00:00:00 2001 |
| From: Vasily Averin <vvs@virtuozzo.com> |
| Date: Tue, 25 Feb 2020 10:06:29 +0300 |
| Subject: [PATCH] netfilter: xt_recent: recent_seq_next should increase |
| position index |
| |
| commit db25517a550926f609c63054b12ea9ad515e1a10 upstream. |
| |
| If .next function does not change position index, |
| following .show function will repeat output related |
| to current position index. |
| |
| Without the patch: |
| # dd if=/proc/net/xt_recent/SSH # original file outpt |
| src=127.0.0.4 ttl: 0 last_seen: 6275444819 oldest_pkt: 1 6275444819 |
| src=127.0.0.2 ttl: 0 last_seen: 6275438906 oldest_pkt: 1 6275438906 |
| src=127.0.0.3 ttl: 0 last_seen: 6275441953 oldest_pkt: 1 6275441953 |
| 0+1 records in |
| 0+1 records out |
| 204 bytes copied, 6.1332e-05 s, 3.3 MB/s |
| |
| Read after lseek into middle of last line (offset 140 in example below) |
| generates expected end of last line and then unexpected whole last line |
| once again |
| |
| # dd if=/proc/net/xt_recent/SSH bs=140 skip=1 |
| dd: /proc/net/xt_recent/SSH: cannot skip to specified offset |
| 127.0.0.3 ttl: 0 last_seen: 6275441953 oldest_pkt: 1 6275441953 |
| src=127.0.0.3 ttl: 0 last_seen: 6275441953 oldest_pkt: 1 6275441953 |
| 0+1 records in |
| 0+1 records out |
| 132 bytes copied, 6.2487e-05 s, 2.1 MB/s |
| |
| Cc: stable@vger.kernel.org |
| Fixes: 1f4aace60b0e ("fs/seq_file.c: simplify seq_file iteration code ...") |
| Link: https://bugzilla.kernel.org/show_bug.cgi?id=206283 |
| Signed-off-by: Vasily Averin <vvs@virtuozzo.com> |
| Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org> |
| Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com> |
| |
| diff --git a/net/netfilter/xt_recent.c b/net/netfilter/xt_recent.c |
| index 781e0b482189..6c2582a19766 100644 |
| --- a/net/netfilter/xt_recent.c |
| +++ b/net/netfilter/xt_recent.c |
| @@ -492,12 +492,12 @@ static void *recent_seq_next(struct seq_file *seq, void *v, loff_t *pos) |
| const struct recent_entry *e = v; |
| const struct list_head *head = e->list.next; |
| |
| + (*pos)++; |
| while (head == &t->iphash[st->bucket]) { |
| if (++st->bucket >= ip_list_hash_size) |
| return NULL; |
| head = t->iphash[st->bucket].next; |
| } |
| - (*pos)++; |
| return list_entry(head, struct recent_entry, list); |
| } |
| |
| -- |
| 2.7.4 |
| |