123elf icon indicating copy to clipboard operation
123elf copied to clipboard

OpenBSD port

Open vrza opened this issue 2 years ago • 4 comments

Project now builds using the feature branch from https://github.com/taviso/123elf/pull/86

It segfaults at runtime in init_terminal_settings in wrappers.c, when ioctl(2) (called by tcgetattr(3)) attempts to write to this memory location:

static struct termios original;

ioctl(2) fails with errno == 14 (EFAULT, "Bad address").

Is it possible that there is some unsafe programming practice at play here that OpenBSD catches?

vrza avatar Jun 09 '22 11:06 vrza

Passing a pointer to heap memory to ioctl instead works around the problem:

void __attribute__((constructor)) init_terminal_settings()
{
    // Make a backup of the terminal state to restore to later.
    int attr;
    struct termios *t;
    t = malloc(sizeof(struct termios));
    if (isatty(STDIN_FILENO)) {
        attr = tcgetattr(STDIN_FILENO, t);
        memmove(t, &original, sizeof(struct termios));
        if (attr != 0) err(EXIT_FAILURE, "Failed to query terminal attributes.");
    }

}

but I still don't understand why it can't write directly to the data segment.

vrza avatar Jun 09 '22 14:06 vrza

wow, cool that it works!

I'm not really sure why it's failing, the code seems okay to me... I think there's no guarantee about what order constructors are run in, so maybe they're being run too early, and OpenBSD expects some other constructor to run first?

These might not really be necessary anymore though... I might be able to refactor them out. I think now terminal settings are better handled, so less cleanup is necessary.

(Sorry for the slow response to PRs, I'll get to them!)

taviso avatar Jun 09 '22 14:06 taviso

Although it passes the workaround, it proceeds to segfault here:

Program received signal SIGSEGV, Segmentation fault.
0x0804adb8 in ?? ()
(gdb) bt
#0  0x0804adb8 in ?? ()
#1  0x0804a53b in __init ()
#2  0x0804ad67 in _start ()
(gdb) disas __init
Dump of assembler code for function __init:
   0x0804a530 <+0>:	push   %ebp
   0x0804a531 <+1>:	mov    %esp,%ebp
   0x0804a533 <+3>:	and    $0xfffffff0,%esp
   0x0804a536 <+6>:	call   0x804ad90
   0x0804a53b <+11>:	nop
   0x0804a53c <+12>:	leave  
   0x0804a53d <+13>:	ret    
End of assembler dump.

vrza avatar Jun 09 '22 15:06 vrza

After rebuilding the symbol undefine list for OpenBSD (using the Linux list as the starting point), the "Bad address" ioctl issue is gone. I reverted the workaround.

Program still segfaults in __init, though.

vrza avatar Jun 10 '22 17:06 vrza