Skip to content

Commit 1af7f88

Browse files
Eric Dumazetkuba-moo
Eric Dumazet
authored andcommitted
inet: fix inet_fill_ifaddr() flags truncation
I missed that (struct ifaddrmsg)->ifa_flags was only 8bits, while (struct in_ifaddr)->ifa_flags is 32bits. Use a temporary 32bit variable as I did in set_ifa_lifetime() and check_lifetime(). Fixes: 3ddc223 ("inet: annotate data-races around ifa->ifa_flags") Reported-by: Yu Watanabe <[email protected]> Dianosed-by: Yu Watanabe <[email protected]> Closes: systemd/systemd#32666 (comment) Signed-off-by: Eric Dumazet <[email protected]> Reviewed-by: Larysa Zaremba <[email protected]> Reviewed-by: David Ahern <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Jakub Kicinski <[email protected]>
1 parent c9f9df3 commit 1af7f88

File tree

1 file changed

+10
-3
lines changed

1 file changed

+10
-3
lines changed

net/ipv4/devinet.c

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1683,6 +1683,7 @@ static int inet_fill_ifaddr(struct sk_buff *skb, const struct in_ifaddr *ifa,
16831683
struct nlmsghdr *nlh;
16841684
unsigned long tstamp;
16851685
u32 preferred, valid;
1686+
u32 flags;
16861687

16871688
nlh = nlmsg_put(skb, args->portid, args->seq, args->event, sizeof(*ifm),
16881689
args->flags);
@@ -1692,7 +1693,13 @@ static int inet_fill_ifaddr(struct sk_buff *skb, const struct in_ifaddr *ifa,
16921693
ifm = nlmsg_data(nlh);
16931694
ifm->ifa_family = AF_INET;
16941695
ifm->ifa_prefixlen = ifa->ifa_prefixlen;
1695-
ifm->ifa_flags = READ_ONCE(ifa->ifa_flags);
1696+
1697+
flags = READ_ONCE(ifa->ifa_flags);
1698+
/* Warning : ifm->ifa_flags is an __u8, it holds only 8 bits.
1699+
* The 32bit value is given in IFA_FLAGS attribute.
1700+
*/
1701+
ifm->ifa_flags = (__u8)flags;
1702+
16961703
ifm->ifa_scope = ifa->ifa_scope;
16971704
ifm->ifa_index = ifa->ifa_dev->dev->ifindex;
16981705

@@ -1701,7 +1708,7 @@ static int inet_fill_ifaddr(struct sk_buff *skb, const struct in_ifaddr *ifa,
17011708
goto nla_put_failure;
17021709

17031710
tstamp = READ_ONCE(ifa->ifa_tstamp);
1704-
if (!(ifm->ifa_flags & IFA_F_PERMANENT)) {
1711+
if (!(flags & IFA_F_PERMANENT)) {
17051712
preferred = READ_ONCE(ifa->ifa_preferred_lft);
17061713
valid = READ_ONCE(ifa->ifa_valid_lft);
17071714
if (preferred != INFINITY_LIFE_TIME) {
@@ -1732,7 +1739,7 @@ static int inet_fill_ifaddr(struct sk_buff *skb, const struct in_ifaddr *ifa,
17321739
nla_put_string(skb, IFA_LABEL, ifa->ifa_label)) ||
17331740
(ifa->ifa_proto &&
17341741
nla_put_u8(skb, IFA_PROTO, ifa->ifa_proto)) ||
1735-
nla_put_u32(skb, IFA_FLAGS, ifm->ifa_flags) ||
1742+
nla_put_u32(skb, IFA_FLAGS, flags) ||
17361743
(ifa->ifa_rt_priority &&
17371744
nla_put_u32(skb, IFA_RT_PRIORITY, ifa->ifa_rt_priority)) ||
17381745
put_cacheinfo(skb, READ_ONCE(ifa->ifa_cstamp), tstamp,

0 commit comments

Comments
 (0)