Re: [PATCH v9 03/15] kallsyms: Hide layout

From: Borislav Petkov
Date: Wed Jan 05 2022 - 13:46:10 EST


On Thu, Dec 23, 2021 at 01:21:57AM +0100, Alexander Lobakin wrote:
> @@ -687,11 +697,12 @@ static void reset_iter(struct kallsym_iter *iter, loff_t new_pos)
> iter->name[0] = '\0';
> iter->nameoff = get_symbol_offset(new_pos);
> iter->pos = new_pos;
> - if (new_pos == 0) {

if (!iter->show_layout)
return;

> + if (iter->show_layout && new_pos == 0) {
> iter->pos_arch_end = 0;
> iter->pos_mod_end = 0;
> iter->pos_ftrace_mod_end = 0;
> iter->pos_bpf_end = 0;
> + iter->pos_end = 0;
> }
> }

...

> @@ -838,16 +860,54 @@ static int kallsyms_open(struct inode *inode, struct file *file)
> * using get_symbol_offset for every symbol.
> */
> struct kallsym_iter *iter;
> - iter = __seq_open_private(file, &kallsyms_op, sizeof(*iter));
> - if (!iter)
> - return -ENOMEM;
> - reset_iter(iter, 0);
> + /*
> + * This fake iter is needed for the cases with unprivileged
> + * access. We need to know the exact number of symbols to
> + * randomize the display layout.
> + */
> + struct kallsym_iter fake;
> + size_t size = sizeof(*iter);
> + loff_t pos;
> +
> + fake.show_layout = true;
> + reset_iter(&fake, 0);
>
> /*
> * 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);
> + fake.show_layout = kallsyms_show_value(file->f_cred);
> + if (fake.show_layout)
> + goto open;

There are those silly labels again:

if (!fake.show_layout) {
for (... )
;
size = ...
}

iter = __seq_open_private(...

> +
> + for (pos = kallsyms_num_syms; update_iter_mod(&fake, pos); pos++)
> + ;
> +
> + size = struct_size(iter, shuffled_pos, fake.pos_end + 1);
> +
> +open:
> + iter = __seq_open_private(file, &kallsyms_op, size);
> + if (!iter)
> + return -ENOMEM;
> +
> + iter->show_layout = fake.show_layout;
> + reset_iter(iter, 0);
> +
> + if (iter->show_layout)
> + return 0;
> +
> + /* Copy the bounds since they were already discovered above */
> + iter->pos_arch_end = fake.pos_arch_end;
> + iter->pos_mod_end = fake.pos_mod_end;
> + iter->pos_ftrace_mod_end = fake.pos_ftrace_mod_end;
> + iter->pos_bpf_end = fake.pos_bpf_end;
> + iter->pos_end = fake.pos_end;
> +
> + for (pos = 0; pos <= iter->pos_end; pos++)
> + iter->shuffled_pos[pos] = pos;
> +
> + shuffle_array(iter->shuffled_pos, iter->pos_end + 1);
> +
> return 0;
> }

Thx.

--
Regards/Gruss,
Boris.

https://people.kernel.org/tglx/notes-about-netiquette