Can you not add needless dprintf's ? This part is size-constrained on
i386-pc and part of the patch just adds dprintf's unrelated to the
topic at hand.
Can we skip all this on non-efi and have it ifdef-ed out for the sake of size?

On Fri, May 24, 2024 at 2:06 PM Mate Kukri <mate.ku...@canonical.com> wrote:
>
> From: Peter Jones <pjo...@redhat.com>
>
> For NX, we need to set write and executable permissions on the sections
> of grub modules when we load them.
>
> On sections with SHF_ALLOC set, which is typically everything except
> .modname and the symbol and string tables, this patch clears the Read
> Only flag on sections that have the ELF flag SHF_WRITE set, and clears
> the No eXecute flag on sections with SHF_EXECINSTR set.  In all other
> cases it sets both flags.
>
> Signed-off-by: Peter Jones <pjo...@redhat.com>
> [rharwood: arm tgptr -> tgaddr]
> Signed-off-by: Robbie Harwood <rharw...@redhat.com>
> (cherry picked from commit ad1b904d325b7edb651111577e065a20e6b77c74)
> Signed-off-by: Jan Setje-Eilers <jan.setjeeil...@oracle.com>
> Signed-off-by: Mate Kukri <mate.ku...@canonical.com>
>
> Conflicts:
>         grub-core/kern/dl.c     (obvious)
> ---
>  grub-core/kern/dl.c | 102 ++++++++++++++++++++++++++++++++++++++------
>  include/grub/dl.h   |  44 +++++++++++++++++++
>  2 files changed, 133 insertions(+), 13 deletions(-)
>
> diff --git a/grub-core/kern/dl.c b/grub-core/kern/dl.c
> index fb06fd8c6..2784fae7a 100644
> --- a/grub-core/kern/dl.c
> +++ b/grub-core/kern/dl.c
> @@ -233,6 +233,8 @@ grub_dl_load_segments (grub_dl_t mod, const Elf_Ehdr *e)
>  #endif
>    char *ptr;
>
> +  grub_dprintf ("modules", "loading segments for \"%s\"\n", mod->name);
> +
>    arch_addralign = grub_arch_dl_min_alignment ();
>
>    for (i = 0, s = (const Elf_Shdr *)((const char *) e + e->e_shoff);
> @@ -334,6 +336,7 @@ grub_dl_load_segments (grub_dl_t mod, const Elf_Ehdr *e)
>    ptr += got;
>  #endif
>
> +  grub_dprintf ("modules", "done loading segments for \"%s\"\n", mod->name);
>    return GRUB_ERR_NONE;
>  }
>
> @@ -600,6 +603,7 @@ grub_dl_relocate_symbols (grub_dl_t mod, void *ehdr)
>    Elf_Shdr *s;
>    unsigned i;
>
> +  grub_dprintf ("modules", "relocating symbols for \"%s\"\n", mod->name);
>    for (i = 0, s = (Elf_Shdr *) ((char *) e + e->e_shoff);
>         i < e->e_shnum;
>         i++, s = (Elf_Shdr *) ((char *) s + e->e_shentsize))
> @@ -608,22 +612,92 @@ grub_dl_relocate_symbols (grub_dl_t mod, void *ehdr)
>         grub_dl_segment_t seg;
>         grub_err_t err;
>
> -       /* Find the target segment.  */
> -       for (seg = mod->segment; seg; seg = seg->next)
> -         if (seg->section == s->sh_info)
> -           break;
> +       seg = grub_dl_find_segment(mod, s->sh_info);
> +        if (!seg)
> +         continue;
>
> -       if (seg)
> -         {
> -           if (!mod->symtab)
> -             return grub_error (GRUB_ERR_BAD_MODULE, "relocation without 
> symbol table");
> +       if (!mod->symtab)
> +         return grub_error (GRUB_ERR_BAD_MODULE, "relocation without symbol 
> table");
>
> -           err = grub_arch_dl_relocate_symbols (mod, ehdr, s, seg);
> -           if (err)
> -             return err;
> -         }
> +       err = grub_arch_dl_relocate_symbols (mod, ehdr, s, seg);
> +       if (err)
> +         return err;
>        }
>
> +  grub_dprintf ("modules", "done relocating symbols for \"%s\"\n", 
> mod->name);
> +  return GRUB_ERR_NONE;
> +}
> +
> +static grub_err_t
> +grub_dl_set_mem_attrs (grub_dl_t mod, void *ehdr)
> +{

> +  unsigned i;
> +  const Elf_Shdr *s;
> +  const Elf_Ehdr *e = ehdr;
> +#if !defined (__i386__) && !defined (__x86_64__) && !defined(__riscv)
> +  grub_size_t arch_addralign = grub_arch_dl_min_alignment ();
> +  grub_addr_t tgaddr;
> +  grub_uint64_t tgsz;
> +#endif
> +
> +  grub_dprintf ("modules", "updating memory attributes for \"%s\"\n",
> +               mod->name);
> +  for (i = 0, s = (const Elf_Shdr *)((const char *) e + e->e_shoff);
> +       i < e->e_shnum;
> +       i++, s = (const Elf_Shdr *)((const char *) s + e->e_shentsize))
> +    {
> +      grub_dl_segment_t seg;
> +      grub_uint64_t set_attrs = GRUB_MEM_ATTR_R;
> +      grub_uint64_t clear_attrs = GRUB_MEM_ATTR_W|GRUB_MEM_ATTR_X;
> +
> +      seg = grub_dl_find_segment(mod, i);
> +      if (!seg)
> +       continue;
> +
> +      if (seg->size == 0 || !(s->sh_flags & SHF_ALLOC))
> +       continue;
> +
> +      if (s->sh_flags & SHF_WRITE)
> +       {
> +         set_attrs |= GRUB_MEM_ATTR_W;
> +         clear_attrs &= ~GRUB_MEM_ATTR_W;
> +       }
> +
> +      if (s->sh_flags & SHF_EXECINSTR)
> +       {
> +         set_attrs |= GRUB_MEM_ATTR_X;
> +         clear_attrs &= ~GRUB_MEM_ATTR_X;
> +       }
> +
> +      grub_dprintf ("modules", "setting memory attrs for section \"%s\" to 
> -%s%s%s+%s%s%s\n",
> +                   grub_dl_get_section_name(e, s),
> +                   (clear_attrs & GRUB_MEM_ATTR_R) ? "r" : "",
> +                   (clear_attrs & GRUB_MEM_ATTR_W) ? "w" : "",
> +                   (clear_attrs & GRUB_MEM_ATTR_X) ? "x" : "",
> +                   (set_attrs & GRUB_MEM_ATTR_R) ? "r" : "",
> +                   (set_attrs & GRUB_MEM_ATTR_W) ? "w" : "",
> +                   (set_attrs & GRUB_MEM_ATTR_X) ? "x" : "");
> +      grub_update_mem_attrs ((grub_addr_t)(seg->addr), seg->size, set_attrs, 
> clear_attrs);
> +    }
> +
> +#if !defined (__i386__) && !defined (__x86_64__) && !defined(__riscv)
> +  tgaddr = grub_min((grub_addr_t)mod->tramp, (grub_addr_t)mod->got);
> +  tgsz = grub_max((grub_addr_t)mod->trampptr, (grub_addr_t)mod->gotptr) - 
> tgaddr;
> +
> +  if (tgsz)
> +    {
> +      tgsz = ALIGN_UP(tgsz, arch_addralign);
> +
> +      grub_dprintf ("modules", "updating attributes for GOT and 
> trampolines\n",
> +                   mod->name);
> +      grub_update_mem_attrs (tgaddr, tgsz, GRUB_MEM_ATTR_R|GRUB_MEM_ATTR_X,
> +                            GRUB_MEM_ATTR_W);
> +    }
> +#endif
> +
> +  grub_dprintf ("modules", "done updating module memory attributes for 
> \"%s\"\n",
> +               mod->name);
> +
>    return GRUB_ERR_NONE;
>  }
>
> @@ -660,6 +734,7 @@ grub_dl_load_core_noinit (void *addr, grub_size_t size)
>    mod->ref_count = 1;
>
>    grub_dprintf ("modules", "relocating to %p\n", mod);
> +
Needless hunk
>    /* Me, Vladimir Serbinenko, hereby I add this module check as per new
>       GNU module policy. Note that this license check is informative only.
>       Modules have to be licensed under GPLv3 or GPLv3+ (optionally
> @@ -673,7 +748,8 @@ grub_dl_load_core_noinit (void *addr, grub_size_t size)
>        || grub_dl_resolve_dependencies (mod, e)
>        || grub_dl_load_segments (mod, e)
>        || grub_dl_resolve_symbols (mod, e)
> -      || grub_dl_relocate_symbols (mod, e))
> +      || grub_dl_relocate_symbols (mod, e)
> +      || grub_dl_set_mem_attrs (mod, e))
>      {
>        mod->fini = 0;
>        grub_dl_unload (mod);
> diff --git a/include/grub/dl.h b/include/grub/dl.h
> index 8a37cc16f..4c8a9b4ee 100644
> --- a/include/grub/dl.h
> +++ b/include/grub/dl.h
> @@ -27,6 +27,7 @@
>  #include <grub/elf.h>
>  #include <grub/list.h>
>  #include <grub/misc.h>
> +#include <grub/mm.h>
>  #endif
>
>  /*
> @@ -254,6 +255,49 @@ grub_dl_is_persistent (grub_dl_t mod)
>    return mod->persistent;
>  }
>
> +static inline const char *
> +grub_dl_get_section_name (const Elf_Ehdr *e, const Elf_Shdr *s)
> +{
> +  Elf_Shdr *str_s;
> +  const char *str;
> +
> +  str_s = (Elf_Shdr *) ((char *) e + e->e_shoff + e->e_shstrndx * 
> e->e_shentsize);
> +  str = (char *) e + str_s->sh_offset;
> +
> +  return str + s->sh_name;
> +}
> +
> +static inline long
> +grub_dl_find_section_index (Elf_Ehdr *e, const char *name)
> +{
> +  Elf_Shdr *s;
> +  const char *str;
> +  unsigned i;
> +
> +  s = (Elf_Shdr *) ((char *) e + e->e_shoff + e->e_shstrndx * 
> e->e_shentsize);
> +  str = (char *) e + s->sh_offset;
> +
> +  for (i = 0, s = (Elf_Shdr *) ((char *) e + e->e_shoff);
> +       i < e->e_shnum;
> +       i++, s = (Elf_Shdr *) ((char *) s + e->e_shentsize))
> +    if (grub_strcmp (str + s->sh_name, name) == 0)
> +      return (long)i;
> +  return -1;
> +}
> +
> +/* Return the segment for a section of index N */
> +static inline grub_dl_segment_t
> +grub_dl_find_segment (grub_dl_t mod, unsigned n)
> +{
> +  grub_dl_segment_t seg;
> +
> +  for (seg = mod->segment; seg; seg = seg->next)
> +    if (seg->section == n)
> +      return seg;
> +
> +  return NULL;
> +}
> +

I like those inlines

>  #endif
>
>  grub_err_t grub_dl_register_symbol (const char *name, void *addr,
> --
> 2.39.2
>
>
> _______________________________________________
> Grub-devel mailing list
> Grub-devel@gnu.org
> https://lists.gnu.org/mailman/listinfo/grub-devel



-- 
Regards
Vladimir 'phcoder' Serbinenko

_______________________________________________
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel

Reply via email to