lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [day] [month] [year] [list]
Message-ID: <CAC12nxd9qfvoskRiP+fm6daoxKUbNO9LBH4VX_RoXRsuL-9Jmg@mail.gmail.com>
Date:   Tue, 31 May 2022 09:11:59 -0400
From:   Alphabet Hotel <alephhotel285@...il.com>
To:     linux-kernel@...r.kernel.org
Subject: x86-32: can't create call gate in LDT?

I was looking at emulating the lcall7 syscall interface in userspace
but it seems I can't even ask for a call gate. I did get it to work by
using a regular code segment for entry 0 and mapping my lcall7 handler
at offset 0 but now I'm in a different code segment and GCC is lost.
Could the ability to use call gates be added to the kernel? The patch
looks fairly easy and if it only allows calls into the existing CS it
should be safe. My test program works as-is but it's a hack and it
would require switching segments on every syscall.

#define _GNU_SOURCE
#include <stdio.h>
#include <err.h>
#include <sys/syscall.h>
#include <asm/ldt.h>

static int ret = 1, val = 0;

static void __attribute__ ((regparm(1))) lcall7(int call_nr) {
    val = call_nr;              // remaining args are on the stack
    asm volatile ("xor %eax,%eax;"
                  "lret;"       // far return is required
    );
}

int main() {
    struct user_desc desc = {
            .entry_number = 0,
            .base_addr = (unsigned long)&lcall7,
            .limit = 1,          // one page
            .limit_in_pages = 1,
            .seg_32bit = 1,
            .contents = 2,       // non-conforming code
    };

    if (syscall(__NR_modify_ldt, 0x11, &desc, sizeof(desc)))
        err(1, "modify_ldt");

    asm volatile ("lcall $7,$0;"
                  : "=a" (ret)
                  : "a" (42)
    );
    if (!ret && val == 42)
        printf("lcall7 worked\n");
}

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ