FAILED: patch "[PATCH] bpf: Prevent mmap()'ing read-only maps as writable" failed to apply to 5.6-stable tree
Subsystems (5)
[email protected]
maintainerThe patch below does not apply to the 5.6-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From dfeb376dd4cb2c5004aeb625e2475f58a5ff2ea7 Mon Sep 17 00:00:00 2001
From: Andrii Nakryiko <[email protected]>
Date: Mon, 18 May 2020 22:38:24 -0700
Subject: [PATCH] bpf: Prevent mmap()'ing read-only maps as writable
As discussed in [0], it's dangerous to allow mapping BPF map, that's meant to be frozen and is read-only on BPF program side, because that allows user-space to actually store a writable view to the page even after it is frozen. This is exacerbated by BPF verifier making a strong assumption that contents of such frozen map will remain unchanged. To prevent this, disallow mapping BPF_F_RDONLY_PROG mmap()'able BPF maps as writable, ever.
[0] https://lore.kernel.org/bpf/CAEf4BzYGWYhXdp6BJ7_=9OQPJxQpgug080MMjdSB72i9R+5c6g@mail.gmail.com/
kernel/bpf/syscall.c +14 -3
@@ -623,9 +623,20 @@ static int bpf_map_mmap(struct file *filp, struct vm_area_struct *vma)mutex_lock (&map->freeze_mutex); -if ((vma->vm_flags &VM_WRITE ) && map->frozen) { - err = -EPERM ; - goto out; +if (vma->vm_flags &VM_WRITE ) { +if (map->frozen) { + err = -EPERM ; + goto out; + } +/* map is meant to be read-only, so do not allow mapping as +* writable, because it's possible to leak a writable page +* reference and allows user-space to still modify it after +* freezing, while verifier will assume contents do not change +*/ +if (map->map_flags &BPF_F_RDONLY_PROG ) { + err = -EACCES ; + goto out; + } }/* set default open/close callbacks */
tools/testing/selftests/bpf/prog_tests/mmap.c +12 -1
@@ -19,7 +19,7 @@ void test_mmap(void)const size_t map_sz =roundup_page (sizeof (struct map_data ));const int zero =0 , one =1 , two =2 , far =1500 ;const long page_size =sysconf (_SC_PAGE_SIZE); -int err, duration =0 , i, data_map_fd, data_map_id, tmp_fd; +int err, duration =0 , i, data_map_fd, data_map_id, tmp_fd, rdmap_fd;struct bpf_map *data_map, *bss_map;void *bss_mmaped =NULL , *map_mmaped =NULL , *tmp1, *tmp2;struct test_mmap__bss *bss_data;
@@ -37,6 +37,17 @@ void test_mmap(void) data_map = skel->maps.data_map; data_map_fd =bpf_map__fd (data_map); + rdmap_fd =bpf_map__fd (skel->maps.rdonly_map); + tmp1 =mmap (NULL ,4096 ,PROT_READ |PROT_WRITE ,MAP_SHARED , rdmap_fd,0 ); +if (CHECK (tmp1 !=MAP_FAILED ,"rdonly_write_mmap" ,"unexpected success\n" )) { +munmap (tmp1,4096 ); + goto cleanup; + } +/* now double-check if it's mmap()'able at all */ + tmp1 =mmap (NULL ,4096 ,PROT_READ ,MAP_SHARED , rdmap_fd,0 ); +if (CHECK (tmp1 ==MAP_FAILED ,"rdonly_read_mmap" ,"failed: %d\n" , errno)) + goto cleanup; +/* get map's ID */ memset (&map_info,0 , map_info_sz); err =bpf_obj_get_info_by_fd (data_map_fd, &map_info, &map_info_sz);
tools/testing/selftests/bpf/progs/test_mmap.c +8 -0
@@ -7,6 +7,14 @@ char _license[] SEC("license") = "GPL"; +struct { + __uint(type, BPF_MAP_TYPE_ARRAY); + __uint(max_entries, 4096); + __uint(map_flags, BPF_F_MMAPABLE | BPF_F_RDONLY_PROG); + __type(key, __u32); + __type(value, char); +} rdonly_map SEC(".maps"); +struct { __uint(type, BPF_MAP_TYPE_ARRAY); __uint(max_entries, 512 * 4); /* at least 4 pages of data */
Sasha Levin
maintainerQuoted 24 lines · On Mon, May 25, 2020 at 04:39:40PM +0200, [email protected] wrote:
The patch below does not apply to the 5.6-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From
dfeb376dd4cb2c5004aeb625e2475f58a5ff2ea7Mon Sep 17 00:00:00 2001
From: Andrii Nakryiko <[email protected]>
Date: Mon, 18 May 2020 22:38:24 -0700
Subject: [PATCH] bpf: Prevent mmap()'ing read-only maps as writableAs discussed in [0], it's dangerous to allow mapping BPF map, that's meant to be frozen and is read-only on BPF program side, because that allows user-space to actually store a writable view to the page even after it is frozen. This is exacerbated by BPF verifier making a strong assumption that contents of such frozen map will remain unchanged. To prevent this, disallow mapping
BPF_F_RDONLY_PROGmmap()'able BPF maps as writable, ever.
Quoted 8 lines
[0] https://lore.kernel.org/bpf/CAEf4BzYGWYhXdp6BJ7_=9OQPJxQpgug080MMjdSB72i9R+5c6g@mail.gmail.com/
Fixes fc9702273e2e ("bpf: Add mmap() support for BPF_MAP_TYPE_ARRAY")Suggested-by Jann Horn <[email protected]>Signed-off-by Andrii Nakryiko <[email protected]>Signed-off-by Alexei Starovoitov <[email protected]>Reviewed-by Jann Horn <[email protected]>
I've adjusted context in the selftest update and queued it up.
Signature · 2 lines
Thanks, Sasha