libarchive/0010-Fix-CVE-2026-15028.patch
Daniel Handzus 1241138f64 Fix for CVE-2026-15028 and CVE-2026-16517
Patches in the upstream archive_integer.h library,
which both CVE fixes depend on.

Resolves: RHEL-215400
Resolves: RHEL-215640
2026-08-20 10:47:10 +02:00

81 lines
2.1 KiB
Diff

diff -Naur libarchive-3.7.7/libarchive/archive_read_support_format_tar.c libarchive-3.7.7-patch/libarchive/archive_read_support_format_tar.c
--- libarchive-3.7.7/libarchive/archive_read_support_format_tar.c 2026-08-18 08:43:36.246102967 +0200
+++ libarchive-3.7.7-patch/libarchive/archive_read_support_format_tar.c 2026-08-18 08:49:13.860883568 +0200
@@ -42,6 +42,7 @@
#include "archive_acl_private.h" /* For ACL parsing routines. */
#include "archive_entry.h"
#include "archive_entry_locale.h"
+#include "archive_integer.h"
#include "archive_private.h"
#include "archive_read_private.h"
@@ -3246,13 +3247,10 @@
return (ARCHIVE_FATAL);
tar->sparse_last->hole = hole;
}
- if (length == 0 || *e == '\n') {
- if (length == 0 && *e == '\n') {
- return (ARCHIVE_OK);
- } else {
- return (ARCHIVE_WARN);
- }
- }
+ if (length == 0)
+ return (ARCHIVE_OK);
+ if (*e == '\n')
+ return (ARCHIVE_WARN);
p = e + 1;
length--;
hole = hole == 0;
@@ -3296,13 +3294,9 @@
static int64_t
tar_atol_base_n(const char *p, size_t char_cnt, int base)
{
- int64_t l, maxval, limit, last_digit_limit;
+ int64_t l;
int digit, sign;
- maxval = INT64_MAX;
- limit = INT64_MAX / base;
- last_digit_limit = INT64_MAX % base;
-
/* the pointer will not be dereferenced if char_cnt is zero
* due to the way the && operator is evaluated.
*/
@@ -3316,25 +3310,22 @@
sign = -1;
p++;
char_cnt--;
-
- maxval = INT64_MIN;
- limit = -(INT64_MIN / base);
- last_digit_limit = -(INT64_MIN % base);
}
l = 0;
- if (char_cnt != 0) {
+ while (char_cnt != 0) {
digit = *p - '0';
- while (digit >= 0 && digit < base && char_cnt != 0) {
- if (l>limit || (l == limit && digit >= last_digit_limit)) {
- return maxval; /* Truncate on overflow. */
- }
- l = (l * base) + digit;
- digit = *++p - '0';
- char_cnt--;
+ if (digit < 0 || digit >= base)
+ break;
+ if (archive_ckd_mul_i64(&l, l, base) ||
+ archive_ckd_add_i64(&l, l, sign * digit)) {
+ /* Truncate on overflow. */
+ return sign < 0 ? INT64_MIN : INT64_MAX;
}
+ p++;
+ char_cnt--;
}
- return (sign < 0) ? -l : l;
+ return l;
}
static int64_t