Skip to content

Commit 67be665

Browse files
anakryikogregkh
authored andcommitted
bpf: Prevent writable memory-mapping of read-only ringbuf pages
commit 04ea308 upstream. Only the very first page of BPF ringbuf that contains consumer position counter is supposed to be mapped as writeable by user-space. Producer position is read-only and can be modified only by the kernel code. BPF ringbuf data pages are read-only as well and are not meant to be modified by user-code to maintain integrity of per-record headers. This patch allows to map only consumer position page as writeable and everything else is restricted to be read-only. remap_vmalloc_range() internally adds VM_DONTEXPAND, so all the established memory mappings can't be extended, which prevents any future violations through mremap()'ing. Fixes: 457f443 ("bpf: Implement BPF ring buffer and verifier support for it") Reported-by: Ryota Shiga (Flatt Security) Reported-by: Thadeu Lima de Souza Cascardo <[email protected]> Signed-off-by: Andrii Nakryiko <[email protected]> Signed-off-by: Daniel Borkmann <[email protected]> Acked-by: Alexei Starovoitov <[email protected]> Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent 646f2a9 commit 67be665

File tree

1 file changed

+8
-13
lines changed

1 file changed

+8
-13
lines changed

kernel/bpf/ringbuf.c

Lines changed: 8 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -221,25 +221,20 @@ static int ringbuf_map_get_next_key(struct bpf_map *map, void *key,
221221
return -ENOTSUPP;
222222
}
223223

224-
static size_t bpf_ringbuf_mmap_page_cnt(const struct bpf_ringbuf *rb)
225-
{
226-
size_t data_pages = (rb->mask + 1) >> PAGE_SHIFT;
227-
228-
/* consumer page + producer page + 2 x data pages */
229-
return RINGBUF_POS_PAGES + 2 * data_pages;
230-
}
231-
232224
static int ringbuf_map_mmap(struct bpf_map *map, struct vm_area_struct *vma)
233225
{
234226
struct bpf_ringbuf_map *rb_map;
235-
size_t mmap_sz;
236227

237228
rb_map = container_of(map, struct bpf_ringbuf_map, map);
238-
mmap_sz = bpf_ringbuf_mmap_page_cnt(rb_map->rb) << PAGE_SHIFT;
239-
240-
if (vma->vm_pgoff * PAGE_SIZE + (vma->vm_end - vma->vm_start) > mmap_sz)
241-
return -EINVAL;
242229

230+
if (vma->vm_flags & VM_WRITE) {
231+
/* allow writable mapping for the consumer_pos only */
232+
if (vma->vm_pgoff != 0 || vma->vm_end - vma->vm_start != PAGE_SIZE)
233+
return -EPERM;
234+
} else {
235+
vma->vm_flags &= ~VM_MAYWRITE;
236+
}
237+
/* remap_vmalloc_range() checks size and offset constraints */
243238
return remap_vmalloc_range(vma, rb_map->rb,
244239
vma->vm_pgoff + RINGBUF_PGOFF);
245240
}

0 commit comments

Comments
 (0)