]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
stub: Properly null-terminate filenames in pack_cpio_one
authorAdrian Vovk <adrianvovk@gmail.com>
Wed, 8 Dec 2021 02:01:46 +0000 (21:01 -0500)
committerAdrian Vovk <adrianvovk@gmail.com>
Wed, 8 Dec 2021 18:57:01 +0000 (13:57 -0500)
Previously, mangle_filename would write the null terminator, but
then wouldn't increment the pointer. Thus, the pad4 call that comes
immediately after mangle_filename would trample over the null
terminator that mangle_filename wrote. Since the padding is all
0s, this happened to work for the filenames it was tested for

However, in some cases, this would cause the pointer to be a different
position than predicted. Basically, the predicted size would be one
byte bigger than the actual size (the missing null terminator). Usually,
this disappeared into the alignment padding at the end of the buffer,
but if the buffer was already unexpectedly aligned (b/c it was a byte
shorter than expected), this would cause assertion failures.

Also, the c_namesize field in the cpio header was incorrect. It
didn't include the null terminator, as required by the spec.

src/boot/efi/cpio.c

index d7dd50fc8fa2615fd4063edfab9a7c7677456862..d4c870284bb62ee1e8bb3c8eab7f5ab746611d5d 100644 (file)
@@ -34,7 +34,7 @@ static CHAR8* mangle_filename(CHAR8 *p, const CHAR16 *f) {
                 *(w++) = *f;
         }
 
-        *w = 0;
+        *(w++) = 0;
         return w;
 }
 
@@ -138,7 +138,7 @@ static EFI_STATUS pack_cpio_one(
         a = write_cpio_word(a, 0);                                          /* minor(dev) */
         a = write_cpio_word(a, 0);                                          /* major(rdev) */
         a = write_cpio_word(a, 0);                                          /* minor(rdev) */
-        a = write_cpio_word(a, target_dir_prefix_size + fname_size + 1);    /* fname size */
+        a = write_cpio_word(a, target_dir_prefix_size + fname_size + 2);    /* fname size */
         a = write_cpio_word(a, 0);                                          /* "crc" */
 
         CopyMem(a, target_dir_prefix, target_dir_prefix_size);