Re: [PATCH v3 09/10] kallsyms: Hide layout

From: Kees Cook
Date: Wed Jun 24 2020 - 03:21:02 EST


On Tue, Jun 23, 2020 at 10:23:26AM -0700, Kristen Carlson Accardi wrote:
> This patch makes /proc/kallsyms display alphabetically by symbol
> name rather than sorted by address in order to hide the newly
> randomized address layout.
>
> Signed-off-by: Kristen Carlson Accardi <kristen@xxxxxxxxxxxxxxx>
> Reviewed-by: Tony Luck <tony.luck@xxxxxxxxx>
> Tested-by: Tony Luck <tony.luck@xxxxxxxxx>
> ---
> kernel/kallsyms.c | 128 ++++++++++++++++++++++++++++++++++++++++++++++
> 1 file changed, 128 insertions(+)
>
> diff --git a/kernel/kallsyms.c b/kernel/kallsyms.c
> index 16c8c605f4b0..df2b20e1b7f2 100644
> --- a/kernel/kallsyms.c
> +++ b/kernel/kallsyms.c
> @@ -25,6 +25,7 @@
> #include <linux/filter.h>
> #include <linux/ftrace.h>
> #include <linux/compiler.h>
> +#include <linux/list_sort.h>
>
> /*
> * These will be re-linked against their real values
> @@ -446,6 +447,11 @@ struct kallsym_iter {
> int show_value;
> };
>
> +struct kallsyms_iter_list {
> + struct kallsym_iter iter;
> + struct list_head next;
> +};
> +
> int __weak arch_get_kallsym(unsigned int symnum, unsigned long *value,
> char *type, char *name)
> {
> @@ -660,6 +666,127 @@ int kallsyms_show_value(void)
> }
> }

The #ifdef can be moved up to here:

#ifdef CONFIG_FG_KASLR

Otherwise without CONFIG_FG_KASLR, I get:

kernel/kallsyms.c:714:12: warning: âkallsyms_list_cmpâ defined but not used [-Wunused-function]
714 | static int kallsyms_list_cmp(void *priv, struct list_head *a,
| ^~~~~~~~~~~~~~~~~


>
> +static int sorted_show(struct seq_file *m, void *p)
> +{
> + struct list_head *list = m->private;
> + struct kallsyms_iter_list *iter;
> + int rc;
> +
> + if (list_empty(list))
> + return 0;
> +
> + iter = list_first_entry(list, struct kallsyms_iter_list, next);
> +
> + m->private = iter;
> + rc = s_show(m, p);
> + m->private = list;
> +
> + list_del(&iter->next);
> + kfree(iter);
> +
> + return rc;
> +}
> +
> +static void *sorted_start(struct seq_file *m, loff_t *pos)
> +{
> + return m->private;
> +}
> +
> +static void *sorted_next(struct seq_file *m, void *p, loff_t *pos)
> +{
> + struct list_head *list = m->private;
> +
> + (*pos)++;
> +
> + if (list_empty(list))
> + return NULL;
> +
> + return p;
> +}
> +
> +static const struct seq_operations kallsyms_sorted_op = {
> + .start = sorted_start,
> + .next = sorted_next,
> + .stop = s_stop,
> + .show = sorted_show
> +};
> +
> +static int kallsyms_list_cmp(void *priv, struct list_head *a,
> + struct list_head *b)
> +{
> + struct kallsyms_iter_list *iter_a, *iter_b;
> +
> + iter_a = list_entry(a, struct kallsyms_iter_list, next);
> + iter_b = list_entry(b, struct kallsyms_iter_list, next);
> +
> + return strcmp(iter_a->iter.name, iter_b->iter.name);
> +}
> +
> +int get_all_symbol_name(void *data, const char *name, struct module *mod,
> + unsigned long addr)

This can be static too.

Otherwise, looks good!

Reviewed-by: Kees Cook <keescook@xxxxxxxxxxxx>

--
Kees Cook