| .. | .. |
|---|
| 30 | 30 | #include <linux/slab.h> |
|---|
| 31 | 31 | #include <linux/netlink.h> |
|---|
| 32 | 32 | #include <linux/hash.h> |
|---|
| 33 | +#include <linux/nospec.h> |
|---|
| 33 | 34 | |
|---|
| 34 | 35 | #include <net/arp.h> |
|---|
| 35 | 36 | #include <net/ip.h> |
|---|
| .. | .. |
|---|
| 277 | 278 | hlist_del(&nexthop_nh->nh_hash); |
|---|
| 278 | 279 | } endfor_nexthops(fi) |
|---|
| 279 | 280 | } |
|---|
| 280 | | - fi->fib_dead = 1; |
|---|
| 281 | + /* Paired with READ_ONCE() from fib_table_lookup() */ |
|---|
| 282 | + WRITE_ONCE(fi->fib_dead, 1); |
|---|
| 281 | 283 | fib_info_put(fi); |
|---|
| 282 | 284 | } |
|---|
| 283 | 285 | spin_unlock_bh(&fib_info_lock); |
|---|
| .. | .. |
|---|
| 1021 | 1023 | if (type > RTAX_MAX) |
|---|
| 1022 | 1024 | return false; |
|---|
| 1023 | 1025 | |
|---|
| 1026 | + type = array_index_nospec(type, RTAX_MAX + 1); |
|---|
| 1024 | 1027 | if (type == RTAX_CC_ALGO) { |
|---|
| 1025 | 1028 | char tmp[TCP_CA_NAME_MAX]; |
|---|
| 1026 | 1029 | bool ecn_ca = false; |
|---|
| .. | .. |
|---|
| 1597 | 1600 | link_it: |
|---|
| 1598 | 1601 | ofi = fib_find_info(fi); |
|---|
| 1599 | 1602 | if (ofi) { |
|---|
| 1603 | + /* fib_table_lookup() should not see @fi yet. */ |
|---|
| 1600 | 1604 | fi->fib_dead = 1; |
|---|
| 1601 | 1605 | free_fib_info(fi); |
|---|
| 1602 | 1606 | ofi->fib_treeref++; |
|---|
| .. | .. |
|---|
| 1635 | 1639 | |
|---|
| 1636 | 1640 | failure: |
|---|
| 1637 | 1641 | if (fi) { |
|---|
| 1642 | + /* fib_table_lookup() should not see @fi yet. */ |
|---|
| 1638 | 1643 | fi->fib_dead = 1; |
|---|
| 1639 | 1644 | free_fib_info(fi); |
|---|
| 1640 | 1645 | } |
|---|