]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
5.7-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 14 Jul 2020 08:21:23 +0000 (10:21 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 14 Jul 2020 08:21:23 +0000 (10:21 +0200)
added patches:
bpf-check-correct-cred-for-cap_syslog-in-bpf_dump_raw_ok.patch
io_uring-account-user-memory-freed-when-exit-has-been-queued.patch
io_uring-fix-memleak-in-__io_sqe_files_update.patch
io_uring-fix-memleak-in-io_sqe_files_register.patch
io_uring-fix-missing-msg_name-assignment.patch
kallsyms-refactor-kallsyms_show_value-to-take-cred.patch
kprobes-do-not-expose-probe-addresses-to-non-cap_syslog.patch
module-do-not-expose-section-addresses-to-non-cap_syslog.patch
module-refactor-section-attr-into-bin-attribute.patch

queue-5.7/bpf-check-correct-cred-for-cap_syslog-in-bpf_dump_raw_ok.patch [new file with mode: 0644]
queue-5.7/io_uring-account-user-memory-freed-when-exit-has-been-queued.patch [new file with mode: 0644]
queue-5.7/io_uring-fix-memleak-in-__io_sqe_files_update.patch [new file with mode: 0644]
queue-5.7/io_uring-fix-memleak-in-io_sqe_files_register.patch [new file with mode: 0644]
queue-5.7/io_uring-fix-missing-msg_name-assignment.patch [new file with mode: 0644]
queue-5.7/kallsyms-refactor-kallsyms_show_value-to-take-cred.patch [new file with mode: 0644]
queue-5.7/kprobes-do-not-expose-probe-addresses-to-non-cap_syslog.patch [new file with mode: 0644]
queue-5.7/module-do-not-expose-section-addresses-to-non-cap_syslog.patch [new file with mode: 0644]
queue-5.7/module-refactor-section-attr-into-bin-attribute.patch [new file with mode: 0644]
queue-5.7/series

diff --git a/queue-5.7/bpf-check-correct-cred-for-cap_syslog-in-bpf_dump_raw_ok.patch b/queue-5.7/bpf-check-correct-cred-for-cap_syslog-in-bpf_dump_raw_ok.patch
new file mode 100644 (file)
index 0000000..ce497e8
--- /dev/null
@@ -0,0 +1,175 @@
+From 63960260457a02af2a6cb35d75e6bdb17299c882 Mon Sep 17 00:00:00 2001
+From: Kees Cook <keescook@chromium.org>
+Date: Thu, 2 Jul 2020 15:45:23 -0700
+Subject: bpf: Check correct cred for CAP_SYSLOG in bpf_dump_raw_ok()
+
+From: Kees Cook <keescook@chromium.org>
+
+commit 63960260457a02af2a6cb35d75e6bdb17299c882 upstream.
+
+When evaluating access control over kallsyms visibility, credentials at
+open() time need to be used, not the "current" creds (though in BPF's
+case, this has likely always been the same). Plumb access to associated
+file->f_cred down through bpf_dump_raw_ok() and its callers now that
+kallsysm_show_value() has been refactored to take struct cred.
+
+Cc: Alexei Starovoitov <ast@kernel.org>
+Cc: Daniel Borkmann <daniel@iogearbox.net>
+Cc: bpf@vger.kernel.org
+Cc: stable@vger.kernel.org
+Fixes: 7105e828c087 ("bpf: allow for correlation of maps and helpers in dump")
+Signed-off-by: Kees Cook <keescook@chromium.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ include/linux/filter.h     |    4 ++--
+ kernel/bpf/syscall.c       |   32 ++++++++++++++++++--------------
+ net/core/sysctl_net_core.c |    2 +-
+ 3 files changed, 21 insertions(+), 17 deletions(-)
+
+--- a/include/linux/filter.h
++++ b/include/linux/filter.h
+@@ -888,12 +888,12 @@ void bpf_jit_compile(struct bpf_prog *pr
+ bool bpf_jit_needs_zext(void);
+ bool bpf_helper_changes_pkt_data(void *func);
+-static inline bool bpf_dump_raw_ok(void)
++static inline bool bpf_dump_raw_ok(const struct cred *cred)
+ {
+       /* Reconstruction of call-sites is dependent on kallsyms,
+        * thus make dump the same restriction.
+        */
+-      return kallsyms_show_value(current_cred());
++      return kallsyms_show_value(cred);
+ }
+ struct bpf_prog *bpf_patch_insn_single(struct bpf_prog *prog, u32 off,
+--- a/kernel/bpf/syscall.c
++++ b/kernel/bpf/syscall.c
+@@ -2918,7 +2918,8 @@ static const struct bpf_map *bpf_map_fro
+       return NULL;
+ }
+-static struct bpf_insn *bpf_insn_prepare_dump(const struct bpf_prog *prog)
++static struct bpf_insn *bpf_insn_prepare_dump(const struct bpf_prog *prog,
++                                            const struct cred *f_cred)
+ {
+       const struct bpf_map *map;
+       struct bpf_insn *insns;
+@@ -2944,7 +2945,7 @@ static struct bpf_insn *bpf_insn_prepare
+                   code == (BPF_JMP | BPF_CALL_ARGS)) {
+                       if (code == (BPF_JMP | BPF_CALL_ARGS))
+                               insns[i].code = BPF_JMP | BPF_CALL;
+-                      if (!bpf_dump_raw_ok())
++                      if (!bpf_dump_raw_ok(f_cred))
+                               insns[i].imm = 0;
+                       continue;
+               }
+@@ -3000,7 +3001,8 @@ static int set_info_rec_size(struct bpf_
+       return 0;
+ }
+-static int bpf_prog_get_info_by_fd(struct bpf_prog *prog,
++static int bpf_prog_get_info_by_fd(struct file *file,
++                                 struct bpf_prog *prog,
+                                  const union bpf_attr *attr,
+                                  union bpf_attr __user *uattr)
+ {
+@@ -3069,11 +3071,11 @@ static int bpf_prog_get_info_by_fd(struc
+               struct bpf_insn *insns_sanitized;
+               bool fault;
+-              if (prog->blinded && !bpf_dump_raw_ok()) {
++              if (prog->blinded && !bpf_dump_raw_ok(file->f_cred)) {
+                       info.xlated_prog_insns = 0;
+                       goto done;
+               }
+-              insns_sanitized = bpf_insn_prepare_dump(prog);
++              insns_sanitized = bpf_insn_prepare_dump(prog, file->f_cred);
+               if (!insns_sanitized)
+                       return -ENOMEM;
+               uinsns = u64_to_user_ptr(info.xlated_prog_insns);
+@@ -3107,7 +3109,7 @@ static int bpf_prog_get_info_by_fd(struc
+       }
+       if (info.jited_prog_len && ulen) {
+-              if (bpf_dump_raw_ok()) {
++              if (bpf_dump_raw_ok(file->f_cred)) {
+                       uinsns = u64_to_user_ptr(info.jited_prog_insns);
+                       ulen = min_t(u32, info.jited_prog_len, ulen);
+@@ -3142,7 +3144,7 @@ static int bpf_prog_get_info_by_fd(struc
+       ulen = info.nr_jited_ksyms;
+       info.nr_jited_ksyms = prog->aux->func_cnt ? : 1;
+       if (ulen) {
+-              if (bpf_dump_raw_ok()) {
++              if (bpf_dump_raw_ok(file->f_cred)) {
+                       unsigned long ksym_addr;
+                       u64 __user *user_ksyms;
+                       u32 i;
+@@ -3173,7 +3175,7 @@ static int bpf_prog_get_info_by_fd(struc
+       ulen = info.nr_jited_func_lens;
+       info.nr_jited_func_lens = prog->aux->func_cnt ? : 1;
+       if (ulen) {
+-              if (bpf_dump_raw_ok()) {
++              if (bpf_dump_raw_ok(file->f_cred)) {
+                       u32 __user *user_lens;
+                       u32 func_len, i;
+@@ -3230,7 +3232,7 @@ static int bpf_prog_get_info_by_fd(struc
+       else
+               info.nr_jited_line_info = 0;
+       if (info.nr_jited_line_info && ulen) {
+-              if (bpf_dump_raw_ok()) {
++              if (bpf_dump_raw_ok(file->f_cred)) {
+                       __u64 __user *user_linfo;
+                       u32 i;
+@@ -3276,7 +3278,8 @@ done:
+       return 0;
+ }
+-static int bpf_map_get_info_by_fd(struct bpf_map *map,
++static int bpf_map_get_info_by_fd(struct file *file,
++                                struct bpf_map *map,
+                                 const union bpf_attr *attr,
+                                 union bpf_attr __user *uattr)
+ {
+@@ -3319,7 +3322,8 @@ static int bpf_map_get_info_by_fd(struct
+       return 0;
+ }
+-static int bpf_btf_get_info_by_fd(struct btf *btf,
++static int bpf_btf_get_info_by_fd(struct file *file,
++                                struct btf *btf,
+                                 const union bpf_attr *attr,
+                                 union bpf_attr __user *uattr)
+ {
+@@ -3351,13 +3355,13 @@ static int bpf_obj_get_info_by_fd(const
+               return -EBADFD;
+       if (f.file->f_op == &bpf_prog_fops)
+-              err = bpf_prog_get_info_by_fd(f.file->private_data, attr,
++              err = bpf_prog_get_info_by_fd(f.file, f.file->private_data, attr,
+                                             uattr);
+       else if (f.file->f_op == &bpf_map_fops)
+-              err = bpf_map_get_info_by_fd(f.file->private_data, attr,
++              err = bpf_map_get_info_by_fd(f.file, f.file->private_data, attr,
+                                            uattr);
+       else if (f.file->f_op == &btf_fops)
+-              err = bpf_btf_get_info_by_fd(f.file->private_data, attr, uattr);
++              err = bpf_btf_get_info_by_fd(f.file, f.file->private_data, attr, uattr);
+       else
+               err = -EINVAL;
+--- a/net/core/sysctl_net_core.c
++++ b/net/core/sysctl_net_core.c
+@@ -277,7 +277,7 @@ static int proc_dointvec_minmax_bpf_enab
+       ret = proc_dointvec_minmax(&tmp, write, buffer, lenp, ppos);
+       if (write && !ret) {
+               if (jit_enable < 2 ||
+-                  (jit_enable == 2 && bpf_dump_raw_ok())) {
++                  (jit_enable == 2 && bpf_dump_raw_ok(current_cred()))) {
+                       *(int *)table->data = jit_enable;
+                       if (jit_enable == 2)
+                               pr_warn("bpf_jit_enable = 2 was set! NEVER use this in production, only for JIT debugging!\n");
diff --git a/queue-5.7/io_uring-account-user-memory-freed-when-exit-has-been-queued.patch b/queue-5.7/io_uring-account-user-memory-freed-when-exit-has-been-queued.patch
new file mode 100644 (file)
index 0000000..bed4624
--- /dev/null
@@ -0,0 +1,56 @@
+From 309fc03a3284af62eb6082fb60327045a1dabf57 Mon Sep 17 00:00:00 2001
+From: Jens Axboe <axboe@kernel.dk>
+Date: Fri, 10 Jul 2020 09:13:34 -0600
+Subject: io_uring: account user memory freed when exit has been queued
+
+From: Jens Axboe <axboe@kernel.dk>
+
+commit 309fc03a3284af62eb6082fb60327045a1dabf57 upstream.
+
+We currently account the memory after the exit work has been run, but
+that leaves a gap where a process has closed its ring and until the
+memory has been accounted as freed. If the memlocked ulimit is
+borderline, then that can introduce spurious setup errors returning
+-ENOMEM because the free work hasn't been run yet.
+
+Account this as freed when we close the ring, as not to expose a tiny
+gap where setting up a new ring can fail.
+
+Fixes: 85faa7b8346e ("io_uring: punt final io_ring_ctx wait-and-free to workqueue")
+Cc: stable@vger.kernel.org # v5.7
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/io_uring.c |   13 ++++++++++---
+ 1 file changed, 10 insertions(+), 3 deletions(-)
+
+--- a/fs/io_uring.c
++++ b/fs/io_uring.c
+@@ -7402,9 +7402,6 @@ static void io_ring_ctx_free(struct io_r
+       io_mem_free(ctx->sq_sqes);
+       percpu_ref_exit(&ctx->refs);
+-      if (ctx->account_mem)
+-              io_unaccount_mem(ctx->user,
+-                              ring_pages(ctx->sq_entries, ctx->cq_entries));
+       free_uid(ctx->user);
+       put_cred(ctx->creds);
+       kfree(ctx->completions);
+@@ -7500,6 +7497,16 @@ static void io_ring_ctx_wait_and_kill(st
+       if (ctx->rings)
+               io_cqring_overflow_flush(ctx, true);
+       idr_for_each(&ctx->personality_idr, io_remove_personalities, ctx);
++
++      /*
++       * Do this upfront, so we won't have a grace period where the ring
++       * is closed but resources aren't reaped yet. This can cause
++       * spurious failure in setting up a new ring.
++       */
++      if (ctx->account_mem)
++              io_unaccount_mem(ctx->user,
++                              ring_pages(ctx->sq_entries, ctx->cq_entries));
++
+       INIT_WORK(&ctx->exit_work, io_ring_exit_work);
+       queue_work(system_wq, &ctx->exit_work);
+ }
diff --git a/queue-5.7/io_uring-fix-memleak-in-__io_sqe_files_update.patch b/queue-5.7/io_uring-fix-memleak-in-__io_sqe_files_update.patch
new file mode 100644 (file)
index 0000000..c0852d4
--- /dev/null
@@ -0,0 +1,76 @@
+From f3bd9dae3708a0ff6b067e766073ffeb853301f9 Mon Sep 17 00:00:00 2001
+From: Yang Yingliang <yangyingliang@huawei.com>
+Date: Thu, 9 Jul 2020 10:11:41 +0000
+Subject: io_uring: fix memleak in __io_sqe_files_update()
+
+From: Yang Yingliang <yangyingliang@huawei.com>
+
+commit f3bd9dae3708a0ff6b067e766073ffeb853301f9 upstream.
+
+I got a memleak report when doing some fuzz test:
+
+BUG: memory leak
+unreferenced object 0xffff888113e02300 (size 488):
+comm "syz-executor401", pid 356, jiffies 4294809529 (age 11.954s)
+hex dump (first 32 bytes):
+00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
+a0 a4 ce 19 81 88 ff ff 60 ce 09 0d 81 88 ff ff ........`.......
+backtrace:
+[<00000000129a84ec>] kmem_cache_zalloc include/linux/slab.h:659 [inline]
+[<00000000129a84ec>] __alloc_file+0x25/0x310 fs/file_table.c:101
+[<000000003050ad84>] alloc_empty_file+0x4f/0x120 fs/file_table.c:151
+[<000000004d0a41a3>] alloc_file+0x5e/0x550 fs/file_table.c:193
+[<000000002cb242f0>] alloc_file_pseudo+0x16a/0x240 fs/file_table.c:233
+[<00000000046a4baa>] anon_inode_getfile fs/anon_inodes.c:91 [inline]
+[<00000000046a4baa>] anon_inode_getfile+0xac/0x1c0 fs/anon_inodes.c:74
+[<0000000035beb745>] __do_sys_perf_event_open+0xd4a/0x2680 kernel/events/core.c:11720
+[<0000000049009dc7>] do_syscall_64+0x56/0xa0 arch/x86/entry/common.c:359
+[<00000000353731ca>] entry_SYSCALL_64_after_hwframe+0x44/0xa9
+
+BUG: memory leak
+unreferenced object 0xffff8881152dd5e0 (size 16):
+comm "syz-executor401", pid 356, jiffies 4294809529 (age 11.954s)
+hex dump (first 16 bytes):
+01 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 ................
+backtrace:
+[<0000000074caa794>] kmem_cache_zalloc include/linux/slab.h:659 [inline]
+[<0000000074caa794>] lsm_file_alloc security/security.c:567 [inline]
+[<0000000074caa794>] security_file_alloc+0x32/0x160 security/security.c:1440
+[<00000000c6745ea3>] __alloc_file+0xba/0x310 fs/file_table.c:106
+[<000000003050ad84>] alloc_empty_file+0x4f/0x120 fs/file_table.c:151
+[<000000004d0a41a3>] alloc_file+0x5e/0x550 fs/file_table.c:193
+[<000000002cb242f0>] alloc_file_pseudo+0x16a/0x240 fs/file_table.c:233
+[<00000000046a4baa>] anon_inode_getfile fs/anon_inodes.c:91 [inline]
+[<00000000046a4baa>] anon_inode_getfile+0xac/0x1c0 fs/anon_inodes.c:74
+[<0000000035beb745>] __do_sys_perf_event_open+0xd4a/0x2680 kernel/events/core.c:11720
+[<0000000049009dc7>] do_syscall_64+0x56/0xa0 arch/x86/entry/common.c:359
+[<00000000353731ca>] entry_SYSCALL_64_after_hwframe+0x44/0xa9
+
+If io_sqe_file_register() failed, we need put the file that get by fget()
+to avoid the memleak.
+
+Fixes: c3a31e605620 ("io_uring: add support for IORING_REGISTER_FILES_UPDATE")
+Cc: stable@vger.kernel.org
+Reported-by: Hulk Robot <hulkci@huawei.com>
+Signed-off-by: Yang Yingliang <yangyingliang@huawei.com>
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/io_uring.c |    4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+--- a/fs/io_uring.c
++++ b/fs/io_uring.c
+@@ -6904,8 +6904,10 @@ static int __io_sqe_files_update(struct
+                       }
+                       table->files[index] = file;
+                       err = io_sqe_file_register(ctx, file, i);
+-                      if (err)
++                      if (err) {
++                              fput(file);
+                               break;
++                      }
+               }
+               nr_args--;
+               done++;
diff --git a/queue-5.7/io_uring-fix-memleak-in-io_sqe_files_register.patch b/queue-5.7/io_uring-fix-memleak-in-io_sqe_files_register.patch
new file mode 100644 (file)
index 0000000..f1aa7c4
--- /dev/null
@@ -0,0 +1,47 @@
+From 667e57da358f61b6966e12e925a69e42d912e8bb Mon Sep 17 00:00:00 2001
+From: Yang Yingliang <yangyingliang@huawei.com>
+Date: Fri, 10 Jul 2020 14:14:20 +0000
+Subject: io_uring: fix memleak in io_sqe_files_register()
+
+From: Yang Yingliang <yangyingliang@huawei.com>
+
+commit 667e57da358f61b6966e12e925a69e42d912e8bb upstream.
+
+I got a memleak report when doing some fuzz test:
+
+BUG: memory leak
+unreferenced object 0x607eeac06e78 (size 8):
+  comm "test", pid 295, jiffies 4294735835 (age 31.745s)
+  hex dump (first 8 bytes):
+    00 00 00 00 00 00 00 00                          ........
+  backtrace:
+    [<00000000932632e6>] percpu_ref_init+0x2a/0x1b0
+    [<0000000092ddb796>] __io_uring_register+0x111d/0x22a0
+    [<00000000eadd6c77>] __x64_sys_io_uring_register+0x17b/0x480
+    [<00000000591b89a6>] do_syscall_64+0x56/0xa0
+    [<00000000864a281d>] entry_SYSCALL_64_after_hwframe+0x44/0xa9
+
+Call percpu_ref_exit() on error path to avoid
+refcount memleak.
+
+Fixes: 05f3fb3c5397 ("io_uring: avoid ring quiesce for fixed file set unregister and update")
+Cc: stable@vger.kernel.org
+Reported-by: Hulk Robot <hulkci@huawei.com>
+Signed-off-by: Yang Yingliang <yangyingliang@huawei.com>
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/io_uring.c |    1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/fs/io_uring.c
++++ b/fs/io_uring.c
+@@ -6751,6 +6751,7 @@ static int io_sqe_files_register(struct
+               for (i = 0; i < nr_tables; i++)
+                       kfree(ctx->file_data->table[i].files);
++              percpu_ref_exit(&ctx->file_data->refs);
+               kfree(ctx->file_data->table);
+               kfree(ctx->file_data);
+               ctx->file_data = NULL;
diff --git a/queue-5.7/io_uring-fix-missing-msg_name-assignment.patch b/queue-5.7/io_uring-fix-missing-msg_name-assignment.patch
new file mode 100644 (file)
index 0000000..247323d
--- /dev/null
@@ -0,0 +1,39 @@
+From dd821e0c95a64b5923a0c57f07d3f7563553e756 Mon Sep 17 00:00:00 2001
+From: Pavel Begunkov <asml.silence@gmail.com>
+Date: Sun, 12 Jul 2020 13:23:08 +0300
+Subject: io_uring: fix missing msg_name assignment
+
+From: Pavel Begunkov <asml.silence@gmail.com>
+
+commit dd821e0c95a64b5923a0c57f07d3f7563553e756 upstream.
+
+Ensure to set msg.msg_name for the async portion of send/recvmsg,
+as the header copy will copy to/from it.
+
+Cc: stable@vger.kernel.org # v5.5+
+Signed-off-by: Pavel Begunkov <asml.silence@gmail.com>
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/io_uring.c |    2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/fs/io_uring.c
++++ b/fs/io_uring.c
+@@ -3587,6 +3587,7 @@ static int io_sendmsg_prep(struct io_kio
+       if (req->flags & REQ_F_NEED_CLEANUP)
+               return 0;
++      io->msg.msg.msg_name = &io->msg.addr;
+       io->msg.iov = io->msg.fast_iov;
+       ret = sendmsg_copy_msghdr(&io->msg.msg, sr->msg, sr->msg_flags,
+                                       &io->msg.iov);
+@@ -3774,6 +3775,7 @@ static int __io_compat_recvmsg_copy_hdr(
+ static int io_recvmsg_copy_hdr(struct io_kiocb *req, struct io_async_ctx *io)
+ {
++      io->msg.msg.msg_name = &io->msg.addr;
+       io->msg.iov = io->msg.fast_iov;
+ #ifdef CONFIG_COMPAT
diff --git a/queue-5.7/kallsyms-refactor-kallsyms_show_value-to-take-cred.patch b/queue-5.7/kallsyms-refactor-kallsyms_show_value-to-take-cred.patch
new file mode 100644 (file)
index 0000000..65f4def
--- /dev/null
@@ -0,0 +1,142 @@
+From 160251842cd35a75edfb0a1d76afa3eb674ff40a Mon Sep 17 00:00:00 2001
+From: Kees Cook <keescook@chromium.org>
+Date: Thu, 2 Jul 2020 11:49:23 -0700
+Subject: kallsyms: Refactor kallsyms_show_value() to take cred
+
+From: Kees Cook <keescook@chromium.org>
+
+commit 160251842cd35a75edfb0a1d76afa3eb674ff40a upstream.
+
+In order to perform future tests against the cred saved during open(),
+switch kallsyms_show_value() to operate on a cred, and have all current
+callers pass current_cred(). This makes it very obvious where callers
+are checking the wrong credential in their "read" contexts. These will
+be fixed in the coming patches.
+
+Additionally switch return value to bool, since it is always used as a
+direct permission check, not a 0-on-success, negative-on-error style
+function return.
+
+Cc: stable@vger.kernel.org
+Signed-off-by: Kees Cook <keescook@chromium.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ include/linux/filter.h   |    2 +-
+ include/linux/kallsyms.h |    5 +++--
+ kernel/kallsyms.c        |   17 +++++++++++------
+ kernel/kprobes.c         |    4 ++--
+ kernel/module.c          |    2 +-
+ 5 files changed, 18 insertions(+), 12 deletions(-)
+
+--- a/include/linux/filter.h
++++ b/include/linux/filter.h
+@@ -893,7 +893,7 @@ static inline bool bpf_dump_raw_ok(void)
+       /* Reconstruction of call-sites is dependent on kallsyms,
+        * thus make dump the same restriction.
+        */
+-      return kallsyms_show_value() == 1;
++      return kallsyms_show_value(current_cred());
+ }
+ struct bpf_prog *bpf_patch_insn_single(struct bpf_prog *prog, u32 off,
+--- a/include/linux/kallsyms.h
++++ b/include/linux/kallsyms.h
+@@ -18,6 +18,7 @@
+ #define KSYM_SYMBOL_LEN (sizeof("%s+%#lx/%#lx [%s]") + (KSYM_NAME_LEN - 1) + \
+                        2*(BITS_PER_LONG*3/10) + (MODULE_NAME_LEN - 1) + 1)
++struct cred;
+ struct module;
+ static inline int is_kernel_inittext(unsigned long addr)
+@@ -98,7 +99,7 @@ int lookup_symbol_name(unsigned long add
+ int lookup_symbol_attrs(unsigned long addr, unsigned long *size, unsigned long *offset, char *modname, char *name);
+ /* How and when do we show kallsyms values? */
+-extern int kallsyms_show_value(void);
++extern bool kallsyms_show_value(const struct cred *cred);
+ #else /* !CONFIG_KALLSYMS */
+@@ -158,7 +159,7 @@ static inline int lookup_symbol_attrs(un
+       return -ERANGE;
+ }
+-static inline int kallsyms_show_value(void)
++static inline bool kallsyms_show_value(const struct cred *cred)
+ {
+       return false;
+ }
+--- a/kernel/kallsyms.c
++++ b/kernel/kallsyms.c
+@@ -644,19 +644,20 @@ static inline int kallsyms_for_perf(void
+  * Otherwise, require CAP_SYSLOG (assuming kptr_restrict isn't set to
+  * block even that).
+  */
+-int kallsyms_show_value(void)
++bool kallsyms_show_value(const struct cred *cred)
+ {
+       switch (kptr_restrict) {
+       case 0:
+               if (kallsyms_for_perf())
+-                      return 1;
++                      return true;
+       /* fallthrough */
+       case 1:
+-              if (has_capability_noaudit(current, CAP_SYSLOG))
+-                      return 1;
++              if (security_capable(cred, &init_user_ns, CAP_SYSLOG,
++                                   CAP_OPT_NOAUDIT) == 0)
++                      return true;
+       /* fallthrough */
+       default:
+-              return 0;
++              return false;
+       }
+ }
+@@ -673,7 +674,11 @@ static int kallsyms_open(struct inode *i
+               return -ENOMEM;
+       reset_iter(iter, 0);
+-      iter->show_value = kallsyms_show_value();
++      /*
++       * Instead of checking this on every s_show() call, cache
++       * the result here at open time.
++       */
++      iter->show_value = kallsyms_show_value(file->f_cred);
+       return 0;
+ }
+--- a/kernel/kprobes.c
++++ b/kernel/kprobes.c
+@@ -2362,7 +2362,7 @@ static void report_probe(struct seq_file
+       else
+               kprobe_type = "k";
+-      if (!kallsyms_show_value())
++      if (!kallsyms_show_value(current_cred()))
+               addr = NULL;
+       if (sym)
+@@ -2463,7 +2463,7 @@ static int kprobe_blacklist_seq_show(str
+        * If /proc/kallsyms is not showing kernel address, we won't
+        * show them here either.
+        */
+-      if (!kallsyms_show_value())
++      if (!kallsyms_show_value(current_cred()))
+               seq_printf(m, "0x%px-0x%px\t%ps\n", NULL, NULL,
+                          (void *)ent->start_addr);
+       else
+--- a/kernel/module.c
++++ b/kernel/module.c
+@@ -4348,7 +4348,7 @@ static int modules_open(struct inode *in
+       if (!err) {
+               struct seq_file *m = file->private_data;
+-              m->private = kallsyms_show_value() ? NULL : (void *)8ul;
++              m->private = kallsyms_show_value(current_cred()) ? NULL : (void *)8ul;
+       }
+       return err;
diff --git a/queue-5.7/kprobes-do-not-expose-probe-addresses-to-non-cap_syslog.patch b/queue-5.7/kprobes-do-not-expose-probe-addresses-to-non-cap_syslog.patch
new file mode 100644 (file)
index 0000000..4b1336a
--- /dev/null
@@ -0,0 +1,44 @@
+From 60f7bb66b88b649433bf700acfc60c3f24953871 Mon Sep 17 00:00:00 2001
+From: Kees Cook <keescook@chromium.org>
+Date: Thu, 2 Jul 2020 15:20:22 -0700
+Subject: kprobes: Do not expose probe addresses to non-CAP_SYSLOG
+
+From: Kees Cook <keescook@chromium.org>
+
+commit 60f7bb66b88b649433bf700acfc60c3f24953871 upstream.
+
+The kprobe show() functions were using "current"'s creds instead
+of the file opener's creds for kallsyms visibility. Fix to use
+seq_file->file->f_cred.
+
+Cc: Masami Hiramatsu <mhiramat@kernel.org>
+Cc: stable@vger.kernel.org
+Fixes: 81365a947de4 ("kprobes: Show address of kprobes if kallsyms does")
+Fixes: ffb9bd68ebdb ("kprobes: Show blacklist addresses as same as kallsyms does")
+Signed-off-by: Kees Cook <keescook@chromium.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ kernel/kprobes.c |    4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/kernel/kprobes.c
++++ b/kernel/kprobes.c
+@@ -2362,7 +2362,7 @@ static void report_probe(struct seq_file
+       else
+               kprobe_type = "k";
+-      if (!kallsyms_show_value(current_cred()))
++      if (!kallsyms_show_value(pi->file->f_cred))
+               addr = NULL;
+       if (sym)
+@@ -2463,7 +2463,7 @@ static int kprobe_blacklist_seq_show(str
+        * If /proc/kallsyms is not showing kernel address, we won't
+        * show them here either.
+        */
+-      if (!kallsyms_show_value(current_cred()))
++      if (!kallsyms_show_value(m->file->f_cred))
+               seq_printf(m, "0x%px-0x%px\t%ps\n", NULL, NULL,
+                          (void *)ent->start_addr);
+       else
diff --git a/queue-5.7/module-do-not-expose-section-addresses-to-non-cap_syslog.patch b/queue-5.7/module-do-not-expose-section-addresses-to-non-cap_syslog.patch
new file mode 100644 (file)
index 0000000..443e5a3
--- /dev/null
@@ -0,0 +1,67 @@
+From b25a7c5af9051850d4f3d93ca500056ab6ec724b Mon Sep 17 00:00:00 2001
+From: Kees Cook <keescook@chromium.org>
+Date: Thu, 2 Jul 2020 14:43:59 -0700
+Subject: module: Do not expose section addresses to non-CAP_SYSLOG
+
+From: Kees Cook <keescook@chromium.org>
+
+commit b25a7c5af9051850d4f3d93ca500056ab6ec724b upstream.
+
+The printing of section addresses in /sys/module/*/sections/* was not
+using the correct credentials to evaluate visibility.
+
+Before:
+
+ # cat /sys/module/*/sections/.*text
+ 0xffffffffc0458000
+ ...
+ # capsh --drop=CAP_SYSLOG -- -c "cat /sys/module/*/sections/.*text"
+ 0xffffffffc0458000
+ ...
+
+After:
+
+ # cat /sys/module/*/sections/*.text
+ 0xffffffffc0458000
+ ...
+ # capsh --drop=CAP_SYSLOG -- -c "cat /sys/module/*/sections/.*text"
+ 0x0000000000000000
+ ...
+
+Additionally replaces the existing (safe) /proc/modules check with
+file->f_cred for consistency.
+
+Reported-by: Dominik Czarnota <dominik.czarnota@trailofbits.com>
+Fixes: be71eda5383f ("module: Fix display of wrong module .text address")
+Cc: stable@vger.kernel.org
+Tested-by: Jessica Yu <jeyu@kernel.org>
+Acked-by: Jessica Yu <jeyu@kernel.org>
+Signed-off-by: Kees Cook <keescook@chromium.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ kernel/module.c |    6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+--- a/kernel/module.c
++++ b/kernel/module.c
+@@ -1527,8 +1527,8 @@ static ssize_t module_sect_read(struct f
+       if (pos != 0)
+               return -EINVAL;
+-      return sprintf(buf, "0x%px\n", kptr_restrict < 2 ?
+-                     (void *)sattr->address : NULL);
++      return sprintf(buf, "0x%px\n",
++                     kallsyms_show_value(file->f_cred) ? (void *)sattr->address : NULL);
+ }
+ static void free_sect_attrs(struct module_sect_attrs *sect_attrs)
+@@ -4351,7 +4351,7 @@ static int modules_open(struct inode *in
+       if (!err) {
+               struct seq_file *m = file->private_data;
+-              m->private = kallsyms_show_value(current_cred()) ? NULL : (void *)8ul;
++              m->private = kallsyms_show_value(file->f_cred) ? NULL : (void *)8ul;
+       }
+       return err;
diff --git a/queue-5.7/module-refactor-section-attr-into-bin-attribute.patch b/queue-5.7/module-refactor-section-attr-into-bin-attribute.patch
new file mode 100644 (file)
index 0000000..cef9012
--- /dev/null
@@ -0,0 +1,131 @@
+From ed66f991bb19d94cae5d38f77de81f96aac7813f Mon Sep 17 00:00:00 2001
+From: Kees Cook <keescook@chromium.org>
+Date: Thu, 2 Jul 2020 13:47:20 -0700
+Subject: module: Refactor section attr into bin attribute
+
+From: Kees Cook <keescook@chromium.org>
+
+commit ed66f991bb19d94cae5d38f77de81f96aac7813f upstream.
+
+In order to gain access to the open file's f_cred for kallsym visibility
+permission checks, refactor the module section attributes to use the
+bin_attribute instead of attribute interface. Additionally removes the
+redundant "name" struct member.
+
+Cc: stable@vger.kernel.org
+Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Tested-by: Jessica Yu <jeyu@kernel.org>
+Acked-by: Jessica Yu <jeyu@kernel.org>
+Signed-off-by: Kees Cook <keescook@chromium.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ kernel/module.c |   45 ++++++++++++++++++++++++---------------------
+ 1 file changed, 24 insertions(+), 21 deletions(-)
+
+--- a/kernel/module.c
++++ b/kernel/module.c
+@@ -1507,8 +1507,7 @@ static inline bool sect_empty(const Elf_
+ }
+ struct module_sect_attr {
+-      struct module_attribute mattr;
+-      char *name;
++      struct bin_attribute battr;
+       unsigned long address;
+ };
+@@ -1518,11 +1517,16 @@ struct module_sect_attrs {
+       struct module_sect_attr attrs[];
+ };
+-static ssize_t module_sect_show(struct module_attribute *mattr,
+-                              struct module_kobject *mk, char *buf)
++static ssize_t module_sect_read(struct file *file, struct kobject *kobj,
++                              struct bin_attribute *battr,
++                              char *buf, loff_t pos, size_t count)
+ {
+       struct module_sect_attr *sattr =
+-              container_of(mattr, struct module_sect_attr, mattr);
++              container_of(battr, struct module_sect_attr, battr);
++
++      if (pos != 0)
++              return -EINVAL;
++
+       return sprintf(buf, "0x%px\n", kptr_restrict < 2 ?
+                      (void *)sattr->address : NULL);
+ }
+@@ -1532,7 +1536,7 @@ static void free_sect_attrs(struct modul
+       unsigned int section;
+       for (section = 0; section < sect_attrs->nsections; section++)
+-              kfree(sect_attrs->attrs[section].name);
++              kfree(sect_attrs->attrs[section].battr.attr.name);
+       kfree(sect_attrs);
+ }
+@@ -1541,42 +1545,41 @@ static void add_sect_attrs(struct module
+       unsigned int nloaded = 0, i, size[2];
+       struct module_sect_attrs *sect_attrs;
+       struct module_sect_attr *sattr;
+-      struct attribute **gattr;
++      struct bin_attribute **gattr;
+       /* Count loaded sections and allocate structures */
+       for (i = 0; i < info->hdr->e_shnum; i++)
+               if (!sect_empty(&info->sechdrs[i]))
+                       nloaded++;
+       size[0] = ALIGN(struct_size(sect_attrs, attrs, nloaded),
+-                      sizeof(sect_attrs->grp.attrs[0]));
+-      size[1] = (nloaded + 1) * sizeof(sect_attrs->grp.attrs[0]);
++                      sizeof(sect_attrs->grp.bin_attrs[0]));
++      size[1] = (nloaded + 1) * sizeof(sect_attrs->grp.bin_attrs[0]);
+       sect_attrs = kzalloc(size[0] + size[1], GFP_KERNEL);
+       if (sect_attrs == NULL)
+               return;
+       /* Setup section attributes. */
+       sect_attrs->grp.name = "sections";
+-      sect_attrs->grp.attrs = (void *)sect_attrs + size[0];
++      sect_attrs->grp.bin_attrs = (void *)sect_attrs + size[0];
+       sect_attrs->nsections = 0;
+       sattr = &sect_attrs->attrs[0];
+-      gattr = &sect_attrs->grp.attrs[0];
++      gattr = &sect_attrs->grp.bin_attrs[0];
+       for (i = 0; i < info->hdr->e_shnum; i++) {
+               Elf_Shdr *sec = &info->sechdrs[i];
+               if (sect_empty(sec))
+                       continue;
++              sysfs_bin_attr_init(&sattr->battr);
+               sattr->address = sec->sh_addr;
+-              sattr->name = kstrdup(info->secstrings + sec->sh_name,
+-                                      GFP_KERNEL);
+-              if (sattr->name == NULL)
++              sattr->battr.attr.name =
++                      kstrdup(info->secstrings + sec->sh_name, GFP_KERNEL);
++              if (sattr->battr.attr.name == NULL)
+                       goto out;
+               sect_attrs->nsections++;
+-              sysfs_attr_init(&sattr->mattr.attr);
+-              sattr->mattr.show = module_sect_show;
+-              sattr->mattr.store = NULL;
+-              sattr->mattr.attr.name = sattr->name;
+-              sattr->mattr.attr.mode = S_IRUSR;
+-              *(gattr++) = &(sattr++)->mattr.attr;
++              sattr->battr.read = module_sect_read;
++              sattr->battr.size = 3 /* "0x", "\n" */ + (BITS_PER_LONG / 4);
++              sattr->battr.attr.mode = 0400;
++              *(gattr++) = &(sattr++)->battr;
+       }
+       *gattr = NULL;
+@@ -1666,7 +1669,7 @@ static void add_notes_attrs(struct modul
+                       continue;
+               if (info->sechdrs[i].sh_type == SHT_NOTE) {
+                       sysfs_bin_attr_init(nattr);
+-                      nattr->attr.name = mod->sect_attrs->attrs[loaded].name;
++                      nattr->attr.name = mod->sect_attrs->attrs[loaded].battr.attr.name;
+                       nattr->attr.mode = S_IRUGO;
+                       nattr->size = info->sechdrs[i].sh_size;
+                       nattr->private = (void *) info->sechdrs[i].sh_addr;
index c7428e12cf02cb5b92955911ce294840a541c346..400557fd7a806d7acda85b4f8e8fc3f6dafaf07b 100644 (file)
@@ -121,3 +121,12 @@ kvm-x86-bit-8-of-non-leaf-pdpes-is-not-reserved.patch
 kvm-x86-inject-gp-if-guest-attempts-to-toggle-cr4.la57-in-64-bit-mode.patch
 kvm-x86-mark-cr4.tsd-as-being-possibly-owned-by-the-guest.patch
 kvm-arm64-fix-kvm_reset_vcpu-return-code-being-incor.patch
+io_uring-fix-memleak-in-__io_sqe_files_update.patch
+io_uring-account-user-memory-freed-when-exit-has-been-queued.patch
+io_uring-fix-memleak-in-io_sqe_files_register.patch
+io_uring-fix-missing-msg_name-assignment.patch
+kallsyms-refactor-kallsyms_show_value-to-take-cred.patch
+module-refactor-section-attr-into-bin-attribute.patch
+module-do-not-expose-section-addresses-to-non-cap_syslog.patch
+kprobes-do-not-expose-probe-addresses-to-non-cap_syslog.patch
+bpf-check-correct-cred-for-cap_syslog-in-bpf_dump_raw_ok.patch