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. ====================
Showing the changes to kernel (2 of 12 files). Show all
Unified · Split
| @@ -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 | } |