linuxboot / heads

A minimal Linux that runs as a coreboot or LinuxBoot ROM payload to provide a secure, flexible boot environment for laptops, workstations and servers.
https://osresearch.net/
GNU General Public License v2.0
1.43k stars 187 forks source link

lvm segfaults with recent musl-cross #651

Closed osresearch closed 4 years ago

osresearch commented 4 years ago

Tracing it appears that it is failing to find /etc/ld-musl-x86_64.path?

12960 execve("/bin/lvm", ["lvm"], 0x7fbc459a2760 /* 28 vars */) = 0
12960 arch_prctl(ARCH_SET_FS, 0x7fa55302bd88) = 0
12960 set_tid_address(0x7fa55302c35c)   = 12960
12960 open("/etc/ld-musl-x86_64.path", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
12960 open("/lib/libdevmapper.so.1.02", O_RDONLY|O_CLOEXEC) = 3
12960 fcntl(3, F_SETFD, FD_CLOEXEC)     = 0
12960 fstat(3, {st_mode=S_IFREG|0700, st_size=333240, ...}) = 0
12960 read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\300\271\0\0\0\0\0\0"..., 960) = 960
12960 mmap(NULL, 2433024, PROT_READ|PROT_EXEC, MAP_PRIVATE, 3, 0) = 0x7fa552b46000
osresearch commented 4 years ago

Although providing it with that file and /proc doesn't seem to make it happy. (I'm having trouble figuring out how to start lvm under gdb in a chroot, so strace is the next best thing)

13247 execve("/bin/lvm", ["lvm"], 0x7f6aee559760 /* 32 vars */) = 0
13247 arch_prctl(ARCH_SET_FS, 0x7fbf1d0d6d88) = 0
13247 set_tid_address(0x7fbf1d0d735c)   = 13247
13247 open("/etc/ld-musl-x86_64.path", O_RDONLY|O_CLOEXEC) = 3
13247 fcntl(3, F_SETFD, FD_CLOEXEC)     = 0
13247 fcntl(3, F_SETFD, FD_CLOEXEC)     = 0
13247 read(3, "/lib\n", 1024)           = 5
13247 read(3, "", 1024)                 = 0
13247 close(3)                          = 0
13247 open("/lib/libdevmapper.so.1.02", O_RDONLY|O_CLOEXEC) = 3
13247 fcntl(3, F_SETFD, FD_CLOEXEC)     = 0
13247 fstat(3, {st_mode=S_IFREG|0700, st_size=333240, ...}) = 0
13247 read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\300\271\0\0\0\0\0\0"..., 960) = 960
13247 mmap(NULL, 2433024, PROT_READ|PROT_EXEC, MAP_PRIVATE, 3, 0) = 0x7fbf1cbf1000
13247 mmap(0x7fbf1ce3e000, 20480, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED, 3, 0x4d000) = 0x7fbf1ce3e000
13247 mmap(0x7fbf1ce42000, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7fbf1ce42000
13247 close(3)                          = 0
13247 mprotect(0x7fbf1ce3e000, 4096, PROT_READ) = 0
13247 mprotect(0x7fbf1d0d3000, 4096, PROT_READ) = 0
13247 mprotect(0x55e136ee3000, 32768, PROT_READ) = 0
13247 fcntl(2, F_GETFD)                 = 0
13247 getppid()                         = 13241
13247 open("/proc/13241/cmdline", O_RDONLY) = 3
13247 read(3, "/bin/sh\0", 31)          = 8
13247 close(3)                          = 0
13247 open("/proc/self/fd", O_RDONLY|O_CLOEXEC|O_DIRECTORY) = 3
13247 fcntl(3, F_SETFD, FD_CLOEXEC)     = 0
13247 getdents64(3, /* 6 entries */, 2048) = 144
13247 getdents64(3, /* 0 entries */, 2048) = 0
13247 close(3)                          = 0
13247 brk(NULL)                         = 0x55e138ccc000
13247 brk(0x55e138cd0000)               = 0x55e138cd0000
13247 brk(0x55e138cd3000)               = 0x55e138cd3000
13247 fcntl(0, F_GETFD)                 = 0
13247 fcntl(0, F_GETFL)                 = 0x8402 (flags O_RDWR|O_APPEND|O_LARGEFILE)
13247 dup(0)                            = 3
13247 close(0)                          = 0
13247 dup2(3, 0)                        = 0
13247 close(3)                          = 0
13247 --- SIGSEGV {si_signo=SIGSEGV, si_code=SEGV_ACCERR, si_addr=0x7fbf1d0d3e10} ---
13247 +++ killed by SIGSEGV (core dumped) +++
osresearch commented 4 years ago

cut-n-paste from the slack:

regarding the lvm crashes, it is doing some really messy stuff with memory management in lib/mm/memlock.c lots of assumptions about how glibc malloc works and attempts to circumvent it. it calls into mallinfo() to try to figure out fragmentation and calls malloc() with different sizes to force block allocation. really messy stuff. musl says "no" about implementing mallinfo: https://www.openwall.com/lists/musl/2018/01/17/2

my guess is that the musl malloc changed just enough in between the last working version and now, which is causing the segfault

that whole file gives me the heebyjeebies. it reminds me of the custom allocator behind heartbleed; programs trying to be too smart sometimes make questionable decisions. hudson

although... doing some printf debugging makes it look like the attempts to do something with stdin/stdout/stderr might be the problem. because wtf.

and turning off buffering in the call to tool context fixes the segfault.