From ee188125b10d1588a0536af033d7b7b1bbbaafaf Mon Sep 17 00:00:00 2001 From: Mark Wielaard Date: Sun, 28 Aug 2022 19:51:13 +0200 Subject: [PATCH] libelf: Correctly decode ar_mode as octal string ar_mode is encoded as an octal ascii string, not decimal. Add a new OCT_FIELD macro to decode it. https://sourceware.org/bugzilla/show_bug.cgi?id=28729 Signed-off-by: Mark Wielaard --- libelf/elf_begin.c | 25 +++++++++++++++++++++++-- 1 files changed, 23 insertions(+), 2 deletions(-) diff --git a/libelf/elf_begin.c b/libelf/elf_begin.c index 17d9b1f3..71eb3594 100644 --- a/libelf/elf_begin.c +++ b/libelf/elf_begin.c @@ -977,7 +977,8 @@ __libelf_next_arhdr_wrlock (Elf *elf) atoll depending on the size of the types. We are also prepared for the case where the whole field in the `struct ar_hdr' is filled in which case we cannot simply use atol/l but instead have - to create a temporary copy. */ + to create a temporary copy. Note that all fields use decimal + encoding, except ar_mode which uses octal. */ #define INT_FIELD(FIELD) \ do \ @@ -997,10 +998,30 @@ __libelf_next_arhdr_wrlock (Elf *elf) } \ while (0) +#define OCT_FIELD(FIELD) \ + do \ + { \ + char buf[sizeof (ar_hdr->FIELD) + 1]; \ + const char *string = ar_hdr->FIELD; \ + if (ar_hdr->FIELD[sizeof (ar_hdr->FIELD) - 1] != ' ') \ + { \ + *((char *) mempcpy (buf, ar_hdr->FIELD, sizeof (ar_hdr->FIELD))) \ + = '\0'; \ + string = buf; \ + } \ + if (sizeof (elf_ar_hdr->FIELD) <= sizeof (long int)) \ + elf_ar_hdr->FIELD \ + = (__typeof (elf_ar_hdr->FIELD)) strtol (string, NULL, 8); \ + else \ + elf_ar_hdr->FIELD \ + = (__typeof (elf_ar_hdr->FIELD)) strtoll (string, NULL, 8); \ + } \ + while (0) + INT_FIELD (ar_date); INT_FIELD (ar_uid); INT_FIELD (ar_gid); - INT_FIELD (ar_mode); + OCT_FIELD (ar_mode); INT_FIELD (ar_size); if (elf_ar_hdr->ar_size < 0) -- 2.27.0