[Bug 225105] Linux static golang binaries crash at startup
bugzilla-noreply at freebsd.org
bugzilla-noreply at freebsd.org
Fri Jan 12 20:27:22 UTC 2018
https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=225105
--- Comment #4 from Conrad Meyer <cem at freebsd.org> ---
(In reply to Edward Tomasz Napierala from comment #1)
I think r313993 did (sort of) introduce this bug. I'm curious why reverting it
does not fix the issue. I think one problem may be the lack of
set_pcb_flags(pcb, PCB_FULL_IRET) in linux_set_cloned_tls().
Here's the problem: AMD64_SET_FSBASE expects a pointer to a pointer:
case AMD64_SET_FSBASE:
error = copyin(uap->parms, &a64base, sizeof(a64base));
if (!error) {
if (a64base < VM_MAXUSER_ADDRESS) {
set_pcb_flags(pcb, PCB_FULL_IRET);
pcb->pcb_fsbase = a64base;
td->td_frame->tf_fs = _ufssel;
} else
error = EINVAL;
}
break;
linux_arch_prctl() after r313993 is just passing in the pointer value itself:
case LINUX_ARCH_SET_FS:
bsd_args.op = AMD64_SET_FSBASE;
bsd_args.parms = (void *)args->addr;
error = sysarch(td, &bsd_args);
Previously, it would set the value args->addr directly:
case LINUX_ARCH_SET_FS:
error = linux_set_cloned_tls(td, (void *)args->addr);
...
linux_set_cloned_tls(struct thread *td, void *desc)
{
...
pcb = td->td_pcb;
pcb->pcb_fsbase = (register_t)desc;
Please try this patch:
--- a/sys/amd64/linux/linux_machdep.c
+++ b/sys/amd64/linux/linux_machdep.c
@@ -234,14 +234,14 @@ linux_arch_prctl(struct thread *td, struct
linux_arch_prctl_args *args)
switch (args->code) {
case LINUX_ARCH_SET_GS:
bsd_args.op = AMD64_SET_GSBASE;
- bsd_args.parms = (void *)args->addr;
+ bsd_args.parms = (void *)&args->addr;
error = sysarch(td, &bsd_args);
if (error == EINVAL)
error = EPERM;
break;
case LINUX_ARCH_SET_FS:
bsd_args.op = AMD64_SET_FSBASE;
- bsd_args.parms = (void *)args->addr;
+ bsd_args.parms = (void *)&args->addr;
error = sysarch(td, &bsd_args);
if (error == EINVAL)
error = EPERM;
I would also consider changing linux_set_cloned_tls to match sysarch()
AMD64_SET_FSBASE:
@@ -271,6 +271,7 @@ linux_set_cloned_tls(struct thread *td, void *desc)
return (EPERM);
pcb = td->td_pcb;
+ set_pcb_flags(pcb, PCB_FULL_IRET);
pcb->pcb_fsbase = (register_t)desc;
td->td_frame->tf_fs = _ufssel;
Or better yet, just invoking sysarch() as well:
@@ -265,14 +265,13 @@ linux_arch_prctl(struct thread *td, struct
linux_arch_prctl_args *args)
int
linux_set_cloned_tls(struct thread *td, void *desc)
{
- struct pcb *pcb;
-
- if ((uint64_t)desc >= VM_MAXUSER_ADDRESS)
- return (EPERM);
-
- pcb = td->td_pcb;
- pcb->pcb_fsbase = (register_t)desc;
- td->td_frame->tf_fs = _ufssel;
+ struct sysarch_args bsd_args;
+ int error;
- return (0);
+ bsd_args.op = AMD64_SET_FSBASE;
+ bsd_args.parms = (void *)&desc;
+ error = sysarch(td, &bsd_args);
+ if (error == EINVAL)
+ error = EPERM;
+ return (error);
}
--
You are receiving this mail because:
You are the assignee for the bug.
More information about the freebsd-bugs
mailing list