mirror of
https://github.com/Fishwaldo/Star64_linux.git
synced 2025-06-21 14:11:20 +00:00
Refactor kallsyms_show_value() users for correct cred
Several users of kallsyms_show_value() were performing checks not during "open". Refactor everything needed to gain proper checks against file->f_cred for modules, kprobes, and bpf. -----BEGIN PGP SIGNATURE----- iQJKBAABCgA0FiEEpcP2jyKd1g9yPm4TiXL039xtwCYFAl8GUbMWHGtlZXNjb29r QGNocm9taXVtLm9yZwAKCRCJcvTf3G3AJohnD/9VsPsAMV+8lhsPvkcuW/DkTcAY qUEzsXU3v06gJ0Z/1lBKtisJ6XmD93wWcZCTFvJ0S8vR3yLZvOVfToVjCMO32Trc 4ZkWTPwpvfeLug6T6CcI2ukQdZ/opI1cSabqGl79arSBgE/tsghwrHuJ8Exkz4uq 0b7i8nZa+RiTezwx4EVeGcg6Dv1tG5UTG2VQvD/+QGGKneBlrlaKlI885N/6jsHa KxvB7+8ES1pnfGYZenx+RxMdljNrtyptbQEU8gyvoV5YR7635gjZsVsPwWANJo+4 EGcFFpwWOAcVQaC3dareLTM8nVngU6Wl3Rd7JjZtjvtZba8DdCn669R34zDGXbiP +1n1dYYMSMBeqVUbAQfQyLD0pqMIHdwQj2TN8thSGccr2o3gNk6AXgYq0aYm8IBf xDCvAansJw9WqmxErIIsD4BFkMqF7MjH3eYZxwCPWSrKGDvKxQSPV5FarnpDC9U7 dYCWVxNPmtn+unC/53yXjEcBepKaYgNR7j5G7uOfkHvU43Bd5demzLiVJ10D8abJ ezyErxxEqX2Gr7JR2fWv7iBbULJViqcAnYjdl0y0NgK/hftt98iuge6cZmt1z6ai 24vI3X4VhvvVN5/f64cFDAdYtMRUtOo2dmxdXMid1NI07Mj2qFU1MUwb8RHHlxbK 8UegV2zcrBghnVuMkw== =ib5Q -----END PGP SIGNATURE----- Merge tag 'kallsyms_show_value-v5.8-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux Pull kallsyms fix from Kees Cook: "Refactor kallsyms_show_value() users for correct cred. I'm not delighted by the timing of getting these changes to you, but it does fix a handful of kernel address exposures, and no one has screamed yet at the patches. Several users of kallsyms_show_value() were performing checks not during "open". Refactor everything needed to gain proper checks against file->f_cred for modules, kprobes, and bpf" * tag 'kallsyms_show_value-v5.8-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux: selftests: kmod: Add module address visibility test bpf: Check correct cred for CAP_SYSLOG in bpf_dump_raw_ok() kprobes: Do not expose probe addresses to non-CAP_SYSLOG module: Do not expose section addresses to non-CAP_SYSLOG module: Refactor section attr into bin attribute kallsyms: Refactor kallsyms_show_value() to take cred
This commit is contained in:
commit
ce69fb3b39
8 changed files with 103 additions and 53 deletions
|
@ -884,12 +884,12 @@ void bpf_jit_compile(struct bpf_prog *prog);
|
||||||
bool bpf_jit_needs_zext(void);
|
bool bpf_jit_needs_zext(void);
|
||||||
bool bpf_helper_changes_pkt_data(void *func);
|
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,
|
/* Reconstruction of call-sites is dependent on kallsyms,
|
||||||
* thus make dump the same restriction.
|
* thus make dump the same restriction.
|
||||||
*/
|
*/
|
||||||
return kallsyms_show_value() == 1;
|
return kallsyms_show_value(cred);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct bpf_prog *bpf_patch_insn_single(struct bpf_prog *prog, u32 off,
|
struct bpf_prog *bpf_patch_insn_single(struct bpf_prog *prog, u32 off,
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
#define KSYM_SYMBOL_LEN (sizeof("%s+%#lx/%#lx [%s]") + (KSYM_NAME_LEN - 1) + \
|
#define KSYM_SYMBOL_LEN (sizeof("%s+%#lx/%#lx [%s]") + (KSYM_NAME_LEN - 1) + \
|
||||||
2*(BITS_PER_LONG*3/10) + (MODULE_NAME_LEN - 1) + 1)
|
2*(BITS_PER_LONG*3/10) + (MODULE_NAME_LEN - 1) + 1)
|
||||||
|
|
||||||
|
struct cred;
|
||||||
struct module;
|
struct module;
|
||||||
|
|
||||||
static inline int is_kernel_inittext(unsigned long addr)
|
static inline int is_kernel_inittext(unsigned long addr)
|
||||||
|
@ -98,7 +99,7 @@ int lookup_symbol_name(unsigned long addr, char *symname);
|
||||||
int lookup_symbol_attrs(unsigned long addr, unsigned long *size, unsigned long *offset, char *modname, char *name);
|
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? */
|
/* 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 */
|
#else /* !CONFIG_KALLSYMS */
|
||||||
|
|
||||||
|
@ -158,7 +159,7 @@ static inline int lookup_symbol_attrs(unsigned long addr, unsigned long *size, u
|
||||||
return -ERANGE;
|
return -ERANGE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int kallsyms_show_value(void)
|
static inline bool kallsyms_show_value(const struct cred *cred)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -3139,7 +3139,8 @@ static const struct bpf_map *bpf_map_from_imm(const struct bpf_prog *prog,
|
||||||
return NULL;
|
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;
|
const struct bpf_map *map;
|
||||||
struct bpf_insn *insns;
|
struct bpf_insn *insns;
|
||||||
|
@ -3165,7 +3166,7 @@ static struct bpf_insn *bpf_insn_prepare_dump(const struct bpf_prog *prog)
|
||||||
code == (BPF_JMP | BPF_CALL_ARGS)) {
|
code == (BPF_JMP | BPF_CALL_ARGS)) {
|
||||||
if (code == (BPF_JMP | BPF_CALL_ARGS))
|
if (code == (BPF_JMP | BPF_CALL_ARGS))
|
||||||
insns[i].code = BPF_JMP | BPF_CALL;
|
insns[i].code = BPF_JMP | BPF_CALL;
|
||||||
if (!bpf_dump_raw_ok())
|
if (!bpf_dump_raw_ok(f_cred))
|
||||||
insns[i].imm = 0;
|
insns[i].imm = 0;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -3221,7 +3222,8 @@ static int set_info_rec_size(struct bpf_prog_info *info)
|
||||||
return 0;
|
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,
|
const union bpf_attr *attr,
|
||||||
union bpf_attr __user *uattr)
|
union bpf_attr __user *uattr)
|
||||||
{
|
{
|
||||||
|
@ -3290,11 +3292,11 @@ static int bpf_prog_get_info_by_fd(struct bpf_prog *prog,
|
||||||
struct bpf_insn *insns_sanitized;
|
struct bpf_insn *insns_sanitized;
|
||||||
bool fault;
|
bool fault;
|
||||||
|
|
||||||
if (prog->blinded && !bpf_dump_raw_ok()) {
|
if (prog->blinded && !bpf_dump_raw_ok(file->f_cred)) {
|
||||||
info.xlated_prog_insns = 0;
|
info.xlated_prog_insns = 0;
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
insns_sanitized = bpf_insn_prepare_dump(prog);
|
insns_sanitized = bpf_insn_prepare_dump(prog, file->f_cred);
|
||||||
if (!insns_sanitized)
|
if (!insns_sanitized)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
uinsns = u64_to_user_ptr(info.xlated_prog_insns);
|
uinsns = u64_to_user_ptr(info.xlated_prog_insns);
|
||||||
|
@ -3328,7 +3330,7 @@ static int bpf_prog_get_info_by_fd(struct bpf_prog *prog,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (info.jited_prog_len && ulen) {
|
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);
|
uinsns = u64_to_user_ptr(info.jited_prog_insns);
|
||||||
ulen = min_t(u32, info.jited_prog_len, ulen);
|
ulen = min_t(u32, info.jited_prog_len, ulen);
|
||||||
|
|
||||||
|
@ -3363,7 +3365,7 @@ static int bpf_prog_get_info_by_fd(struct bpf_prog *prog,
|
||||||
ulen = info.nr_jited_ksyms;
|
ulen = info.nr_jited_ksyms;
|
||||||
info.nr_jited_ksyms = prog->aux->func_cnt ? : 1;
|
info.nr_jited_ksyms = prog->aux->func_cnt ? : 1;
|
||||||
if (ulen) {
|
if (ulen) {
|
||||||
if (bpf_dump_raw_ok()) {
|
if (bpf_dump_raw_ok(file->f_cred)) {
|
||||||
unsigned long ksym_addr;
|
unsigned long ksym_addr;
|
||||||
u64 __user *user_ksyms;
|
u64 __user *user_ksyms;
|
||||||
u32 i;
|
u32 i;
|
||||||
|
@ -3394,7 +3396,7 @@ static int bpf_prog_get_info_by_fd(struct bpf_prog *prog,
|
||||||
ulen = info.nr_jited_func_lens;
|
ulen = info.nr_jited_func_lens;
|
||||||
info.nr_jited_func_lens = prog->aux->func_cnt ? : 1;
|
info.nr_jited_func_lens = prog->aux->func_cnt ? : 1;
|
||||||
if (ulen) {
|
if (ulen) {
|
||||||
if (bpf_dump_raw_ok()) {
|
if (bpf_dump_raw_ok(file->f_cred)) {
|
||||||
u32 __user *user_lens;
|
u32 __user *user_lens;
|
||||||
u32 func_len, i;
|
u32 func_len, i;
|
||||||
|
|
||||||
|
@ -3451,7 +3453,7 @@ static int bpf_prog_get_info_by_fd(struct bpf_prog *prog,
|
||||||
else
|
else
|
||||||
info.nr_jited_line_info = 0;
|
info.nr_jited_line_info = 0;
|
||||||
if (info.nr_jited_line_info && ulen) {
|
if (info.nr_jited_line_info && ulen) {
|
||||||
if (bpf_dump_raw_ok()) {
|
if (bpf_dump_raw_ok(file->f_cred)) {
|
||||||
__u64 __user *user_linfo;
|
__u64 __user *user_linfo;
|
||||||
u32 i;
|
u32 i;
|
||||||
|
|
||||||
|
@ -3497,7 +3499,8 @@ done:
|
||||||
return 0;
|
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,
|
const union bpf_attr *attr,
|
||||||
union bpf_attr __user *uattr)
|
union bpf_attr __user *uattr)
|
||||||
{
|
{
|
||||||
|
@ -3540,7 +3543,8 @@ static int bpf_map_get_info_by_fd(struct bpf_map *map,
|
||||||
return 0;
|
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,
|
const union bpf_attr *attr,
|
||||||
union bpf_attr __user *uattr)
|
union bpf_attr __user *uattr)
|
||||||
{
|
{
|
||||||
|
@ -3555,7 +3559,8 @@ static int bpf_btf_get_info_by_fd(struct btf *btf,
|
||||||
return btf_get_info_by_fd(btf, attr, uattr);
|
return btf_get_info_by_fd(btf, attr, uattr);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int bpf_link_get_info_by_fd(struct bpf_link *link,
|
static int bpf_link_get_info_by_fd(struct file *file,
|
||||||
|
struct bpf_link *link,
|
||||||
const union bpf_attr *attr,
|
const union bpf_attr *attr,
|
||||||
union bpf_attr __user *uattr)
|
union bpf_attr __user *uattr)
|
||||||
{
|
{
|
||||||
|
@ -3608,15 +3613,15 @@ static int bpf_obj_get_info_by_fd(const union bpf_attr *attr,
|
||||||
return -EBADFD;
|
return -EBADFD;
|
||||||
|
|
||||||
if (f.file->f_op == &bpf_prog_fops)
|
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);
|
uattr);
|
||||||
else if (f.file->f_op == &bpf_map_fops)
|
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);
|
uattr);
|
||||||
else if (f.file->f_op == &btf_fops)
|
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 if (f.file->f_op == &bpf_link_fops)
|
else if (f.file->f_op == &bpf_link_fops)
|
||||||
err = bpf_link_get_info_by_fd(f.file->private_data,
|
err = bpf_link_get_info_by_fd(f.file, f.file->private_data,
|
||||||
attr, uattr);
|
attr, uattr);
|
||||||
else
|
else
|
||||||
err = -EINVAL;
|
err = -EINVAL;
|
||||||
|
|
|
@ -644,19 +644,20 @@ static inline int kallsyms_for_perf(void)
|
||||||
* Otherwise, require CAP_SYSLOG (assuming kptr_restrict isn't set to
|
* Otherwise, require CAP_SYSLOG (assuming kptr_restrict isn't set to
|
||||||
* block even that).
|
* block even that).
|
||||||
*/
|
*/
|
||||||
int kallsyms_show_value(void)
|
bool kallsyms_show_value(const struct cred *cred)
|
||||||
{
|
{
|
||||||
switch (kptr_restrict) {
|
switch (kptr_restrict) {
|
||||||
case 0:
|
case 0:
|
||||||
if (kallsyms_for_perf())
|
if (kallsyms_for_perf())
|
||||||
return 1;
|
return true;
|
||||||
/* fallthrough */
|
/* fallthrough */
|
||||||
case 1:
|
case 1:
|
||||||
if (has_capability_noaudit(current, CAP_SYSLOG))
|
if (security_capable(cred, &init_user_ns, CAP_SYSLOG,
|
||||||
return 1;
|
CAP_OPT_NOAUDIT) == 0)
|
||||||
|
return true;
|
||||||
/* fallthrough */
|
/* fallthrough */
|
||||||
default:
|
default:
|
||||||
return 0;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -673,7 +674,11 @@ static int kallsyms_open(struct inode *inode, struct file *file)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
reset_iter(iter, 0);
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2448,7 +2448,7 @@ static void report_probe(struct seq_file *pi, struct kprobe *p,
|
||||||
else
|
else
|
||||||
kprobe_type = "k";
|
kprobe_type = "k";
|
||||||
|
|
||||||
if (!kallsyms_show_value())
|
if (!kallsyms_show_value(pi->file->f_cred))
|
||||||
addr = NULL;
|
addr = NULL;
|
||||||
|
|
||||||
if (sym)
|
if (sym)
|
||||||
|
@ -2540,7 +2540,7 @@ static int kprobe_blacklist_seq_show(struct seq_file *m, void *v)
|
||||||
* If /proc/kallsyms is not showing kernel address, we won't
|
* If /proc/kallsyms is not showing kernel address, we won't
|
||||||
* show them here either.
|
* show them here either.
|
||||||
*/
|
*/
|
||||||
if (!kallsyms_show_value())
|
if (!kallsyms_show_value(m->file->f_cred))
|
||||||
seq_printf(m, "0x%px-0x%px\t%ps\n", NULL, NULL,
|
seq_printf(m, "0x%px-0x%px\t%ps\n", NULL, NULL,
|
||||||
(void *)ent->start_addr);
|
(void *)ent->start_addr);
|
||||||
else
|
else
|
||||||
|
|
|
@ -1510,8 +1510,7 @@ static inline bool sect_empty(const Elf_Shdr *sect)
|
||||||
}
|
}
|
||||||
|
|
||||||
struct module_sect_attr {
|
struct module_sect_attr {
|
||||||
struct module_attribute mattr;
|
struct bin_attribute battr;
|
||||||
char *name;
|
|
||||||
unsigned long address;
|
unsigned long address;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1521,13 +1520,18 @@ struct module_sect_attrs {
|
||||||
struct module_sect_attr attrs[];
|
struct module_sect_attr attrs[];
|
||||||
};
|
};
|
||||||
|
|
||||||
static ssize_t module_sect_show(struct module_attribute *mattr,
|
static ssize_t module_sect_read(struct file *file, struct kobject *kobj,
|
||||||
struct module_kobject *mk, char *buf)
|
struct bin_attribute *battr,
|
||||||
|
char *buf, loff_t pos, size_t count)
|
||||||
{
|
{
|
||||||
struct module_sect_attr *sattr =
|
struct module_sect_attr *sattr =
|
||||||
container_of(mattr, struct module_sect_attr, mattr);
|
container_of(battr, struct module_sect_attr, battr);
|
||||||
return sprintf(buf, "0x%px\n", kptr_restrict < 2 ?
|
|
||||||
(void *)sattr->address : NULL);
|
if (pos != 0)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
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)
|
static void free_sect_attrs(struct module_sect_attrs *sect_attrs)
|
||||||
|
@ -1535,7 +1539,7 @@ static void free_sect_attrs(struct module_sect_attrs *sect_attrs)
|
||||||
unsigned int section;
|
unsigned int section;
|
||||||
|
|
||||||
for (section = 0; section < sect_attrs->nsections; 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);
|
kfree(sect_attrs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1544,42 +1548,41 @@ static void add_sect_attrs(struct module *mod, const struct load_info *info)
|
||||||
unsigned int nloaded = 0, i, size[2];
|
unsigned int nloaded = 0, i, size[2];
|
||||||
struct module_sect_attrs *sect_attrs;
|
struct module_sect_attrs *sect_attrs;
|
||||||
struct module_sect_attr *sattr;
|
struct module_sect_attr *sattr;
|
||||||
struct attribute **gattr;
|
struct bin_attribute **gattr;
|
||||||
|
|
||||||
/* Count loaded sections and allocate structures */
|
/* Count loaded sections and allocate structures */
|
||||||
for (i = 0; i < info->hdr->e_shnum; i++)
|
for (i = 0; i < info->hdr->e_shnum; i++)
|
||||||
if (!sect_empty(&info->sechdrs[i]))
|
if (!sect_empty(&info->sechdrs[i]))
|
||||||
nloaded++;
|
nloaded++;
|
||||||
size[0] = ALIGN(struct_size(sect_attrs, attrs, nloaded),
|
size[0] = ALIGN(struct_size(sect_attrs, attrs, nloaded),
|
||||||
sizeof(sect_attrs->grp.attrs[0]));
|
sizeof(sect_attrs->grp.bin_attrs[0]));
|
||||||
size[1] = (nloaded + 1) * sizeof(sect_attrs->grp.attrs[0]);
|
size[1] = (nloaded + 1) * sizeof(sect_attrs->grp.bin_attrs[0]);
|
||||||
sect_attrs = kzalloc(size[0] + size[1], GFP_KERNEL);
|
sect_attrs = kzalloc(size[0] + size[1], GFP_KERNEL);
|
||||||
if (sect_attrs == NULL)
|
if (sect_attrs == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* Setup section attributes. */
|
/* Setup section attributes. */
|
||||||
sect_attrs->grp.name = "sections";
|
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;
|
sect_attrs->nsections = 0;
|
||||||
sattr = §_attrs->attrs[0];
|
sattr = §_attrs->attrs[0];
|
||||||
gattr = §_attrs->grp.attrs[0];
|
gattr = §_attrs->grp.bin_attrs[0];
|
||||||
for (i = 0; i < info->hdr->e_shnum; i++) {
|
for (i = 0; i < info->hdr->e_shnum; i++) {
|
||||||
Elf_Shdr *sec = &info->sechdrs[i];
|
Elf_Shdr *sec = &info->sechdrs[i];
|
||||||
if (sect_empty(sec))
|
if (sect_empty(sec))
|
||||||
continue;
|
continue;
|
||||||
|
sysfs_bin_attr_init(&sattr->battr);
|
||||||
sattr->address = sec->sh_addr;
|
sattr->address = sec->sh_addr;
|
||||||
sattr->name = kstrdup(info->secstrings + sec->sh_name,
|
sattr->battr.attr.name =
|
||||||
GFP_KERNEL);
|
kstrdup(info->secstrings + sec->sh_name, GFP_KERNEL);
|
||||||
if (sattr->name == NULL)
|
if (sattr->battr.attr.name == NULL)
|
||||||
goto out;
|
goto out;
|
||||||
sect_attrs->nsections++;
|
sect_attrs->nsections++;
|
||||||
sysfs_attr_init(&sattr->mattr.attr);
|
sattr->battr.read = module_sect_read;
|
||||||
sattr->mattr.show = module_sect_show;
|
sattr->battr.size = 3 /* "0x", "\n" */ + (BITS_PER_LONG / 4);
|
||||||
sattr->mattr.store = NULL;
|
sattr->battr.attr.mode = 0400;
|
||||||
sattr->mattr.attr.name = sattr->name;
|
*(gattr++) = &(sattr++)->battr;
|
||||||
sattr->mattr.attr.mode = S_IRUSR;
|
|
||||||
*(gattr++) = &(sattr++)->mattr.attr;
|
|
||||||
}
|
}
|
||||||
*gattr = NULL;
|
*gattr = NULL;
|
||||||
|
|
||||||
|
@ -1669,7 +1672,7 @@ static void add_notes_attrs(struct module *mod, const struct load_info *info)
|
||||||
continue;
|
continue;
|
||||||
if (info->sechdrs[i].sh_type == SHT_NOTE) {
|
if (info->sechdrs[i].sh_type == SHT_NOTE) {
|
||||||
sysfs_bin_attr_init(nattr);
|
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->attr.mode = S_IRUGO;
|
||||||
nattr->size = info->sechdrs[i].sh_size;
|
nattr->size = info->sechdrs[i].sh_size;
|
||||||
nattr->private = (void *) info->sechdrs[i].sh_addr;
|
nattr->private = (void *) info->sechdrs[i].sh_addr;
|
||||||
|
@ -4379,7 +4382,7 @@ static int modules_open(struct inode *inode, struct file *file)
|
||||||
|
|
||||||
if (!err) {
|
if (!err) {
|
||||||
struct seq_file *m = file->private_data;
|
struct seq_file *m = file->private_data;
|
||||||
m->private = kallsyms_show_value() ? NULL : (void *)8ul;
|
m->private = kallsyms_show_value(file->f_cred) ? NULL : (void *)8ul;
|
||||||
}
|
}
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
|
|
|
@ -274,7 +274,7 @@ static int proc_dointvec_minmax_bpf_enable(struct ctl_table *table, int write,
|
||||||
ret = proc_dointvec_minmax(&tmp, write, buffer, lenp, ppos);
|
ret = proc_dointvec_minmax(&tmp, write, buffer, lenp, ppos);
|
||||||
if (write && !ret) {
|
if (write && !ret) {
|
||||||
if (jit_enable < 2 ||
|
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;
|
*(int *)table->data = jit_enable;
|
||||||
if (jit_enable == 2)
|
if (jit_enable == 2)
|
||||||
pr_warn("bpf_jit_enable = 2 was set! NEVER use this in production, only for JIT debugging!\n");
|
pr_warn("bpf_jit_enable = 2 was set! NEVER use this in production, only for JIT debugging!\n");
|
||||||
|
|
|
@ -63,6 +63,8 @@ ALL_TESTS="$ALL_TESTS 0008:150:1"
|
||||||
ALL_TESTS="$ALL_TESTS 0009:150:1"
|
ALL_TESTS="$ALL_TESTS 0009:150:1"
|
||||||
ALL_TESTS="$ALL_TESTS 0010:1:1"
|
ALL_TESTS="$ALL_TESTS 0010:1:1"
|
||||||
ALL_TESTS="$ALL_TESTS 0011:1:1"
|
ALL_TESTS="$ALL_TESTS 0011:1:1"
|
||||||
|
ALL_TESTS="$ALL_TESTS 0012:1:1"
|
||||||
|
ALL_TESTS="$ALL_TESTS 0013:1:1"
|
||||||
|
|
||||||
# Kselftest framework requirement - SKIP code is 4.
|
# Kselftest framework requirement - SKIP code is 4.
|
||||||
ksft_skip=4
|
ksft_skip=4
|
||||||
|
@ -470,6 +472,38 @@ kmod_test_0011()
|
||||||
echo "$MODPROBE" > /proc/sys/kernel/modprobe
|
echo "$MODPROBE" > /proc/sys/kernel/modprobe
|
||||||
}
|
}
|
||||||
|
|
||||||
|
kmod_check_visibility()
|
||||||
|
{
|
||||||
|
local name="$1"
|
||||||
|
local cmd="$2"
|
||||||
|
|
||||||
|
modprobe $DEFAULT_KMOD_DRIVER
|
||||||
|
|
||||||
|
local priv=$(eval $cmd)
|
||||||
|
local unpriv=$(capsh --drop=CAP_SYSLOG -- -c "$cmd")
|
||||||
|
|
||||||
|
if [ "$priv" = "$unpriv" ] || \
|
||||||
|
[ "${priv:0:3}" = "0x0" ] || \
|
||||||
|
[ "${unpriv:0:3}" != "0x0" ] ; then
|
||||||
|
echo "${FUNCNAME[0]}: FAIL, $name visible to unpriv: '$priv' vs '$unpriv'" >&2
|
||||||
|
exit 1
|
||||||
|
else
|
||||||
|
echo "${FUNCNAME[0]}: OK!"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
kmod_test_0012()
|
||||||
|
{
|
||||||
|
kmod_check_visibility /proc/modules \
|
||||||
|
"grep '^${DEFAULT_KMOD_DRIVER}\b' /proc/modules | awk '{print \$NF}'"
|
||||||
|
}
|
||||||
|
|
||||||
|
kmod_test_0013()
|
||||||
|
{
|
||||||
|
kmod_check_visibility '/sys/module/*/sections/*' \
|
||||||
|
"cat /sys/module/${DEFAULT_KMOD_DRIVER}/sections/.*text | head -n1"
|
||||||
|
}
|
||||||
|
|
||||||
list_tests()
|
list_tests()
|
||||||
{
|
{
|
||||||
echo "Test ID list:"
|
echo "Test ID list:"
|
||||||
|
@ -489,6 +523,8 @@ list_tests()
|
||||||
echo "0009 x $(get_test_count 0009) - multithreaded - push kmod_concurrent over max_modprobes for get_fs_type()"
|
echo "0009 x $(get_test_count 0009) - multithreaded - push kmod_concurrent over max_modprobes for get_fs_type()"
|
||||||
echo "0010 x $(get_test_count 0010) - test nonexistent modprobe path"
|
echo "0010 x $(get_test_count 0010) - test nonexistent modprobe path"
|
||||||
echo "0011 x $(get_test_count 0011) - test completely disabling module autoloading"
|
echo "0011 x $(get_test_count 0011) - test completely disabling module autoloading"
|
||||||
|
echo "0012 x $(get_test_count 0012) - test /proc/modules address visibility under CAP_SYSLOG"
|
||||||
|
echo "0013 x $(get_test_count 0013) - test /sys/module/*/sections/* visibility under CAP_SYSLOG"
|
||||||
}
|
}
|
||||||
|
|
||||||
usage()
|
usage()
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue