Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'bpf-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf

Pull bpf fixes from Alexei Starovoitov:

- Finish constification of 1st parameter of bpf_d_path() (Rong Tao)

- Harden userspace-supplied xdp_desc validation (Alexander Lobakin)

- Fix metadata_dst leak in __bpf_redirect_neigh_v{4,6}() (Daniel
Borkmann)

- Fix undefined behavior in {get,put}_unaligned_be32() (Eric Biggers)

- Use correct context to unpin bpf hash map with special types (KaFai
Wan)

* tag 'bpf-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf:
selftests/bpf: Add test for unpinning htab with internal timer struct
bpf: Avoid RCU context warning when unpinning htab with internal structs
xsk: Harden userspace-supplied xdp_desc validation
bpf: Fix metadata_dst leak __bpf_redirect_neigh_v{4,6}
libbpf: Fix undefined behavior in {get,put}_unaligned_be32()
bpf: Finish constification of 1st parameter of bpf_d_path()

+117 -24
+1 -1
include/uapi/linux/bpf.h
··· 4891 4891 * 4892 4892 * **-ENOENT** if the bpf_local_storage cannot be found. 4893 4893 * 4894 - * long bpf_d_path(struct path *path, char *buf, u32 sz) 4894 + * long bpf_d_path(const struct path *path, char *buf, u32 sz) 4895 4895 * Description 4896 4896 * Return full path for given **struct path** object, which 4897 4897 * needs to be the kernel BTF *path* object. The path is
+2 -2
kernel/bpf/inode.c
··· 775 775 return 0; 776 776 } 777 777 778 - static void bpf_free_inode(struct inode *inode) 778 + static void bpf_destroy_inode(struct inode *inode) 779 779 { 780 780 enum bpf_type type; 781 781 ··· 790 790 .statfs = simple_statfs, 791 791 .drop_inode = inode_just_drop, 792 792 .show_options = bpf_show_options, 793 - .free_inode = bpf_free_inode, 793 + .destroy_inode = bpf_destroy_inode, 794 794 }; 795 795 796 796 enum {
+2
net/core/filter.c
··· 2281 2281 if (IS_ERR(dst)) 2282 2282 goto out_drop; 2283 2283 2284 + skb_dst_drop(skb); 2284 2285 skb_dst_set(skb, dst); 2285 2286 } else if (nh->nh_family != AF_INET6) { 2286 2287 goto out_drop; ··· 2390 2389 goto out_drop; 2391 2390 } 2392 2391 2392 + skb_dst_drop(skb); 2393 2393 skb_dst_set(skb, &rt->dst); 2394 2394 } 2395 2395
+35 -10
net/xdp/xsk_queue.h
··· 143 143 static inline bool xp_aligned_validate_desc(struct xsk_buff_pool *pool, 144 144 struct xdp_desc *desc) 145 145 { 146 - u64 addr = desc->addr - pool->tx_metadata_len; 147 - u64 len = desc->len + pool->tx_metadata_len; 148 - u64 offset = addr & (pool->chunk_size - 1); 146 + u64 len = desc->len; 147 + u64 addr, offset; 149 148 150 - if (!desc->len) 149 + if (!len) 151 150 return false; 152 151 153 - if (offset + len > pool->chunk_size) 152 + /* Can overflow if desc->addr < pool->tx_metadata_len */ 153 + if (check_sub_overflow(desc->addr, pool->tx_metadata_len, &addr)) 154 + return false; 155 + 156 + offset = addr & (pool->chunk_size - 1); 157 + 158 + /* 159 + * Can't overflow: @offset is guaranteed to be < ``U32_MAX`` 160 + * (pool->chunk_size is ``u32``), @len is guaranteed 161 + * to be <= ``U32_MAX``. 162 + */ 163 + if (offset + len + pool->tx_metadata_len > pool->chunk_size) 154 164 return false; 155 165 156 166 if (addr >= pool->addrs_cnt) ··· 168 158 169 159 if (xp_unused_options_set(desc->options)) 170 160 return false; 161 + 171 162 return true; 172 163 } 173 164 174 165 static inline bool xp_unaligned_validate_desc(struct xsk_buff_pool *pool, 175 166 struct xdp_desc *desc) 176 167 { 177 - u64 addr = xp_unaligned_add_offset_to_addr(desc->addr) - pool->tx_metadata_len; 178 - u64 len = desc->len + pool->tx_metadata_len; 168 + u64 len = desc->len; 169 + u64 addr, end; 179 170 180 - if (!desc->len) 171 + if (!len) 181 172 return false; 182 173 174 + /* Can't overflow: @len is guaranteed to be <= ``U32_MAX`` */ 175 + len += pool->tx_metadata_len; 183 176 if (len > pool->chunk_size) 184 177 return false; 185 178 186 - if (addr >= pool->addrs_cnt || addr + len > pool->addrs_cnt || 187 - xp_desc_crosses_non_contig_pg(pool, addr, len)) 179 + /* Can overflow if desc->addr is close to 0 */ 180 + if (check_sub_overflow(xp_unaligned_add_offset_to_addr(desc->addr), 181 + pool->tx_metadata_len, &addr)) 182 + return false; 183 + 184 + if (addr >= pool->addrs_cnt) 185 + return false; 186 + 187 + /* Can overflow if pool->addrs_cnt is high enough */ 188 + if (check_add_overflow(addr, len, &end) || end > pool->addrs_cnt) 189 + return false; 190 + 191 + if (xp_desc_crosses_non_contig_pg(pool, addr, len)) 188 192 return false; 189 193 190 194 if (xp_unused_options_set(desc->options)) 191 195 return false; 196 + 192 197 return true; 193 198 } 194 199
+1
scripts/bpf_doc.py
··· 788 788 'struct task_struct', 789 789 'struct cgroup', 790 790 'struct path', 791 + 'const struct path', 791 792 'struct btf_ptr', 792 793 'struct inode', 793 794 'struct socket',
+1 -1
tools/include/uapi/linux/bpf.h
··· 4891 4891 * 4892 4892 * **-ENOENT** if the bpf_local_storage cannot be found. 4893 4893 * 4894 - * long bpf_d_path(struct path *path, char *buf, u32 sz) 4894 + * long bpf_d_path(const struct path *path, char *buf, u32 sz) 4895 4895 * Description 4896 4896 * Return full path for given **struct path** object, which 4897 4897 * needs to be the kernel BTF *path* object. The path is
+13 -9
tools/lib/bpf/libbpf_utils.c
··· 148 148 } 149 149 } 150 150 151 - #pragma GCC diagnostic push 152 - #pragma GCC diagnostic ignored "-Wpacked" 153 - #pragma GCC diagnostic ignored "-Wattributes" 154 - struct __packed_u32 { __u32 __val; } __attribute__((packed)); 155 - #pragma GCC diagnostic pop 151 + static inline __u32 get_unaligned_be32(const void *p) 152 + { 153 + __be32 val; 156 154 157 - #define get_unaligned_be32(p) be32_to_cpu((((struct __packed_u32 *)(p))->__val)) 158 - #define put_unaligned_be32(v, p) do { \ 159 - ((struct __packed_u32 *)(p))->__val = cpu_to_be32(v); \ 160 - } while (0) 155 + memcpy(&val, p, sizeof(val)); 156 + return be32_to_cpu(val); 157 + } 158 + 159 + static inline void put_unaligned_be32(__u32 val, void *p) 160 + { 161 + __be32 be_val = cpu_to_be32(val); 162 + 163 + memcpy(p, &be_val, sizeof(be_val)); 164 + } 161 165 162 166 #define SHA256_BLOCK_LENGTH 64 163 167 #define Ch(x, y, z) (((x) & (y)) ^ (~(x) & (z)))
+36
tools/testing/selftests/bpf/prog_tests/pinning_htab.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + 3 + #include <test_progs.h> 4 + #include "test_pinning_htab.skel.h" 5 + 6 + static void unpin_map(const char *map_name, const char *pin_path) 7 + { 8 + struct test_pinning_htab *skel; 9 + struct bpf_map *map; 10 + int err; 11 + 12 + skel = test_pinning_htab__open_and_load(); 13 + if (!ASSERT_OK_PTR(skel, "skel open_and_load")) 14 + return; 15 + 16 + map = bpf_object__find_map_by_name(skel->obj, map_name); 17 + if (!ASSERT_OK_PTR(map, "bpf_object__find_map_by_name")) 18 + goto out; 19 + 20 + err = bpf_map__pin(map, pin_path); 21 + if (!ASSERT_OK(err, "bpf_map__pin")) 22 + goto out; 23 + 24 + err = bpf_map__unpin(map, pin_path); 25 + ASSERT_OK(err, "bpf_map__unpin"); 26 + out: 27 + test_pinning_htab__destroy(skel); 28 + } 29 + 30 + void test_pinning_htab(void) 31 + { 32 + if (test__start_subtest("timer_prealloc")) 33 + unpin_map("timer_prealloc", "/sys/fs/bpf/timer_prealloc"); 34 + if (test__start_subtest("timer_no_prealloc")) 35 + unpin_map("timer_no_prealloc", "/sys/fs/bpf/timer_no_prealloc"); 36 + }
+25
tools/testing/selftests/bpf/progs/test_pinning_htab.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + 3 + #include "vmlinux.h" 4 + #include <bpf/bpf_helpers.h> 5 + 6 + char _license[] SEC("license") = "GPL"; 7 + 8 + struct timer_val { 9 + struct bpf_timer timer; 10 + }; 11 + 12 + struct { 13 + __uint(type, BPF_MAP_TYPE_HASH); 14 + __type(key, __u32); 15 + __type(value, struct timer_val); 16 + __uint(max_entries, 1); 17 + } timer_prealloc SEC(".maps"); 18 + 19 + struct { 20 + __uint(type, BPF_MAP_TYPE_HASH); 21 + __type(key, __u32); 22 + __type(value, struct timer_val); 23 + __uint(max_entries, 1); 24 + __uint(map_flags, BPF_F_NO_PREALLOC); 25 + } timer_no_prealloc SEC(".maps");
+1 -1
tools/testing/selftests/bpf/progs/verifier_vfs_accept.c
··· 70 70 int BPF_PROG(path_d_path_from_file_argument, struct file *file) 71 71 { 72 72 int ret; 73 - struct path *path; 73 + const struct path *path; 74 74 75 75 /* The f_path member is a path which is embedded directly within a 76 76 * file. Therefore, a pointer to such embedded members are still