BPF ringbuf assumes the size to be a multiple of page size and the power of 2 value. The latter is important to avoid division while calculating position inside the ring buffer and using (N-1) mask instead. This patch fixes omission to enforce power-of-2 size rule.
Showing the changes to kernel (1 of 1 file). Show all
Unified · Split
| @@ -132,15 +132,6 @@ static struct bpf_ringbuf *bpf_ringbuf_alloc(size_t data_sz, int numa_node) · 131 unmodified lines | |||
| 132 | { | 132 | { |
| 133 | struct bpf_ringbuf *rb; | 133 | struct bpf_ringbuf *rb; |
| 134 | 134 | ||
| 135 | if (!data_sz || !PAGE_ALIGNED(data_sz)) | ||
| 136 | return ERR_PTR(-EINVAL); | ||
| 137 | |||
| 138 | #ifdef CONFIG_64BIT | ||
| 139 | /* on 32-bit arch, it's impossible to overflow record's hdr->pgoff */ | ||
| 140 | if (data_sz > RINGBUF_MAX_DATA_SZ) | ||
| 141 | return ERR_PTR(-E2BIG); | ||
| 142 | #endif | ||
| 143 | |||
| 144 | rb = bpf_ringbuf_area_alloc(data_sz, numa_node); | 135 | rb = bpf_ringbuf_area_alloc(data_sz, numa_node); |
| 145 | if (!rb) | 136 | if (!rb) |
| 146 | return ERR_PTR(-ENOMEM); | 137 | return ERR_PTR(-ENOMEM); |
| @@ -166,9 +157,16 @@ static struct bpf_map *ringbuf_map_alloc(union bpf_attr *attr) · 19 unmodified lines | |||
| 166 | return ERR_PTR(-EINVAL); | 157 | return ERR_PTR(-EINVAL); |
| 167 | 158 | ||
| 168 | if (attr->key_size || attr->value_size || | 159 | if (attr->key_size || attr->value_size || |
| 169 | attr->max_entries == 0 || !PAGE_ALIGNED(attr->max_entries)) | 160 | !is_power_of_2(attr->max_entries) || |
| 161 | !PAGE_ALIGNED(attr->max_entries)) | ||
| 170 | return ERR_PTR(-EINVAL); | 162 | return ERR_PTR(-EINVAL); |
| 171 | 163 | ||
| 164 | #ifdef CONFIG_64BIT | ||
| 165 | /* on 32-bit arch, it's impossible to overflow record's hdr->pgoff */ | ||
| 166 | if (attr->max_entries > RINGBUF_MAX_DATA_SZ) | ||
| 167 | return ERR_PTR(-E2BIG); | ||
| 168 | #endif | ||
| 169 | |||
| 172 | rb_map = kzalloc(sizeof(*rb_map), GFP_USER); | 170 | rb_map = kzalloc(sizeof(*rb_map), GFP_USER); |
| 173 | if (!rb_map) | 171 | if (!rb_map) |
| 174 | return ERR_PTR(-ENOMEM); | 172 | return ERR_PTR(-ENOMEM); |