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 | iter_priv->done_stop = true; | 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 | /* bpf_seq_read, a customized and simpler version for bpf iterator. | 73 | /* bpf_seq_read, a customized and simpler version for bpf iterator. |
| 71 | * no_llseek is assumed for this file. | 74 | * no_llseek is assumed for this file. |
| 72 | * The following are differences from seq_read(): | 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 | struct seq_file *seq = file->private_data; | 83 | struct seq_file *seq = file->private_data; |
| 81 | size_t n, offs, copied = 0; | 84 | size_t n, offs, copied = 0; |
| 82 | int err = 0; | 85 | int err = 0, num_objs = 0; |
| 83 | void *p; | 86 | void *p; |
| 84 | 87 | ||
| 85 | mutex_lock(&seq->lock); | 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 | while (1) { | 138 | while (1) { |
| 136 | loff_t pos = seq->index; | 139 | loff_t pos = seq->index; |
| 137 | 140 | ||
| 141 | num_objs++; | ||
| 138 | offs = seq->count; | 142 | offs = seq->count; |
| 139 | p = seq->op->next(seq, p, &seq->index); | 143 | p = seq->op->next(seq, p, &seq->index); |
| 140 | if (pos == seq->index) { | 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 | if (seq->count >= size) | 157 | if (seq->count >= size) |
| 154 | break; | 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 | err = seq->op->show(seq, p); | 169 | err = seq->op->show(seq, p); |
| 157 | if (err > 0) { | 170 | if (err > 0) { |
| 158 | bpf_iter_dec_seq_num(seq); | 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 | rcu_read_lock(); | 30 | rcu_read_lock(); |
| 31 | retry: | 31 | retry: |
| 32 | pid = idr_get_next(&ns->idr, tid); | 32 | pid = find_ge_pid(*tid, ns); |
| 33 | if (pid) { | 33 | if (pid) { |
| 34 | *tid = pid_nr_ns(pid, ns); | ||
| 34 | task = get_pid_task(pid, PIDTYPE_PID); | 35 | task = get_pid_task(pid, PIDTYPE_PID); |
| 35 | if (!task) { | 36 | if (!task) { |
| 36 | ++*tid; | 37 | ++*tid; |
| @@ -178,10 +179,11 @@ again: · 141 unmodified lines | |||
| 178 | f = fcheck_files(curr_files, curr_fd); | 179 | f = fcheck_files(curr_files, curr_fd); |
| 179 | if (!f) | 180 | if (!f) |
| 180 | continue; | 181 | continue; |
| 182 | if (!get_file_rcu(f)) | ||
| 183 | continue; | ||
| 181 | 184 | ||
| 182 | /* set info->fd */ | 185 | /* set info->fd */ |
| 183 | info->fd = curr_fd; | 186 | info->fd = curr_fd; |
| 184 | get_file(f); | ||
| 185 | rcu_read_unlock(); | 187 | rcu_read_unlock(); |
| 186 | return f; | 188 | return f; |
| 187 | } | 189 | } |