Alexei Starovoitov says: ==================== pull-request: bpf 2020-08-21 The following pull-request contains BPF updates for your *net* tree. We've added 11 non-merge commits during the last 5 day(s) which contain a total of 12 files changed, 78 insertions(+), 24 deletions(-). The main changes are: 1) three fixes in BPF task iterator logic, from Yonghong. 2) fix for compressed dwarf sections in vmlinux, from Jiri. 3) fix xdp attach regression, from Andrii. ====================
Unified · Split
| @@ -767,7 +767,7 @@ union bpf_attr { · 766 unmodified lines | ||
| 767 | 767 | * |
| 768 | 768 | * Also, note that **bpf_trace_printk**\ () is slow, and should |
| 769 | 769 | * only be used for debugging purposes. For this reason, a notice |
| 770 | − * bloc (spanning several lines) is printed to kernel logs and | |
| 770 | + * block (spanning several lines) is printed to kernel logs and | |
| 771 | 771 | * states that the helper should not be used "for production use" |
| 772 | 772 | * the first time this helper is used (or more precisely, when |
| 773 | 773 | * **trace_printk**\ () buffers are allocated). For passing values |
| @@ -1033,14 +1033,14 @@ union bpf_attr { · 259 unmodified lines | ||
| 1033 | 1033 | * |
| 1034 | 1034 | * int ret; |
| 1035 | 1035 | * struct bpf_tunnel_key key = {}; |
| 1036 | − * | |
| 1036 | + * | |
| 1037 | 1037 | * ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key), 0); |
| 1038 | 1038 | * if (ret < 0) |
| 1039 | 1039 | * return TC_ACT_SHOT; // drop packet |
| 1040 | − * | |
| 1040 | + * | |
| 1041 | 1041 | * if (key.remote_ipv4 != 0x0a000001) |
| 1042 | 1042 | * return TC_ACT_SHOT; // drop packet |
| 1043 | − * | |
| 1043 | + * | |
| 1044 | 1044 | * return TC_ACT_OK; // accept packet |
| 1045 | 1045 | * |
| 1046 | 1046 | * This interface can also be used with all encapsulation devices |
| @@ -1147,7 +1147,7 @@ union bpf_attr { · 100 unmodified lines | ||
| 1147 | 1147 | * Description |
| 1148 | 1148 | * Retrieve the realm or the route, that is to say the |
| 1149 | 1149 | * **tclassid** field of the destination for the *skb*. The |
| 1150 | − * indentifier retrieved is a user-provided tag, similar to the | |
| 1150 | + * identifier retrieved is a user-provided tag, similar to the | |
| 1151 | 1151 | * one used with the net_cls cgroup (see description for |
| 1152 | 1152 | * **bpf_get_cgroup_classid**\ () helper), but here this tag is |
| 1153 | 1153 | * held by a route (a destination entry), not by a task. |
| @@ -67,6 +67,9 @@ static void bpf_iter_done_stop(struct seq_file *seq) · 66 unmodified lines | ||
| 67 | 67 | iter_priv->done_stop = true; |
| 68 | 68 | } |
| 69 | 69 | |
| 70 | +/* maximum visited objects before bailing out */ | |
| 71 | +#define MAX_ITER_OBJECTS 1000000 | |
| 72 | + | |
| 70 | 73 | /* bpf_seq_read, a customized and simpler version for bpf iterator. |
| 71 | 74 | * no_llseek is assumed for this file. |
| 72 | 75 | * The following are differences from seq_read(): |
| @@ -79,7 +82,7 @@ static ssize_t bpf_seq_read(struct file *file, char __user *buf, size_t size, · 6 unmodified lines | ||
| 79 | 82 | { |
| 80 | 83 | struct seq_file *seq = file->private_data; |
| 81 | 84 | size_t n, offs, copied = 0; |
| 82 | − int err = 0; | |
| 85 | + int err = 0, num_objs = 0; | |
| 83 | 86 | void *p; |
| 84 | 87 | |
| 85 | 88 | mutex_lock(&seq->lock); |
| @@ -135,6 +138,7 @@ static ssize_t bpf_seq_read(struct file *file, char __user *buf, size_t size, · 49 unmodified lines | ||
| 135 | 138 | while (1) { |
| 136 | 139 | loff_t pos = seq->index; |
| 137 | 140 | |
| 141 | + num_objs++; | |
| 138 | 142 | offs = seq->count; |
| 139 | 143 | p = seq->op->next(seq, p, &seq->index); |
| 140 | 144 | if (pos == seq->index) { |
| @@ -153,6 +157,15 @@ static ssize_t bpf_seq_read(struct file *file, char __user *buf, size_t size, · 12 unmodified lines | ||
| 153 | 157 | if (seq->count >= size) |
| 154 | 158 | break; |
| 155 | 159 | |
| 160 | + if (num_objs >= MAX_ITER_OBJECTS) { | |
| 161 | + if (offs == 0) { | |
| 162 | + err = -EAGAIN; | |
| 163 | + seq->op->stop(seq, p); | |
| 164 | + goto done; | |
| 165 | + } | |
| 166 | + break; | |
| 167 | + } | |
| 168 | + | |
| 156 | 169 | err = seq->op->show(seq, p); |
| 157 | 170 | if (err > 0) { |
| 158 | 171 | bpf_iter_dec_seq_num(seq); |
| @@ -29,8 +29,9 @@ static struct task_struct *task_seq_get_next(struct pid_namespace *ns, · 28 unmodified lines | ||
| 29 | 29 | |
| 30 | 30 | rcu_read_lock(); |
| 31 | 31 | retry: |
| 32 | − pid = idr_get_next(&ns->idr, tid); | |
| 32 | + pid = find_ge_pid(*tid, ns); | |
| 33 | 33 | if (pid) { |
| 34 | + *tid = pid_nr_ns(pid, ns); | |
| 34 | 35 | task = get_pid_task(pid, PIDTYPE_PID); |
| 35 | 36 | if (!task) { |
| 36 | 37 | ++*tid; |
| @@ -178,10 +179,11 @@ again: · 141 unmodified lines | ||
| 178 | 179 | f = fcheck_files(curr_files, curr_fd); |
| 179 | 180 | if (!f) |
| 180 | 181 | continue; |
| 182 | + if (!get_file_rcu(f)) | |
| 183 | + continue; | |
| 181 | 184 | |
| 182 | 185 | /* set info->fd */ |
| 183 | 186 | info->fd = curr_fd; |
| 184 | − get_file(f); | |
| 185 | 187 | rcu_read_unlock(); |
| 186 | 188 | return f; |
| 187 | 189 | } |
| @@ -8742,13 +8742,15 @@ struct bpf_xdp_link { · 8741 unmodified lines | ||
| 8742 | 8742 | int flags; |
| 8743 | 8743 | }; |
| 8744 | 8744 | |
| 8745 | −static enum bpf_xdp_mode dev_xdp_mode(u32 flags) | |
| 8745 | +static enum bpf_xdp_mode dev_xdp_mode(struct net_device *dev, u32 flags) | |
| 8746 | 8746 | { |
| 8747 | 8747 | if (flags & XDP_FLAGS_HW_MODE) |
| 8748 | 8748 | return XDP_MODE_HW; |
| 8749 | 8749 | if (flags & XDP_FLAGS_DRV_MODE) |
| 8750 | 8750 | return XDP_MODE_DRV; |
| 8751 | − return XDP_MODE_SKB; | |
| 8751 | + if (flags & XDP_FLAGS_SKB_MODE) | |
| 8752 | + return XDP_MODE_SKB; | |
| 8753 | + return dev->netdev_ops->ndo_bpf ? XDP_MODE_DRV : XDP_MODE_SKB; | |
| 8752 | 8754 | } |
| 8753 | 8755 | |
| 8754 | 8756 | static bpf_op_t dev_xdp_bpf_op(struct net_device *dev, enum bpf_xdp_mode mode) |
| @@ -8896,7 +8898,7 @@ static int dev_xdp_attach(struct net_device *dev, struct netlink_ext_ack *extack · 141 unmodified lines | ||
| 8896 | 8898 | return -EINVAL; |
| 8897 | 8899 | } |
| 8898 | 8900 | |
| 8899 | − mode = dev_xdp_mode(flags); | |
| 8901 | + mode = dev_xdp_mode(dev, flags); | |
| 8900 | 8902 | /* can't replace attached link */ |
| 8901 | 8903 | if (dev_xdp_link(dev, mode)) { |
| 8902 | 8904 | NL_SET_ERR_MSG(extack, "Can't replace active BPF XDP link"); |
| @@ -8984,7 +8986,7 @@ static int dev_xdp_detach_link(struct net_device *dev, · 81 unmodified lines | ||
| 8984 | 8986 | |
| 8985 | 8987 | ASSERT_RTNL(); |
| 8986 | 8988 | |
| 8987 | − mode = dev_xdp_mode(link->flags); | |
| 8989 | + mode = dev_xdp_mode(dev, link->flags); | |
| 8988 | 8990 | if (dev_xdp_link(dev, mode) != link) |
| 8989 | 8991 | return -EINVAL; |
| 8990 | 8992 | |
| @@ -9080,7 +9082,7 @@ static int bpf_xdp_link_update(struct bpf_link *link, struct bpf_prog *new_prog, · 89 unmodified lines | ||
| 9080 | 9082 | goto out_unlock; |
| 9081 | 9083 | } |
| 9082 | 9084 | |
| 9083 | − mode = dev_xdp_mode(xdp_link->flags); | |
| 9085 | + mode = dev_xdp_mode(xdp_link->dev, xdp_link->flags); | |
| 9084 | 9086 | bpf_op = dev_xdp_bpf_op(xdp_link->dev, mode); |
| 9085 | 9087 | err = dev_xdp_install(xdp_link->dev, mode, bpf_op, NULL, |
| 9086 | 9088 | xdp_link->flags, new_prog); |
| @@ -9164,7 +9166,7 @@ out_put_dev: · 77 unmodified lines | ||
| 9164 | 9166 | int dev_change_xdp_fd(struct net_device *dev, struct netlink_ext_ack *extack, |
| 9165 | 9167 | int fd, int expected_fd, u32 flags) |
| 9166 | 9168 | { |
| 9167 | − enum bpf_xdp_mode mode = dev_xdp_mode(flags); | |
| 9169 | + enum bpf_xdp_mode mode = dev_xdp_mode(dev, flags); | |
| 9168 | 9170 | struct bpf_prog *new_prog = NULL, *old_prog = NULL; |
| 9169 | 9171 | int err; |
| 9170 | 9172 | |
| @@ -134,6 +134,8 @@ int build_obj_refs_table(struct obj_refs_table *table, enum bpf_obj_type type) · 133 unmodified lines | ||
| 134 | 134 | while (true) { |
| 135 | 135 | ret = read(fd, buf, sizeof(buf)); |
| 136 | 136 | if (ret < 0) { |
| 137 | + if (errno == EAGAIN) | |
| 138 | + continue; | |
| 137 | 139 | err = -errno; |
| 138 | 140 | p_err("failed to read PID iterator output: %d", err); |
| 139 | 141 | goto out; |
| @@ -233,6 +233,39 @@ static struct btf_id *add_symbol(struct rb_root *root, char *name, size_t size) · 232 unmodified lines | ||
| 233 | 233 | return btf_id__add(root, id, false); |
| 234 | 234 | } |
| 235 | 235 | |
| 236 | +/* | |
| 237 | + * The data of compressed section should be aligned to 4 | |
| 238 | + * (for 32bit) or 8 (for 64 bit) bytes. The binutils ld | |
| 239 | + * sets sh_addralign to 1, which makes libelf fail with | |
| 240 | + * misaligned section error during the update: | |
| 241 | + * FAILED elf_update(WRITE): invalid section alignment | |
| 242 | + * | |
| 243 | + * While waiting for ld fix, we fix the compressed sections | |
| 244 | + * sh_addralign value manualy. | |
| 245 | + */ | |
| 246 | +static int compressed_section_fix(Elf *elf, Elf_Scn *scn, GElf_Shdr *sh) | |
| 247 | +{ | |
| 248 | + int expected = gelf_getclass(elf) == ELFCLASS32 ? 4 : 8; | |
| 249 | + | |
| 250 | + if (!(sh->sh_flags & SHF_COMPRESSED)) | |
| 251 | + return 0; | |
| 252 | + | |
| 253 | + if (sh->sh_addralign == expected) | |
| 254 | + return 0; | |
| 255 | + | |
| 256 | + pr_debug2(" - fixing wrong alignment sh_addralign %u, expected %u\n", | |
| 257 | + sh->sh_addralign, expected); | |
| 258 | + | |
| 259 | + sh->sh_addralign = expected; | |
| 260 | + | |
| 261 | + if (gelf_update_shdr(scn, sh) == 0) { | |
| 262 | + printf("FAILED cannot update section header: %s\n", | |
| 263 | + elf_errmsg(-1)); | |
| 264 | + return -1; | |
| 265 | + } | |
| 266 | + return 0; | |
| 267 | +} | |
| 268 | + | |
| 236 | 269 | static int elf_collect(struct object *obj) |
| 237 | 270 | { |
| 238 | 271 | Elf_Scn *scn = NULL; |
| @@ -309,6 +342,9 @@ static int elf_collect(struct object *obj) · 70 unmodified lines | ||
| 309 | 342 | obj->efile.idlist_shndx = idx; |
| 310 | 343 | obj->efile.idlist_addr = sh.sh_addr; |
| 311 | 344 | } |
| 345 | + | |
| 346 | + if (compressed_section_fix(elf, scn, &sh)) | |
| 347 | + return -1; | |
| 312 | 348 | } |
| 313 | 349 | |
| 314 | 350 | return 0; |
| @@ -767,7 +767,7 @@ union bpf_attr { · 766 unmodified lines | ||
| 767 | 767 | * |
| 768 | 768 | * Also, note that **bpf_trace_printk**\ () is slow, and should |
| 769 | 769 | * only be used for debugging purposes. For this reason, a notice |
| 770 | − * bloc (spanning several lines) is printed to kernel logs and | |
| 770 | + * block (spanning several lines) is printed to kernel logs and | |
| 771 | 771 | * states that the helper should not be used "for production use" |
| 772 | 772 | * the first time this helper is used (or more precisely, when |
| 773 | 773 | * **trace_printk**\ () buffers are allocated). For passing values |
| @@ -1033,14 +1033,14 @@ union bpf_attr { · 259 unmodified lines | ||
| 1033 | 1033 | * |
| 1034 | 1034 | * int ret; |
| 1035 | 1035 | * struct bpf_tunnel_key key = {}; |
| 1036 | − * | |
| 1036 | + * | |
| 1037 | 1037 | * ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key), 0); |
| 1038 | 1038 | * if (ret < 0) |
| 1039 | 1039 | * return TC_ACT_SHOT; // drop packet |
| 1040 | − * | |
| 1040 | + * | |
| 1041 | 1041 | * if (key.remote_ipv4 != 0x0a000001) |
| 1042 | 1042 | * return TC_ACT_SHOT; // drop packet |
| 1043 | − * | |
| 1043 | + * | |
| 1044 | 1044 | * return TC_ACT_OK; // accept packet |
| 1045 | 1045 | * |
| 1046 | 1046 | * This interface can also be used with all encapsulation devices |
| @@ -1147,7 +1147,7 @@ union bpf_attr { · 100 unmodified lines | ||
| 1147 | 1147 | * Description |
| 1148 | 1148 | * Retrieve the realm or the route, that is to say the |
| 1149 | 1149 | * **tclassid** field of the destination for the *skb*. The |
| 1150 | − * indentifier retrieved is a user-provided tag, similar to the | |
| 1150 | + * identifier retrieved is a user-provided tag, similar to the | |
| 1151 | 1151 | * one used with the net_cls cgroup (see description for |
| 1152 | 1152 | * **bpf_get_cgroup_classid**\ () helper), but here this tag is |
| 1153 | 1153 | * held by a route (a destination entry), not by a task. |
| @@ -879,7 +879,7 @@ static void btf_dump_emit_struct_def(struct btf_dump *d, · 878 unmodified lines | ||
| 879 | 879 | btf_dump_printf(d, ": %d", m_sz); |
| 880 | 880 | off = m_off + m_sz; |
| 881 | 881 | } else { |
| 882 | − m_sz = max(0LL, btf__resolve_size(d->btf, m->type)); | |
| 882 | + m_sz = max((__s64)0, btf__resolve_size(d->btf, m->type)); | |
| 883 | 883 | off = m_off + m_sz * 8; |
| 884 | 884 | } |
| 885 | 885 | btf_dump_printf(d, ";"); |
| @@ -2264,7 +2264,7 @@ static int bpf_object__init_user_btf_maps(struct bpf_object *obj, bool strict, · 2263 unmodified lines | ||
| 2264 | 2264 | data = elf_getdata(scn, NULL); |
| 2265 | 2265 | if (!scn || !data) { |
| 2266 | 2266 | pr_warn("failed to get Elf_Data from map section %d (%s)\n", |
| 2267 | − obj->efile.maps_shndx, MAPS_ELF_SEC); | |
| 2267 | + obj->efile.btf_maps_shndx, MAPS_ELF_SEC); | |
| 2268 | 2268 | return -EINVAL; |
| 2269 | 2269 | } |
| 2270 | 2270 | |
| @@ -6,7 +6,6 @@ test_lpm_map · 5 unmodified lines | ||
| 6 | 6 | test_tag |
| 7 | 7 | FEATURE-DUMP.libbpf |
| 8 | 8 | fixdep |
| 9 | −test_align | |
| 10 | 9 | test_dev_cgroup |
| 11 | 10 | /test_progs* |
| 12 | 11 | test_tcpbpf_user |
| @@ -32,7 +32,7 @@ LDLIBS += -lcap -lelf -lz -lrt -lpthread · 31 unmodified lines | ||
| 32 | 32 | |
| 33 | 33 | # Order correspond to 'make run_tests' order |
| 34 | 34 | TEST_GEN_PROGS = test_verifier test_tag test_maps test_lru_map test_lpm_map test_progs \ |
| 35 | − test_align test_verifier_log test_dev_cgroup test_tcpbpf_user \ | |
| 35 | + test_verifier_log test_dev_cgroup test_tcpbpf_user \ | |
| 36 | 36 | test_sock test_btf test_sockmap get_cgroup_id_user test_socket_cookie \ |
| 37 | 37 | test_cgroup_storage \ |
| 38 | 38 | test_netcnt test_tcpnotify_user test_sock_fields test_sysctl \ |
| @@ -19,7 +19,7 @@ static int libbpf_debug_print(enum libbpf_print_level level, · 18 unmodified lines | ||
| 19 | 19 | log_buf = va_arg(args, char *); |
| 20 | 20 | if (!log_buf) |
| 21 | 21 | goto out; |
| 22 | − if (strstr(log_buf, err_str) == 0) | |
| 22 | + if (err_str && strstr(log_buf, err_str) == 0) | |
| 23 | 23 | found = true; |
| 24 | 24 | out: |
| 25 | 25 | printf(format, log_buf); |