]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
lib/buildid: remove single-page limit for PHDR search
authorAndrii Nakryiko <andrii@kernel.org>
Thu, 29 Aug 2024 17:42:26 +0000 (10:42 -0700)
committerAlexei Starovoitov <ast@kernel.org>
Wed, 11 Sep 2024 16:58:30 +0000 (09:58 -0700)
Now that freader allows to access multiple pages transparently, there is
no need to limit program headers to the very first ELF file page. Remove
this limitation, but still put some sane limit on amount of program
headers that we are willing to iterate over (set arbitrarily to 256).

Reviewed-by: Eduard Zingerman <eddyz87@gmail.com>
Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
Link: https://lore.kernel.org/r/20240829174232.3133883-5-andrii@kernel.org
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
lib/buildid.c

index 7fb08a1d98bd1aed36f994c19298df185fac0a6e..e8fc4aeb01f2d28e06fc697eb8a6b6facf84c120 100644 (file)
@@ -8,6 +8,8 @@
 
 #define BUILD_ID 3
 
+#define MAX_PHDR_CNT 256
+
 struct freader {
        void *buf;
        u32 buf_sz;
@@ -223,9 +225,9 @@ static int get_build_id_32(struct freader *r, unsigned char *build_id, __u32 *si
        phnum = READ_ONCE(ehdr->e_phnum);
        phoff = READ_ONCE(ehdr->e_phoff);
 
-       /* only supports phdr that fits in one page */
-       if (phnum > (PAGE_SIZE - sizeof(Elf32_Ehdr)) / sizeof(Elf32_Phdr))
-               return -EINVAL;
+       /* set upper bound on amount of segments (phdrs) we iterate */
+       if (phnum > MAX_PHDR_CNT)
+               phnum = MAX_PHDR_CNT;
 
        /* check that phoff is not large enough to cause an overflow */
        if (phoff + phnum * sizeof(Elf32_Phdr) < phoff)
@@ -260,9 +262,9 @@ static int get_build_id_64(struct freader *r, unsigned char *build_id, __u32 *si
        phnum = READ_ONCE(ehdr->e_phnum);
        phoff = READ_ONCE(ehdr->e_phoff);
 
-       /* only supports phdr that fits in one page */
-       if (phnum > (PAGE_SIZE - sizeof(Elf64_Ehdr)) / sizeof(Elf64_Phdr))
-               return -EINVAL;
+       /* set upper bound on amount of segments (phdrs) we iterate */
+       if (phnum > MAX_PHDR_CNT)
+               phnum = MAX_PHDR_CNT;
 
        /* check that phoff is not large enough to cause an overflow */
        if (phoff + phnum * sizeof(Elf64_Phdr) < phoff)