diff mbox series

[1/3] modpost: add array range check to sec_name()

Message ID 20220730173636.1303357-1-masahiroy@kernel.org (mailing list archive)
State New, archived
Headers show
Series [1/3] modpost: add array range check to sec_name() | expand

Commit Message

Masahiro Yamada July 30, 2022, 5:36 p.m. UTC
The section index is always positive, so the argunent, secindex, should
be unsigned.

Also, inserted the array range check.

If sym->st_shndx is a special section index (between SHN_LORESERVE and
SHN_HIRESERVE), there is no corresponding section header.

For example, if a symbol specifies an absolute value, sym->st_shndx is
SHN_ABS (=0xfff1).

The current users do not cause the out-of-range access of
info->sechddrs[], but it is better to avoid such a pitfall.

Signed-off-by: Masahiro Yamada <masahiroy@kernel.org>
---

 scripts/mod/modpost.c | 10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)

Comments

Jeff Johnson Aug. 1, 2022, 8:29 p.m. UTC | #1
On 7/30/2022 10:36 AM, Masahiro Yamada wrote:
> The section index is always positive, so the argunent, secindex, should

nit: s/argunent/argument/
Masahiro Yamada Aug. 2, 2022, 5:09 p.m. UTC | #2
On Tue, Aug 2, 2022 at 5:29 AM Jeff Johnson <quic_jjohnson@quicinc.com> wrote:
>
> On 7/30/2022 10:36 AM, Masahiro Yamada wrote:
> > The section index is always positive, so the argunent, secindex, should
>
> nit: s/argunent/argument/

Thanks.
I will not send v2 just because of this typo.
I locally fixed it.
Nick Desaulniers Aug. 2, 2022, 5:55 p.m. UTC | #3
On Sat, Jul 30, 2022 at 10:37 AM Masahiro Yamada <masahiroy@kernel.org> wrote:
>
> The section index is always positive, so the argunent, secindex, should
> be unsigned.
>
> Also, inserted the array range check.
>
> If sym->st_shndx is a special section index (between SHN_LORESERVE and
> SHN_HIRESERVE), there is no corresponding section header.
>
> For example, if a symbol specifies an absolute value, sym->st_shndx is
> SHN_ABS (=0xfff1).
>
> The current users do not cause the out-of-range access of
> info->sechddrs[], but it is better to avoid such a pitfall.
>
> Signed-off-by: Masahiro Yamada <masahiroy@kernel.org>

I don't mind adding this check; though if it's anomalous I think we
could also just print to stderr and abort.

I would prefer Elf_Sym over unsigned int though.  WDYT?

> ---
>
>  scripts/mod/modpost.c | 10 +++++++++-
>  1 file changed, 9 insertions(+), 1 deletion(-)
>
> diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c
> index 08411fff3e17..148b38699889 100644
> --- a/scripts/mod/modpost.c
> +++ b/scripts/mod/modpost.c
> @@ -336,8 +336,16 @@ static const char *sech_name(const struct elf_info *info, Elf_Shdr *sechdr)
>                                       sechdr->sh_name);
>  }
>
> -static const char *sec_name(const struct elf_info *info, int secindex)
> +static const char *sec_name(const struct elf_info *info, unsigned int secindex)
>  {
> +       /*
> +        * If sym->st_shndx is a special section index, there is no
> +        * corresponding section header.
> +        * Return "" if the index is out of range of info->sechdrs[] array.
> +        */
> +       if (secindex >= info->num_sections)
> +               return "";
> +
>         return sech_name(info, &info->sechdrs[secindex]);
>  }
>
> --
> 2.34.1
>
Masahiro Yamada Aug. 3, 2022, 10:05 a.m. UTC | #4
On Wed, Aug 3, 2022 at 2:55 AM Nick Desaulniers <ndesaulniers@google.com> wrote:
>
> On Sat, Jul 30, 2022 at 10:37 AM Masahiro Yamada <masahiroy@kernel.org> wrote:
> >
> > The section index is always positive, so the argunent, secindex, should
> > be unsigned.
> >
> > Also, inserted the array range check.
> >
> > If sym->st_shndx is a special section index (between SHN_LORESERVE and
> > SHN_HIRESERVE), there is no corresponding section header.
> >
> > For example, if a symbol specifies an absolute value, sym->st_shndx is
> > SHN_ABS (=0xfff1).
> >
> > The current users do not cause the out-of-range access of
> > info->sechddrs[], but it is better to avoid such a pitfall.
> >
> > Signed-off-by: Masahiro Yamada <masahiroy@kernel.org>
>
> I don't mind adding this check; though if it's anomalous I think we
> could also just print to stderr and abort.


If  sec_name() has a failure path,
I need to add another check before calling sec_name().


I want to get a return value that can be safely passed
to strcmp(), etc.


For example,

   strcmp(!sec_name(elf, secindex),  "some_pattern");


Returning "" for special sections
will work nicely without additional check code.



I am changing the code with a bigger picture in my mind,
although that may not be so clear if you look at this patch only.



> I would prefer Elf_Sym over unsigned int though.  WDYT?
>

In /usr/include/elf.h, Elf{32,64}_Sym are structures.
How to use it instead of unsigned int?


typedef struct
{
  Elf32_Word    st_name;                /* Symbol name (string tbl index) */
  Elf32_Addr    st_value;               /* Symbol value */
  Elf32_Word    st_size;                /* Symbol size */
  unsigned char st_info;                /* Symbol type and binding */
  unsigned char st_other;               /* Symbol visibility */
  Elf32_Section st_shndx;               /* Section index */
} Elf32_Sym;

typedef struct
{
  Elf64_Word    st_name;                /* Symbol name (string tbl index) */
  unsigned char st_info;                /* Symbol type and binding */
  unsigned char st_other;               /* Symbol visibility */
  Elf64_Section st_shndx;               /* Section index */
  Elf64_Addr    st_value;               /* Symbol value */
  Elf64_Xword   st_size;                /* Symbol size */
} Elf64_Sym;




Best Regards
Masahiro Yamada
diff mbox series

Patch

diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c
index 08411fff3e17..148b38699889 100644
--- a/scripts/mod/modpost.c
+++ b/scripts/mod/modpost.c
@@ -336,8 +336,16 @@  static const char *sech_name(const struct elf_info *info, Elf_Shdr *sechdr)
 				      sechdr->sh_name);
 }
 
-static const char *sec_name(const struct elf_info *info, int secindex)
+static const char *sec_name(const struct elf_info *info, unsigned int secindex)
 {
+	/*
+	 * If sym->st_shndx is a special section index, there is no
+	 * corresponding section header.
+	 * Return "" if the index is out of range of info->sechdrs[] array.
+	 */
+	if (secindex >= info->num_sections)
+		return "";
+
 	return sech_name(info, &info->sechdrs[secindex]);
 }