]> git.ipfire.org Git - thirdparty/libarchive.git/commitdiff
rar: Fix OOB access with unicode filenames (#2203)
authorTobias Stoeckmann <stoeckmann@users.noreply.github.com>
Sun, 2 Jun 2024 23:28:45 +0000 (01:28 +0200)
committerGitHub <noreply@github.com>
Sun, 2 Jun 2024 23:28:45 +0000 (16:28 -0700)
Prevent out of boundary accesses by revalidating offset every time it is
incremented.

libarchive/archive_read_support_format_rar.c

index 3f3d7db2bc9aa53b2081c6c89925e66b173aa6ce..054b47ad0c8a4c4eacaa4ed54d610af2fb010681 100644 (file)
@@ -1545,7 +1545,7 @@ read_header(struct archive_read *a, struct archive_entry *entry,
       fn_end = filename_size * 2;
       filename_size = 0;
       offset = (unsigned)strlen(filename) + 1;
-      highbyte = *(p + offset++);
+      highbyte = offset >= end ? 0 : *(p + offset++);
       flagbits = 0;
       flagbyte = 0;
       while (offset < end && filename_size < fn_end)
@@ -1560,14 +1560,22 @@ read_header(struct archive_read *a, struct archive_entry *entry,
         switch((flagbyte >> flagbits) & 3)
         {
           case 0:
+            if (offset >= end)
+              continue;
             filename[filename_size++] = '\0';
             filename[filename_size++] = *(p + offset++);
             break;
           case 1:
+            if (offset >= end)
+              continue;
             filename[filename_size++] = highbyte;
             filename[filename_size++] = *(p + offset++);
             break;
           case 2:
+            if (offset >= end - 1) {
+              offset = end;
+              continue;
+            }
             filename[filename_size++] = *(p + offset + 1);
             filename[filename_size++] = *(p + offset);
             offset += 2;
@@ -1575,9 +1583,15 @@ read_header(struct archive_read *a, struct archive_entry *entry,
           case 3:
           {
             char extra, high;
-            uint8_t length = *(p + offset++);
+            uint8_t length;
+
+            if (offset >= end)
+              continue;
 
+            length = *(p + offset++);
             if (length & 0x80) {
+              if (offset >= end)
+                continue;
               extra = *(p + offset++);
               high = (char)highbyte;
             } else