[Bug 269568] strip(1) creates an executable which crashes in ld-elf.so.1

From: <bugzilla-noreply_at_freebsd.org>
Date: Thu, 16 Mar 2023 13:19:37 UTC

--- Comment #2 from Fernando ApesteguĂ­a <fernape@FreeBSD.org> ---
More info:

The problem is with the GNU_STACK segment. I edited the binary and changed the
vaddr and msize to match that of the original unstripped file and the resulting
binary runs fine.

Inspecting the sources of strip(1) I found the problem is in the copy_phdr
function in segments.c in this specific code:

                if (seg->nsec > 0) {
                        s = seg->v_sec[0];
                        seg->vaddr = s->vma;
                        seg->paddr = s->lma;

                seg->fsz = seg->msz = 0;
                for (i = 0; i < seg->nsec; i++) {
                        s = seg->v_sec[i];
                        seg->msz = s->vma + s->sz - seg->vaddr;
                        if (s->type != SHT_NOBITS)
                                seg->fsz = s->off + s->sz - seg->off;

Changing that part so we actually copy the program header verbatim creates an
executable that doesn't crash. This kind of behavior seems to be similar to
what llvm-strip and gnustrip do. To check this, using the objects created by a
"make kernel" and "make buildworld" strip the full binary and check the
original program header and the one from the stripped binary:

for file in $(find . -name '*.full')
do t=$(mktemp /tmp/tmp.XXXX)
        "${STRIP_CMD}" -o "${t}" "${file}"
        diff <(readelf -l "${file}") <(readelf -l "${t}")
        if [[ $? -eq 0 ]]
        then            echo "Equal program header for ${file}"
        else            echo "Different program header for ${file}"
        rm "${t}"

llvm-strip doesn't change the program header at all nor does GNU strip. But
strip(1) in base changes it quite often (RELRO, INTERP and at least in jdupes
case GNU_STACK segments).

You are receiving this mail because:
You are the assignee for the bug.