]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.19-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 14 Jul 2020 08:18:34 +0000 (10:18 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 14 Jul 2020 08:18:34 +0000 (10:18 +0200)
added patches:
bpf-check-correct-cred-for-cap_syslog-in-bpf_dump_raw_ok.patch
kallsyms-refactor-kallsyms_show_value-to-take-cred.patch
kernel-module-use-struct_size-helper.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-4.19/bpf-check-correct-cred-for-cap_syslog-in-bpf_dump_raw_ok.patch [new file with mode: 0644]
queue-4.19/kallsyms-refactor-kallsyms_show_value-to-take-cred.patch [new file with mode: 0644]
queue-4.19/kernel-module-use-struct_size-helper.patch [new file with mode: 0644]
queue-4.19/kprobes-do-not-expose-probe-addresses-to-non-cap_syslog.patch [new file with mode: 0644]
queue-4.19/module-do-not-expose-section-addresses-to-non-cap_syslog.patch [new file with mode: 0644]
queue-4.19/module-refactor-section-attr-into-bin-attribute.patch [new file with mode: 0644]
queue-4.19/series

diff --git a/queue-4.19/bpf-check-correct-cred-for-cap_syslog-in-bpf_dump_raw_ok.patch b/queue-4.19/bpf-check-correct-cred-for-cap_syslog-in-bpf_dump_raw_ok.patch
new file mode 100644 (file)
index 0000000..ab58ef5
--- /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
+@@ -752,12 +752,12 @@ struct bpf_prog *bpf_int_jit_compile(str
+ void bpf_jit_compile(struct bpf_prog *prog);
+ 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
+@@ -1903,7 +1903,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;
+@@ -1925,7 +1926,7 @@ static struct bpf_insn *bpf_insn_prepare
+                   insns[i].code == (BPF_JMP | BPF_CALL_ARGS)) {
+                       if (insns[i].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;
+               }
+@@ -1942,7 +1943,7 @@ static struct bpf_insn *bpf_insn_prepare
+                       continue;
+               }
+-              if (!bpf_dump_raw_ok() &&
++              if (!bpf_dump_raw_ok(f_cred) &&
+                   imm == (unsigned long)prog->aux) {
+                       insns[i].imm = 0;
+                       insns[i + 1].imm = 0;
+@@ -1953,7 +1954,8 @@ static struct bpf_insn *bpf_insn_prepare
+       return insns;
+ }
+-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)
+ {
+@@ -2010,11 +2012,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);
+@@ -2048,7 +2050,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);
+@@ -2083,7 +2085,7 @@ static int bpf_prog_get_info_by_fd(struc
+       ulen = info.nr_jited_ksyms;
+       info.nr_jited_ksyms = prog->aux->func_cnt;
+       if (info.nr_jited_ksyms && ulen) {
+-              if (bpf_dump_raw_ok()) {
++              if (bpf_dump_raw_ok(file->f_cred)) {
+                       u64 __user *user_ksyms;
+                       ulong ksym_addr;
+                       u32 i;
+@@ -2107,7 +2109,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;
+       if (info.nr_jited_func_lens && ulen) {
+-              if (bpf_dump_raw_ok()) {
++              if (bpf_dump_raw_ok(file->f_cred)) {
+                       u32 __user *user_lens;
+                       u32 func_len, i;
+@@ -2132,7 +2134,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)
+ {
+@@ -2174,7 +2177,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)
+ {
+@@ -2206,13 +2210,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
+@@ -270,7 +270,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-4.19/kallsyms-refactor-kallsyms_show_value-to-take-cred.patch b/queue-4.19/kallsyms-refactor-kallsyms_show_value-to-take-cred.patch
new file mode 100644 (file)
index 0000000..fb0fae7
--- /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
+@@ -757,7 +757,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
+@@ -2334,7 +2334,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)
+@@ -2435,7 +2435,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
+@@ -4258,7 +4258,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-4.19/kernel-module-use-struct_size-helper.patch b/queue-4.19/kernel-module-use-struct_size-helper.patch
new file mode 100644 (file)
index 0000000..f62c12a
--- /dev/null
@@ -0,0 +1,51 @@
+From 8d1b73dd25ff92c3fa9807a20c22fa2b44c07336 Mon Sep 17 00:00:00 2001
+From: "Gustavo A. R. Silva" <gustavo@embeddedor.com>
+Date: Thu, 6 Jun 2019 13:18:53 -0500
+Subject: kernel: module: Use struct_size() helper
+
+From: Gustavo A. R. Silva <gustavo@embeddedor.com>
+
+commit 8d1b73dd25ff92c3fa9807a20c22fa2b44c07336 upstream.
+
+One of the more common cases of allocation size calculations is finding
+the size of a structure that has a zero-sized array at the end, along
+with memory for some number of elements for that array. For example:
+
+struct module_sect_attrs {
+       ...
+        struct module_sect_attr attrs[0];
+};
+
+Make use of the struct_size() helper instead of an open-coded version
+in order to avoid any potential type mistakes.
+
+So, replace the following form:
+
+sizeof(*sect_attrs) + nloaded * sizeof(sect_attrs->attrs[0]
+
+with:
+
+struct_size(sect_attrs, attrs, nloaded)
+
+This code was detected with the help of Coccinelle.
+
+Signed-off-by: Gustavo A. R. Silva <gustavo@embeddedor.com>
+Signed-off-by: Jessica Yu <jeyu@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ kernel/module.c |    3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+--- a/kernel/module.c
++++ b/kernel/module.c
+@@ -1491,8 +1491,7 @@ static void add_sect_attrs(struct module
+       for (i = 0; i < info->hdr->e_shnum; i++)
+               if (!sect_empty(&info->sechdrs[i]))
+                       nloaded++;
+-      size[0] = ALIGN(sizeof(*sect_attrs)
+-                      + nloaded * sizeof(sect_attrs->attrs[0]),
++      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]);
+       sect_attrs = kzalloc(size[0] + size[1], GFP_KERNEL);
diff --git a/queue-4.19/kprobes-do-not-expose-probe-addresses-to-non-cap_syslog.patch b/queue-4.19/kprobes-do-not-expose-probe-addresses-to-non-cap_syslog.patch
new file mode 100644 (file)
index 0000000..9135ae6
--- /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
+@@ -2334,7 +2334,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)
+@@ -2435,7 +2435,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-4.19/module-do-not-expose-section-addresses-to-non-cap_syslog.patch b/queue-4.19/module-do-not-expose-section-addresses-to-non-cap_syslog.patch
new file mode 100644 (file)
index 0000000..fdacd1e
--- /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
+@@ -1471,8 +1471,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)
+@@ -4260,7 +4260,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-4.19/module-refactor-section-attr-into-bin-attribute.patch b/queue-4.19/module-refactor-section-attr-into-bin-attribute.patch
new file mode 100644 (file)
index 0000000..894af85
--- /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
+@@ -1451,8 +1451,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;
+ };
+@@ -1462,11 +1461,16 @@ struct module_sect_attrs {
+       struct module_sect_attr attrs[0];
+ };
+-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);
+ }
+@@ -1476,7 +1480,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);
+ }
+@@ -1485,42 +1489,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;
+@@ -1610,7 +1613,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 81858ed2b0b2c6ec4a5e063eff02bdde13efa1a4..7214598fcbfe82df5d0cb9162ddfeddcf735e93b 100644 (file)
@@ -43,3 +43,9 @@ kvm-arm64-stop-clobbering-x0-for-hvc_soft_restart.patch
 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
+kallsyms-refactor-kallsyms_show_value-to-take-cred.patch
+kernel-module-use-struct_size-helper.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