Page MenuHomeFreeBSD

Implement vsyscall hack. Looks like prior to 2.13 glibc vsyscall technique used instead of proper vdso symbols.
ClosedPublic

Authored by dchagin on Nov 3 2014, 8:21 AM.
Tags
None
Referenced Files
Unknown Object (File)
Thu, May 2, 3:49 AM
Unknown Object (File)
Tue, Apr 23, 9:52 PM
Unknown Object (File)
Feb 3 2024, 6:06 AM
Unknown Object (File)
Jan 26 2024, 3:22 PM
Unknown Object (File)
Jan 26 2024, 3:22 PM
Unknown Object (File)
Jan 26 2024, 3:22 PM
Unknown Object (File)
Jan 26 2024, 3:22 PM
Unknown Object (File)
Jan 26 2024, 3:22 PM

Diff Detail

Repository
rS FreeBSD src repository - subversion
Lint
Lint Not Applicable
Unit
Tests Not Applicable

Event Timeline

dchagin retitled this revision from to Implement vsyscall hack. Looks like prior to 2.13 glibc vsyscall technique used instead of proper vdso symbols..
trasz added inline comments.
sys/amd64/amd64/trap.c
265 ↗(On Diff #2238)

Would it be possible to move it out from the fast path somehow? What's the 'type' argument here?

In D1090#3, @trasz wrote:

Would it be possible to move it out from the fast path somehow? What's the 'type' argument here?

type is a page fault, can be moved to the T_PAGEFLT.
But I think this vsyscall hack is dangerous, and as modern glib uses vdso we can avoid implementing it
or hide by sysctl?

"vsyscall mechanism has some limitations: the memory allocated is small and allows only 4 system calls, and, more important and serious, the vsyscall page is statically allocated to the same address in each process, since the location of the vsyscall page is nailed down in the kernel ABI. This static allocation of the vsyscall compromises the benefit introduced by the memory space randomisation commonly used by Linux. An attacker, after compromising an application by exploiting a stack-overflow, can invoke a system call from the vsyscall page with arbitrary parameters. All he needs is the address of the system call, which is easily predicable as it is statically allocated (if you try to run again your command even with different applications, you'll notice that the address of the vsyscall does not change). It would be nice to remove or at least randomize the location of the vsyscall page to thwart this type of attack. Unfortunately, applications depend on the existence and exact address of that page, so nothing can be done."

unfortunately, current default linux-base c6 depends on vsyscall.

Have you talked to linux-c6 maintainer? Perhaps there is some way to avoid it. Does that version of glibc use it unconditionally, or depending on eg. reported kernel version?

If we cannot avoid it - could it be implemented by mapping the shared page (in a way similar to eg mmap) and hooking vsyscall there? This way the code in trap handler wouldn't be needed; traps would be generated only on access to that particular page - again, similar to mmapping a device.

In D1090#9, @trasz wrote:

Have you talked to linux-c6 maintainer? Perhaps there is some way to avoid it. Does that version of glibc use it unconditionally, or depending on eg. reported kernel version?

If we cannot avoid it - could it be implemented by mapping the shared page (in a way similar to eg mmap) and hooking vsyscall there? This way the code in trap handler wouldn't be needed; traps would be generated only on access to that particular page - again, similar to mmapping a device.

vsyscall is a predecessor of vdso, I think vsyscall does not used by modern glibc. We have PR 193106 for fedora-20 ports.

I'd prefer make fedora-20 default instead of merging vsyscall even, Johannes?

Please see the discussion above.

The main problem with Fedora 20 is that the userland ports for it don't exist.
We'd need someone to create ~75 linux-f10- ports before importing it into the tree, then some time to test to make sure no regressions are introduced, etc.

In D1090#13, @xmj wrote:

The main problem with Fedora 20 is that the userland ports for it don't exist.
We'd need someone to create ~75 linux-f10- ports before importing it into the tree, then some time to test to make sure no regressions are introduced, etc.

https://github.com/vassilisl/freebsd-linux_base-f20 there is not enough?

Hm, I've just replaced linux-f10 with linux-c6 and it still seems to work, without vsyscall. How exactly does it depend on it?

In D1090#39027, @trasz wrote:

Hm, I've just replaced linux-f10 with linux-c6 and it still seems to work, without vsyscall. How exactly does it depend on it?

ah, x86_64 Linuxulator depends on vsyscall, btw, vsyscall support has removed from glibc-2.21.

kib added inline comments.
sys/amd64/linux/linux_sysvec.c
789 ↗(On Diff #4475)

You do not need to pass trapframe, it is already available as td->td_frame.

794 ↗(On Diff #4475)

It is weird to return ERESTART there, even if the code is not used. You return EFAULT from copyin below, so -1 there should be considered ERESTART.

Select some reasonable error code.

803 ↗(On Diff #4475)

Off by 2.

819 ↗(On Diff #4475)

This is weird as well, amd64_syscall() was designed to be only called from the asm syscall code. The interface is not quite external.

dchagin edited edge metadata.

fixed!

and I don't see any other syscall entry point unless amd64_syscall()

sys/amd64/linux/linux_sysvec.c
780 ↗(On Diff #12060)

ENOSYS in comment does not match returned value. I do not understand the comment, BTW.

781 ↗(On Diff #12060)

Now it is off by one. Think what would be called for code == LINUX_VSYSCALL_NR. Also, why did not you used nitems() ?

dchagin edited edge metadata.

Fix kib@ notes

sorry, ENOSYS was some crasy logic.

Updating D1090: Implement vsyscall hack. Looks like prior to 2.13 glibc vsyscall

technique used instead of proper vdso symbols.

dchagin edited edge metadata.

-1 removed from vector

Updating D1090: Implement vsyscall hack. Looks like prior to 2.13 glibc vsyscall

technique used instead of proper vdso symbols.

kib added a reviewer: kib.
This revision is now accepted and ready to land.Jan 9 2016, 8:09 PM
This revision was automatically updated to reflect the committed changes.