[PATCH] erofs-utils: tar: fix negative GNU base-256 number parsing
Vansh Choudhary
ch at vnsh.in
Sun Apr 5 20:18:30 AEST 2026
GNU base-256 fields use a 0xff prefix for negative values, but
tarerofs_parsenum() currently accumulates them in signed long long.
That does not sign-extend negative values correctly and can also
trigger signed-overflow undefined behavior while shifting.
Handle positive and negative GNU base-256 fields separately and do the
byte accumulation in unsigned long long instead.
This fixes GNU base-256 decoding for negative tar metadata values such
as mtime, uid, gid and device numbers.
Fixes: 95d315fd7958 ("erofs-utils: introduce tarerofs")
Signed-off-by: Vansh Choudhary <ch at vnsh.in>
---
lib/tar.c | 15 ++++++++++++---
1 file changed, 12 insertions(+), 3 deletions(-)
diff --git a/lib/tar.c b/lib/tar.c
index 871779a..05d1a74 100644
--- a/lib/tar.c
+++ b/lib/tar.c
@@ -328,17 +328,26 @@ static long long tarerofs_otoi(const char *ptr, int len)
static long long tarerofs_parsenum(const char *ptr, int len)
{
+ const u8 *p = (const u8 *)ptr;
+
errno = 0;
/*
* For fields containing numbers or timestamps that are out of range
* for the basic format, the GNU format uses a base-256 representation
* instead of an ASCII octal number.
*/
- if (*(char *)ptr == '\200' || *(char *)ptr == '\377') {
- long long res = 0;
+ if (*(char *)ptr == '\200') {
+ unsigned long long res = 0;
while (--len)
- res = (res << 8) | (u8)*(++ptr);
+ res = (res << 8) | *(++p);
+ return res;
+ }
+ if (*(char *)ptr == '\377') {
+ unsigned long long res = -1ULL;
+
+ while (len--)
+ res = (res << 8) | *(p++);
return res;
}
return tarerofs_otoi(ptr, len);
--
2.43.0
More information about the Linux-erofs
mailing list