OpenBSD fails to execute a.out
Asked Answered
Q

2

5

I wrote this program that should just exit with exitcode 44:

// prog.S
#include <sys/syscall.h>
        .text
        .globl _start
_start:
        subl $8, %esp
        pushl $44
        pushl $0
        movl $SYS_exit, %eax
        int $0x80

I compiled with

$ cc prog.S -nostdlib -o a.out

and run

$./a.out

Doing so on FreeBSD 13.0-RELEASE i386 (clang 11.0.1) worked fine. In fact, the executable runs and the exit code of the program is 44 as it should be.

However, doing the same on OpenBSD 7.0 GENERIC.MP#5 i386 (clang version 11.1.0) and on NetBSD 9.2 i386 (gcc 7.5.0), the kernel refused to execute the code and it was passed to the shell, which of course failed:

openbsd$ ./a.out
./a.out[1]: syntax error: `(' unexpected

The strange thing is also that file says it's an ELF binary and therefore should be normally executed by the kernel

openbsd$ file a.out

a.out: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), statically linked, not stripped

Even objdump prints what is expected to print

openbsd$ objdump -d a.out

a.out:     file format elf32-i386

Disassembly of section .text:

00001184 <_start>:
    1184:   83 ec 08                sub    $0x8,%esp
    1187:   6a 2c                   push   $0x2c
    1189:   b8 01 00 00 00          mov    $0x1,%eax
    118e:   6a 00                   push   $0x0
    1190:   cd 80                   int    $0x80


Any idea about what I'm doing wrong?

PS: Changing _start with main and compiling without -nostdlib works fine both on OpenBSD and NetBSD

Quinquereme answered 5/2, 2022 at 17:27 Comment(7)
u sure its the right file and that its marked executablePlainsong
@Plainsong Yep. It's 755Quinquereme
and that its the right file? what does file a.out sayPlainsong
@pm100. file a.out says it's recognized to be an executable at least. I even tried to recompile it many times and I can assure you that that's the executable compiled by clang. Always the same resultQuinquereme
Could any (Open/Net)BSD user confirm this behaviorQuinquereme
Reproduced on an old OpenBSD 6.7 amd64 vm that I had laying around. I'd guess it does some extra checks on an ELF executable before deciding to actually execute it, and if those fail it decides to try it as a shell script instead. What checks those might be, and why this binary fails them, I don't know.Hodges
What does objdump say about it?Cuneiform
Q
5

I found out that OpenBSD checks for .section ".note.openbsd.ident", "a". If it's not present it doesn't execute the file. If I substituted _start with main and linked without -nostdlib, .note.openbsd.ident can be found in libc. Similarly for NetBSD.

To learn more visit https://www.exploit-db.com/papers/13219

Quinquereme answered 7/2, 2022 at 14:14 Comment(0)
O
4

On recent versions of NetBSD you can also link an assembler language program starting with the _start symbol and with -nostdlib by including just /usr/lib/sysident.o, for example like this:

as -o thello.o thello.s && ld -Bstatic -o thello /usr/lib/sysident.o thello.o

On recent NetBSD this object also includes a .note.netbsd.pax section for controlling the PaX executable security features such as Mprotect, ASLR, and Segvguard.

Have a look in the #include <elf/common.h> file for definitions for similar note sections for other types of target systems.

See also https://polprog.net/blog/netbsdasmprog/

See also https://github.com/robohack/experiments/blob/master/thello.s

Overthrow answered 11/2, 2022 at 19:36 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.