Messages in this thread | | | From | Alphabet Hotel <> | Date | Tue, 31 May 2022 09:11:59 -0400 | 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"); }
| |