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 |
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/
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.
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 >
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 --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]); }
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(-)