Commit 745e2031 authored by Chris Larson's avatar Chris Larson Committed by David S. Miller

net: fix missing pneigh entries in the neighbor seq_file code

When pneigh entries exist, but the user's read buffer isn't sufficient to
hold them all, one of the pneigh entries will be missing from the results.

In neigh_get_idx_any, the number of elements which neigh_get_idx
encountered is not correctly subtracted from the position number before
the call to pneigh_get_idx.  neigh_get_idx reduces the position by 1 for
each call to neigh_get_next, but it does not reduce it by one for the
first element (neigh_get_first). The patch alters the neigh_get_idx and
pneigh_get_idx functions to subtract one from pos, for the first element,
when pos is non-zero.
Signed-off-by: default avatarChris Larson <clarson@mvista.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent bff69732
...@@ -2281,6 +2281,7 @@ static struct neighbour *neigh_get_idx(struct seq_file *seq, loff_t *pos) ...@@ -2281,6 +2281,7 @@ static struct neighbour *neigh_get_idx(struct seq_file *seq, loff_t *pos)
struct neighbour *n = neigh_get_first(seq); struct neighbour *n = neigh_get_first(seq);
if (n) { if (n) {
--(*pos);
while (*pos) { while (*pos) {
n = neigh_get_next(seq, n, pos); n = neigh_get_next(seq, n, pos);
if (!n) if (!n)
...@@ -2341,6 +2342,7 @@ static struct pneigh_entry *pneigh_get_idx(struct seq_file *seq, loff_t *pos) ...@@ -2341,6 +2342,7 @@ static struct pneigh_entry *pneigh_get_idx(struct seq_file *seq, loff_t *pos)
struct pneigh_entry *pn = pneigh_get_first(seq); struct pneigh_entry *pn = pneigh_get_first(seq);
if (pn) { if (pn) {
--(*pos);
while (*pos) { while (*pos) {
pn = pneigh_get_next(seq, pn, pos); pn = pneigh_get_next(seq, pn, pos);
if (!pn) if (!pn)
...@@ -2354,10 +2356,11 @@ static void *neigh_get_idx_any(struct seq_file *seq, loff_t *pos) ...@@ -2354,10 +2356,11 @@ static void *neigh_get_idx_any(struct seq_file *seq, loff_t *pos)
{ {
struct neigh_seq_state *state = seq->private; struct neigh_seq_state *state = seq->private;
void *rc; void *rc;
loff_t idxpos = *pos;
rc = neigh_get_idx(seq, pos); rc = neigh_get_idx(seq, &idxpos);
if (!rc && !(state->flags & NEIGH_SEQ_NEIGH_ONLY)) if (!rc && !(state->flags & NEIGH_SEQ_NEIGH_ONLY))
rc = pneigh_get_idx(seq, pos); rc = pneigh_get_idx(seq, &idxpos);
return rc; return rc;
} }
...@@ -2366,7 +2369,6 @@ void *neigh_seq_start(struct seq_file *seq, loff_t *pos, struct neigh_table *tbl ...@@ -2366,7 +2369,6 @@ void *neigh_seq_start(struct seq_file *seq, loff_t *pos, struct neigh_table *tbl
__acquires(tbl->lock) __acquires(tbl->lock)
{ {
struct neigh_seq_state *state = seq->private; struct neigh_seq_state *state = seq->private;
loff_t pos_minus_one;
state->tbl = tbl; state->tbl = tbl;
state->bucket = 0; state->bucket = 0;
...@@ -2374,8 +2376,7 @@ void *neigh_seq_start(struct seq_file *seq, loff_t *pos, struct neigh_table *tbl ...@@ -2374,8 +2376,7 @@ void *neigh_seq_start(struct seq_file *seq, loff_t *pos, struct neigh_table *tbl
read_lock_bh(&tbl->lock); read_lock_bh(&tbl->lock);
pos_minus_one = *pos - 1; return *pos ? neigh_get_idx_any(seq, pos) : SEQ_START_TOKEN;
return *pos ? neigh_get_idx_any(seq, &pos_minus_one) : SEQ_START_TOKEN;
} }
EXPORT_SYMBOL(neigh_seq_start); EXPORT_SYMBOL(neigh_seq_start);
......
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