Source: libarchive
Version: 3.7.2-2
Severity: normal
X-Debbugs-Cc: debian-m...@lists.debian.org, ty...@mit.edu
Control: affects -1 src:e2fsprogs

Hi,

the upload of e2fsprogs 1.47.1~rc1-1 to unstable yesterday uses a new
feature where libarchive is used to create filesystem images from
tarballs. This works on all architectures (main as well as ports) except
on mips64el:

https://buildd.debian.org/status/package.php?p=e2fsprogs

I attached a minimal reproducer. It includes an embedded gzipped tarball with a
single file called "myfilename" of size 10. It works fine if _FILE_OFFSET_BITS
is not set but with it, it reports a wrong archive member size of zero on
mips64el:

    $ gcc -Wall -g -O0 libarchivetest.c -larchive -D_FILE_OFFSET_BITS=64
    $ ./a.out
    myfilename: 0

Since the reproducer only makes use of libarchive, I'm filing this as a
libarchive bug. Since this problem is mips64el specific, I'm putting the
porter-list in X-Debbugs-Cc.

The problem can also be reproduced on bookworm.

gdb can show what is going on (thanks to Theodore Ts'o for the initial
debugging):

(gdb) run
[...]
Breakpoint 1, main () at test.c:49
49                      st = archive_entry_stat(entry);
(gdb) next
50                      fprintf(stderr, "%s: %ld\n", 
archive_entry_pathname(entry), st->st_size);
(gdb) p *st
$2 = {st_dev = 1, st_pad1 = {0, 0, 0}, st_ino = 1, st_mode = 33188, st_nlink = 
0, 
  st_uid = 1000, st_gid = 1000, st_rdev = 0, st_pad2 = {0, 0, 10}, st_size = 0, 
  st_atim = {tv_sec = 0, tv_nsec = 0}, st_mtim = {tv_sec = 1714375615, tv_nsec 
= 0}, 
  st_ctim = {tv_sec = 0, tv_nsec = 0}, st_blksize = 0, st_pad4 = 0, st_blocks = 
0, 
  st_pad5 = {0 <repeats 14 times>}}

As one can see, the size "10" is not in st_size but in the padding before the
st_size member. This only happens when _FILE_OFFSET_BITS=64 and only on
mips64el.

Any idea what is going on with mips64el?

Thanks!

cheers, josch
#include <stdio.h>
#include <archive.h>
#include <archive_entry.h>

// gzipped tarball created with xxd --include
unsigned char archive_tar_gz[] = {
  0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xed, 0xce,
  0x41, 0x0a, 0xc2, 0x30, 0x10, 0x85, 0xe1, 0x59, 0x7b, 0x8a, 0x1c, 0x21,
  0xa3, 0xd3, 0xe4, 0x3c, 0xa5, 0x44, 0xb4, 0x98, 0x14, 0xda, 0xb8, 0xe8,
  0xed, 0xad, 0xb8, 0xd0, 0x95, 0xd2, 0x45, 0x29, 0xc2, 0xff, 0x6d, 0x1e,
  0xc3, 0x9b, 0xc5, 0xcb, 0xf3, 0xf9, 0x7a, 0x4b, 0xa5, 0xcd, 0x49, 0x36,
  0xe3, 0x17, 0xc1, 0xec, 0x99, 0x1a, 0x1b, 0xff, 0x99, 0x2f, 0x7a, 0x14,
  0xb5, 0xa0, 0xa7, 0x60, 0x4d, 0x88, 0x51, 0x96, 0x5b, 0x4d, 0xc5, 0xf9,
  0xed, 0x26, 0xbd, 0xdd, 0xa7, 0xda, 0x8e, 0xce, 0x49, 0x3f, 0x4c, 0xdd,
  0xe5, 0xcb, 0xdf, 0xaf, 0xfe, 0x4f, 0xe5, 0xb9, 0x1b, 0x4a, 0x4d, 0xa5,
  0x1e, 0xf6, 0x5e, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x58, 0xe3, 0x01, 0x16, 0x64, 0x3c, 0x30,
  0x00, 0x28, 0x00, 0x00
};
unsigned int archive_tar_gz_len = 136;

int main() {
        int ret;
        struct archive_entry *entry;
        const struct stat *st;

        struct archive *a = archive_read_new();
        if (a == NULL) {
                fprintf(stderr, "archive_read_new\n");
                return 1;
        }
        archive_read_support_filter_all(a);
        archive_read_support_format_all(a);
        ret = archive_read_open_memory(a, archive_tar_gz, archive_tar_gz_len);
        if (ret != ARCHIVE_OK) {
                fprintf(stderr, "archive_read_open_memory\n");
                return 1;
        }
        for (;;) {
                ret = archive_read_next_header(a, &entry);
                if (ret == ARCHIVE_EOF) {
                        break;
                }
                if (ret != ARCHIVE_OK) {
                        fprintf(stderr, "archive_read_next_header\n");
                        return 1;
                }
                st = archive_entry_stat(entry);
                fprintf(stderr, "%s: %ld\n", archive_entry_pathname(entry), 
st->st_size);
        }
        archive_read_close(a);
        archive_read_free(a);
        return 0;
}

Reply via email to