netlabel: correctly list all the static label mappings

[ Upstream commits 0c1233aba1 and
  a6a8fe950e ]

When we have a large number of static label mappings that spill across
the netlink message boundary we fail to properly save our state in the
netlink_callback struct which causes us to repeat the same listings.
This patch fixes this problem by saving the state correctly between
calls to the NetLabel static label netlink "dumpit" routines.

Signed-off-by: Paul Moore <pmoore@redhat.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
Paul Moore 2013-03-06 11:45:24 +00:00 committed by Greg Kroah-Hartman
parent e86429f5b4
commit 8c6292ad91

View file

@ -1189,8 +1189,6 @@ static int netlbl_unlabel_staticlist(struct sk_buff *skb,
struct netlbl_unlhsh_walk_arg cb_arg;
u32 skip_bkt = cb->args[0];
u32 skip_chain = cb->args[1];
u32 skip_addr4 = cb->args[2];
u32 skip_addr6 = cb->args[3];
u32 iter_bkt;
u32 iter_chain = 0, iter_addr4 = 0, iter_addr6 = 0;
struct netlbl_unlhsh_iface *iface;
@ -1215,7 +1213,7 @@ static int netlbl_unlabel_staticlist(struct sk_buff *skb,
continue;
netlbl_af4list_foreach_rcu(addr4,
&iface->addr4_list) {
if (iter_addr4++ < skip_addr4)
if (iter_addr4++ < cb->args[2])
continue;
if (netlbl_unlabel_staticlist_gen(
NLBL_UNLABEL_C_STATICLIST,
@ -1231,7 +1229,7 @@ static int netlbl_unlabel_staticlist(struct sk_buff *skb,
#if IS_ENABLED(CONFIG_IPV6)
netlbl_af6list_foreach_rcu(addr6,
&iface->addr6_list) {
if (iter_addr6++ < skip_addr6)
if (iter_addr6++ < cb->args[3])
continue;
if (netlbl_unlabel_staticlist_gen(
NLBL_UNLABEL_C_STATICLIST,
@ -1250,10 +1248,10 @@ static int netlbl_unlabel_staticlist(struct sk_buff *skb,
unlabel_staticlist_return:
rcu_read_unlock();
cb->args[0] = skip_bkt;
cb->args[1] = skip_chain;
cb->args[2] = skip_addr4;
cb->args[3] = skip_addr6;
cb->args[0] = iter_bkt;
cb->args[1] = iter_chain;
cb->args[2] = iter_addr4;
cb->args[3] = iter_addr6;
return skb->len;
}
@ -1273,12 +1271,9 @@ static int netlbl_unlabel_staticlistdef(struct sk_buff *skb,
{
struct netlbl_unlhsh_walk_arg cb_arg;
struct netlbl_unlhsh_iface *iface;
u32 skip_addr4 = cb->args[0];
u32 skip_addr6 = cb->args[1];
u32 iter_addr4 = 0;
u32 iter_addr4 = 0, iter_addr6 = 0;
struct netlbl_af4list *addr4;
#if IS_ENABLED(CONFIG_IPV6)
u32 iter_addr6 = 0;
struct netlbl_af6list *addr6;
#endif
@ -1292,7 +1287,7 @@ static int netlbl_unlabel_staticlistdef(struct sk_buff *skb,
goto unlabel_staticlistdef_return;
netlbl_af4list_foreach_rcu(addr4, &iface->addr4_list) {
if (iter_addr4++ < skip_addr4)
if (iter_addr4++ < cb->args[0])
continue;
if (netlbl_unlabel_staticlist_gen(NLBL_UNLABEL_C_STATICLISTDEF,
iface,
@ -1305,7 +1300,7 @@ static int netlbl_unlabel_staticlistdef(struct sk_buff *skb,
}
#if IS_ENABLED(CONFIG_IPV6)
netlbl_af6list_foreach_rcu(addr6, &iface->addr6_list) {
if (iter_addr6++ < skip_addr6)
if (iter_addr6++ < cb->args[1])
continue;
if (netlbl_unlabel_staticlist_gen(NLBL_UNLABEL_C_STATICLISTDEF,
iface,
@ -1320,8 +1315,8 @@ static int netlbl_unlabel_staticlistdef(struct sk_buff *skb,
unlabel_staticlistdef_return:
rcu_read_unlock();
cb->args[0] = skip_addr4;
cb->args[1] = skip_addr6;
cb->args[0] = iter_addr4;
cb->args[1] = iter_addr6;
return skb->len;
}