lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date:   Wed, 19 Oct 2022 09:23:38 +0200
From:   Ard Biesheuvel <ardb@...nel.org>
To:     Evgeniy Baskov <baskov@...ras.ru>
Cc:     Borislav Petkov <bp@...en8.de>, Andy Lutomirski <luto@...nel.org>,
        Dave Hansen <dave.hansen@...ux.intel.com>,
        Ingo Molnar <mingo@...hat.com>,
        Peter Zijlstra <peterz@...radead.org>,
        Thomas Gleixner <tglx@...utronix.de>,
        Alexey Khoroshilov <khoroshilov@...ras.ru>,
        lvc-project@...uxtesting.org, x86@...nel.org,
        linux-efi@...r.kernel.org, linux-kernel@...r.kernel.org,
        linux-hardening@...r.kernel.org
Subject: Re: [PATCH 10/16] x86/boot: Make console interface more abstract

On Tue, 6 Sept 2022 at 12:42, Evgeniy Baskov <baskov@...ras.ru> wrote:
>
> To be able to extract kernel from EFI, console output functions
> need to be replaceable by alternative implementations.
>
> Make all of those functions pointers.
> Move serial console code to separate file.
>

What does kernel_add_identity_map() have to do with the above? Should
that be a separate patch?

> Signed-off-by: Evgeniy Baskov <baskov@...ras.ru>
> ---
>  arch/x86/boot/compressed/Makefile       |   2 +-
>  arch/x86/boot/compressed/ident_map_64.c |  15 ++-
>  arch/x86/boot/compressed/misc.c         | 109 +--------------------
>  arch/x86/boot/compressed/misc.h         |  13 ++-
>  arch/x86/boot/compressed/putstr.c       | 124 ++++++++++++++++++++++++
>  5 files changed, 146 insertions(+), 117 deletions(-)
>  create mode 100644 arch/x86/boot/compressed/putstr.c
>
> diff --git a/arch/x86/boot/compressed/Makefile b/arch/x86/boot/compressed/Makefile
> index 35ce1a64068b..29411864bfcd 100644
> --- a/arch/x86/boot/compressed/Makefile
> +++ b/arch/x86/boot/compressed/Makefile
> @@ -92,7 +92,7 @@ $(obj)/misc.o: $(obj)/../voffset.h
>
>  vmlinux-objs-y := $(obj)/vmlinux.lds $(obj)/kernel_info.o $(obj)/head_$(BITS).o \
>         $(obj)/misc.o $(obj)/string.o $(obj)/cmdline.o $(obj)/error.o \
> -       $(obj)/piggy.o $(obj)/cpuflags.o
> +       $(obj)/piggy.o $(obj)/cpuflags.o $(obj)/putstr.o
>
>  vmlinux-objs-$(CONFIG_EARLY_PRINTK) += $(obj)/early_serial_console.o
>  vmlinux-objs-$(CONFIG_RANDOMIZE_BASE) += $(obj)/kaslr.o
> diff --git a/arch/x86/boot/compressed/ident_map_64.c b/arch/x86/boot/compressed/ident_map_64.c
> index c20cd31e665f..c39373687e50 100644
> --- a/arch/x86/boot/compressed/ident_map_64.c
> +++ b/arch/x86/boot/compressed/ident_map_64.c
> @@ -89,12 +89,20 @@ phys_addr_t physical_mask = (1ULL << __PHYSICAL_MASK_SHIFT) - 1;
>  static struct x86_mapping_info mapping_info;
>  int has_nx;
>
> +/*
> + * This points to actual implementation of mapping function.
> + * Either the one down below or the UEFI API wrapper.
> + */
> +unsigned long (*kernel_add_identity_map)(unsigned long start,
> +                                        unsigned long end,
> +                                        unsigned int flags);
> +
>  /*
>   * Adds the specified range to the identity mappings.
>   */
> -unsigned long kernel_add_identity_map(unsigned long start,
> -                                     unsigned long end,
> -                                     unsigned int flags)
> +unsigned long kernel_add_identity_map_(unsigned long start,
> +                                      unsigned long end,
> +                                      unsigned int flags)
>  {
>         int ret;
>
> @@ -136,6 +144,7 @@ void initialize_identity_maps(void *rmode)
>         struct setup_data *sd;
>
>         boot_params = rmode;
> +       kernel_add_identity_map = kernel_add_identity_map_;
>
>         /* Exclude the encryption mask from __PHYSICAL_MASK */
>         physical_mask &= ~sme_me_mask;
> diff --git a/arch/x86/boot/compressed/misc.c b/arch/x86/boot/compressed/misc.c
> index d377e434c4e3..e2c0d05ac293 100644
> --- a/arch/x86/boot/compressed/misc.c
> +++ b/arch/x86/boot/compressed/misc.c
> @@ -53,13 +53,6 @@ struct port_io_ops pio_ops;
>  memptr free_mem_ptr;
>  memptr free_mem_end_ptr;
>
> -static char *vidmem;
> -static int vidport;
> -
> -/* These might be accessed before .bss is cleared, so use .data instead. */
> -static int lines __section(".data");
> -static int cols __section(".data");
> -
>  #ifdef CONFIG_KERNEL_GZIP
>  #include "../../../../lib/decompress_inflate.c"
>  #endif
> @@ -92,95 +85,6 @@ static int cols __section(".data");
>   * ../header.S.
>   */
>
> -static void scroll(void)
> -{
> -       int i;
> -
> -       memmove(vidmem, vidmem + cols * 2, (lines - 1) * cols * 2);
> -       for (i = (lines - 1) * cols * 2; i < lines * cols * 2; i += 2)
> -               vidmem[i] = ' ';
> -}
> -
> -#define XMTRDY          0x20
> -
> -#define TXR             0       /*  Transmit register (WRITE) */
> -#define LSR             5       /*  Line Status               */
> -static void serial_putchar(int ch)
> -{
> -       unsigned timeout = 0xffff;
> -
> -       while ((inb(early_serial_base + LSR) & XMTRDY) == 0 && --timeout)
> -               cpu_relax();
> -
> -       outb(ch, early_serial_base + TXR);
> -}
> -
> -void __putstr(const char *s)
> -{
> -       int x, y, pos;
> -       char c;
> -
> -       if (early_serial_base) {
> -               const char *str = s;
> -               while (*str) {
> -                       if (*str == '\n')
> -                               serial_putchar('\r');
> -                       serial_putchar(*str++);
> -               }
> -       }
> -
> -       if (lines == 0 || cols == 0)
> -               return;
> -
> -       x = boot_params->screen_info.orig_x;
> -       y = boot_params->screen_info.orig_y;
> -
> -       while ((c = *s++) != '\0') {
> -               if (c == '\n') {
> -                       x = 0;
> -                       if (++y >= lines) {
> -                               scroll();
> -                               y--;
> -                       }
> -               } else {
> -                       vidmem[(x + cols * y) * 2] = c;
> -                       if (++x >= cols) {
> -                               x = 0;
> -                               if (++y >= lines) {
> -                                       scroll();
> -                                       y--;
> -                               }
> -                       }
> -               }
> -       }
> -
> -       boot_params->screen_info.orig_x = x;
> -       boot_params->screen_info.orig_y = y;
> -
> -       pos = (x + cols * y) * 2;       /* Update cursor position */
> -       outb(14, vidport);
> -       outb(0xff & (pos >> 9), vidport+1);
> -       outb(15, vidport);
> -       outb(0xff & (pos >> 1), vidport+1);
> -}
> -
> -void __puthex(unsigned long value)
> -{
> -       char alpha[2] = "0";
> -       int bits;
> -
> -       for (bits = sizeof(value) * 8 - 4; bits >= 0; bits -= 4) {
> -               unsigned long digit = (value >> bits) & 0xf;
> -
> -               if (digit < 0xA)
> -                       alpha[0] = '0' + digit;
> -               else
> -                       alpha[0] = 'a' + (digit - 0xA);
> -
> -               __putstr(alpha);
> -       }
> -}
> -
>  #ifdef CONFIG_X86_NEED_RELOCS
>  static void handle_relocations(void *output, unsigned long output_len,
>                                unsigned long virt_addr)
> @@ -407,17 +311,6 @@ asmlinkage __visible void *extract_kernel(void *rmode, memptr heap,
>
>         sanitize_boot_params(boot_params);
>
> -       if (boot_params->screen_info.orig_video_mode == 7) {
> -               vidmem = (char *) 0xb0000;
> -               vidport = 0x3b4;
> -       } else {
> -               vidmem = (char *) 0xb8000;
> -               vidport = 0x3d4;
> -       }
> -
> -       lines = boot_params->screen_info.orig_video_lines;
> -       cols = boot_params->screen_info.orig_video_cols;
> -
>         init_default_io_ops();
>
>         /*
> @@ -428,7 +321,7 @@ asmlinkage __visible void *extract_kernel(void *rmode, memptr heap,
>          */
>         early_tdx_detect();
>
> -       console_init();
> +       init_bare_console();
>
>         /*
>          * Save RSDP address for later use. Have this after console_init()
> diff --git a/arch/x86/boot/compressed/misc.h b/arch/x86/boot/compressed/misc.h
> index a4f99516f310..39dc3de50268 100644
> --- a/arch/x86/boot/compressed/misc.h
> +++ b/arch/x86/boot/compressed/misc.h
> @@ -53,8 +53,8 @@ extern memptr free_mem_end_ptr;
>  void *malloc(int size);
>  void free(void *where);
>  extern struct boot_params *boot_params;
> -void __putstr(const char *s);
> -void __puthex(unsigned long value);
> +extern void (*__putstr)(const char *s);
> +extern void (*__puthex)(unsigned long value);
>  #define error_putstr(__x)  __putstr(__x)
>  #define error_puthex(__x)  __puthex(__x)
>
> @@ -124,6 +124,9 @@ static inline void console_init(void)
>  { }
>  #endif
>
> +/* putstr.c */
> +void init_bare_console(void);
> +
>  #ifdef CONFIG_AMD_MEM_ENCRYPT
>  void sev_enable(struct boot_params *bp);
>  void sev_es_shutdown_ghcb(void);
> @@ -172,9 +175,9 @@ static inline int count_immovable_mem_regions(void) { return 0; }
>  extern unsigned int __pgtable_l5_enabled, pgdir_shift, ptrs_per_p4d;
>  #endif
>  #ifdef CONFIG_X86_64
> -extern unsigned long kernel_add_identity_map(unsigned long start,
> -                                            unsigned long end,
> -                                            unsigned int flags);
> +extern unsigned long (*kernel_add_identity_map)(unsigned long start,
> +                                               unsigned long end,
> +                                               unsigned int flags);
>  #else
>  static inline unsigned long kernel_add_identity_map(unsigned long start,
>                                                     unsigned long end,
> diff --git a/arch/x86/boot/compressed/putstr.c b/arch/x86/boot/compressed/putstr.c
> new file mode 100644
> index 000000000000..accba0de8be9
> --- /dev/null
> +++ b/arch/x86/boot/compressed/putstr.c
> @@ -0,0 +1,124 @@
> +// SPDX-License-Identifier: GPL-2.0
> +#include "misc.h"
> +
> +/* These might be accessed before .bss is cleared, so use .data instead. */
> +static char *vidmem __section(".data");
> +static int vidport __section(".data");
> +static int lines __section(".data");
> +static int cols __section(".data");
> +
> +void (*__putstr)(const char *s);
> +void (*__puthex)(unsigned long value);
> +
> +static void putstr(const char *s);
> +static void puthex(unsigned long value);
> +
> +void init_bare_console(void)
> +{
> +       __putstr = putstr;
> +       __puthex = puthex;
> +
> +       if (boot_params->screen_info.orig_video_mode == 7) {
> +               vidmem = (char *) 0xb0000;
> +               vidport = 0x3b4;
> +       } else {
> +               vidmem = (char *) 0xb8000;
> +               vidport = 0x3d4;
> +       }
> +
> +       lines = boot_params->screen_info.orig_video_lines;
> +       cols = boot_params->screen_info.orig_video_cols;
> +
> +       console_init();
> +}
> +
> +static void scroll(void)
> +{
> +       int i;
> +
> +       memmove(vidmem, vidmem + cols * 2, (lines - 1) * cols * 2);
> +       for (i = (lines - 1) * cols * 2; i < lines * cols * 2; i += 2)
> +               vidmem[i] = ' ';
> +}
> +
> +#define XMTRDY          0x20
> +
> +#define TXR             0       /*  Transmit register (WRITE) */
> +#define LSR             5       /*  Line Status               */
> +
> +static void serial_putchar(int ch)
> +{
> +       unsigned int timeout = 0xffff;
> +
> +       while ((inb(early_serial_base + LSR) & XMTRDY) == 0 && --timeout)
> +               cpu_relax();
> +
> +       outb(ch, early_serial_base + TXR);
> +}
> +
> +static void putstr(const char *s)
> +{
> +       int x, y, pos;
> +       char c;
> +
> +       if (early_serial_base) {
> +               const char *str = s;
> +
> +               while (*str) {
> +                       if (*str == '\n')
> +                               serial_putchar('\r');
> +                       serial_putchar(*str++);
> +               }
> +       }
> +
> +       if (lines == 0 || cols == 0)
> +               return;
> +
> +       x = boot_params->screen_info.orig_x;
> +       y = boot_params->screen_info.orig_y;
> +
> +       while ((c = *s++) != '\0') {
> +               if (c == '\n') {
> +                       x = 0;
> +                       if (++y >= lines) {
> +                               scroll();
> +                               y--;
> +                       }
> +               } else {
> +                       vidmem[(x + cols * y) * 2] = c;
> +                       if (++x >= cols) {
> +                               x = 0;
> +                               if (++y >= lines) {
> +                                       scroll();
> +                                       y--;
> +                               }
> +                       }
> +               }
> +       }
> +
> +       boot_params->screen_info.orig_x = x;
> +       boot_params->screen_info.orig_y = y;
> +
> +       pos = (x + cols * y) * 2;       /* Update cursor position */
> +       outb(14, vidport);
> +       outb(0xff & (pos >> 9), vidport+1);
> +       outb(15, vidport);
> +       outb(0xff & (pos >> 1), vidport+1);
> +}
> +
> +static void puthex(unsigned long value)
> +{
> +       char alpha[2] = "0";
> +       int bits;
> +
> +       for (bits = sizeof(value) * 8 - 4; bits >= 0; bits -= 4) {
> +               unsigned long digit = (value >> bits) & 0xf;
> +
> +               if (digit < 0xA)
> +                       alpha[0] = '0' + digit;
> +               else
> +                       alpha[0] = 'a' + (digit - 0xA);
> +
> +               putstr(alpha);
> +       }
> +}
> --
> 2.35.1
>

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ