[NETLINK]: Correctly set NLM_F_MULTI without checking the pid
This patch rectifies some rtnetlink message builders that derive the flags from the pid. It is now explicit like the other cases which get it right. Also fixes half a dozen dumpers which did not set NLM_F_MULTI at all. Signed-off-by: Jamal Hadi Salim <hadi@cyberus.ca> Signed-off-by: Thomas Graf <tgraf@suug.ch> Signed-off-by: David S. Miller <davem@davemloft.net>
Цей коміт міститься в:

зафіксовано
David S. Miller

джерело
1797754ea7
коміт
b6544c0b4c
@@ -1030,14 +1030,13 @@ static struct notifier_block ip_netdev_notifier = {
|
||||
};
|
||||
|
||||
static int inet_fill_ifaddr(struct sk_buff *skb, struct in_ifaddr *ifa,
|
||||
u32 pid, u32 seq, int event)
|
||||
u32 pid, u32 seq, int event, unsigned int flags)
|
||||
{
|
||||
struct ifaddrmsg *ifm;
|
||||
struct nlmsghdr *nlh;
|
||||
unsigned char *b = skb->tail;
|
||||
|
||||
nlh = NLMSG_PUT(skb, pid, seq, event, sizeof(*ifm));
|
||||
if (pid) nlh->nlmsg_flags |= NLM_F_MULTI;
|
||||
nlh = NLMSG_NEW(skb, pid, seq, event, sizeof(*ifm), flags);
|
||||
ifm = NLMSG_DATA(nlh);
|
||||
ifm->ifa_family = AF_INET;
|
||||
ifm->ifa_prefixlen = ifa->ifa_prefixlen;
|
||||
@@ -1090,7 +1089,7 @@ static int inet_dump_ifaddr(struct sk_buff *skb, struct netlink_callback *cb)
|
||||
continue;
|
||||
if (inet_fill_ifaddr(skb, ifa, NETLINK_CB(cb->skb).pid,
|
||||
cb->nlh->nlmsg_seq,
|
||||
RTM_NEWADDR) <= 0) {
|
||||
RTM_NEWADDR, NLM_F_MULTI) <= 0) {
|
||||
rcu_read_unlock();
|
||||
goto done;
|
||||
}
|
||||
@@ -1113,7 +1112,7 @@ static void rtmsg_ifa(int event, struct in_ifaddr* ifa)
|
||||
|
||||
if (!skb)
|
||||
netlink_set_err(rtnl, 0, RTMGRP_IPV4_IFADDR, ENOBUFS);
|
||||
else if (inet_fill_ifaddr(skb, ifa, 0, 0, event) < 0) {
|
||||
else if (inet_fill_ifaddr(skb, ifa, 0, 0, event, 0) < 0) {
|
||||
kfree_skb(skb);
|
||||
netlink_set_err(rtnl, 0, RTMGRP_IPV4_IFADDR, EINVAL);
|
||||
} else {
|
||||
|
@@ -703,7 +703,8 @@ fn_hash_dump_bucket(struct sk_buff *skb, struct netlink_callback *cb,
|
||||
&f->fn_key,
|
||||
fz->fz_order,
|
||||
fa->fa_tos,
|
||||
fa->fa_info) < 0) {
|
||||
fa->fa_info,
|
||||
NLM_F_MULTI) < 0) {
|
||||
cb->args[3] = i;
|
||||
return -1;
|
||||
}
|
||||
|
@@ -30,7 +30,8 @@ extern int fib_nh_match(struct rtmsg *r, struct nlmsghdr *,
|
||||
struct kern_rta *rta, struct fib_info *fi);
|
||||
extern int fib_dump_info(struct sk_buff *skb, u32 pid, u32 seq, int event,
|
||||
u8 tb_id, u8 type, u8 scope, void *dst,
|
||||
int dst_len, u8 tos, struct fib_info *fi);
|
||||
int dst_len, u8 tos, struct fib_info *fi,
|
||||
unsigned int);
|
||||
extern void rtmsg_fib(int event, u32 key, struct fib_alias *fa,
|
||||
int z, int tb_id,
|
||||
struct nlmsghdr *n, struct netlink_skb_parms *req);
|
||||
|
@@ -367,13 +367,14 @@ static struct notifier_block fib_rules_notifier = {
|
||||
|
||||
static __inline__ int inet_fill_rule(struct sk_buff *skb,
|
||||
struct fib_rule *r,
|
||||
struct netlink_callback *cb)
|
||||
struct netlink_callback *cb,
|
||||
unsigned int flags)
|
||||
{
|
||||
struct rtmsg *rtm;
|
||||
struct nlmsghdr *nlh;
|
||||
unsigned char *b = skb->tail;
|
||||
|
||||
nlh = NLMSG_PUT(skb, NETLINK_CREDS(cb->skb)->pid, cb->nlh->nlmsg_seq, RTM_NEWRULE, sizeof(*rtm));
|
||||
nlh = NLMSG_NEW_ANSWER(skb, cb, RTM_NEWRULE, sizeof(*rtm), flags);
|
||||
rtm = NLMSG_DATA(nlh);
|
||||
rtm->rtm_family = AF_INET;
|
||||
rtm->rtm_dst_len = r->r_dst_len;
|
||||
@@ -422,7 +423,7 @@ int inet_dump_rules(struct sk_buff *skb, struct netlink_callback *cb)
|
||||
for (r=fib_rules, idx=0; r; r = r->r_next, idx++) {
|
||||
if (idx < s_idx)
|
||||
continue;
|
||||
if (inet_fill_rule(skb, r, cb) < 0)
|
||||
if (inet_fill_rule(skb, r, cb, NLM_F_MULTI) < 0)
|
||||
break;
|
||||
}
|
||||
read_unlock(&fib_rules_lock);
|
||||
|
@@ -286,7 +286,7 @@ void rtmsg_fib(int event, u32 key, struct fib_alias *fa,
|
||||
if (fib_dump_info(skb, pid, n->nlmsg_seq, event, tb_id,
|
||||
fa->fa_type, fa->fa_scope, &key, z,
|
||||
fa->fa_tos,
|
||||
fa->fa_info) < 0) {
|
||||
fa->fa_info, 0) < 0) {
|
||||
kfree_skb(skb);
|
||||
return;
|
||||
}
|
||||
@@ -932,13 +932,13 @@ u32 __fib_res_prefsrc(struct fib_result *res)
|
||||
int
|
||||
fib_dump_info(struct sk_buff *skb, u32 pid, u32 seq, int event,
|
||||
u8 tb_id, u8 type, u8 scope, void *dst, int dst_len, u8 tos,
|
||||
struct fib_info *fi)
|
||||
struct fib_info *fi, unsigned int flags)
|
||||
{
|
||||
struct rtmsg *rtm;
|
||||
struct nlmsghdr *nlh;
|
||||
unsigned char *b = skb->tail;
|
||||
|
||||
nlh = NLMSG_PUT(skb, pid, seq, event, sizeof(*rtm));
|
||||
nlh = NLMSG_NEW(skb, pid, seq, event, sizeof(*rtm), flags);
|
||||
rtm = NLMSG_DATA(nlh);
|
||||
rtm->rtm_family = AF_INET;
|
||||
rtm->rtm_dst_len = dst_len;
|
||||
|
@@ -2581,7 +2581,7 @@ int ip_route_output_key(struct rtable **rp, struct flowi *flp)
|
||||
}
|
||||
|
||||
static int rt_fill_info(struct sk_buff *skb, u32 pid, u32 seq, int event,
|
||||
int nowait)
|
||||
int nowait, unsigned int flags)
|
||||
{
|
||||
struct rtable *rt = (struct rtable*)skb->dst;
|
||||
struct rtmsg *r;
|
||||
@@ -2591,9 +2591,8 @@ static int rt_fill_info(struct sk_buff *skb, u32 pid, u32 seq, int event,
|
||||
#ifdef CONFIG_IP_MROUTE
|
||||
struct rtattr *eptr;
|
||||
#endif
|
||||
nlh = NLMSG_PUT(skb, pid, seq, event, sizeof(*r));
|
||||
nlh = NLMSG_NEW(skb, pid, seq, event, sizeof(*r), flags);
|
||||
r = NLMSG_DATA(nlh);
|
||||
nlh->nlmsg_flags = (nowait && pid) ? NLM_F_MULTI : 0;
|
||||
r->rtm_family = AF_INET;
|
||||
r->rtm_dst_len = 32;
|
||||
r->rtm_src_len = 0;
|
||||
@@ -2744,7 +2743,7 @@ int inet_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr* nlh, void *arg)
|
||||
NETLINK_CB(skb).dst_pid = NETLINK_CB(in_skb).pid;
|
||||
|
||||
err = rt_fill_info(skb, NETLINK_CB(in_skb).pid, nlh->nlmsg_seq,
|
||||
RTM_NEWROUTE, 0);
|
||||
RTM_NEWROUTE, 0, 0);
|
||||
if (!err)
|
||||
goto out_free;
|
||||
if (err < 0) {
|
||||
@@ -2781,8 +2780,8 @@ int ip_rt_dump(struct sk_buff *skb, struct netlink_callback *cb)
|
||||
continue;
|
||||
skb->dst = dst_clone(&rt->u.dst);
|
||||
if (rt_fill_info(skb, NETLINK_CB(cb->skb).pid,
|
||||
cb->nlh->nlmsg_seq,
|
||||
RTM_NEWROUTE, 1) <= 0) {
|
||||
cb->nlh->nlmsg_seq, RTM_NEWROUTE,
|
||||
1, NLM_F_MULTI) <= 0) {
|
||||
dst_release(xchg(&skb->dst, NULL));
|
||||
rcu_read_unlock_bh();
|
||||
goto done;
|
||||
|
Посилання в новій задачі
Заблокувати користувача