1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-30 21:58:10 +00:00
serenity/Userland/Libraries/LibC/arch/i386/setjmp.S
Daniel Bertalan bd6dc5ccec Meta+LibC: Don't allow text relocations in SerenityOS libraries
The `-z,text` linker flag causes the linker to reject shared libraries
and PIE executables that have textrels. Our code mostly did not use
these except in one place in LibC, which is changed in this commit.
This makes GNU ld match LLD's behavior, which has this option enabled by
default.

TEXTRELs pose a security risk, as performing these relocations require
executable pages to be written to by the dynamic linker. This can
significantly weaken W^X hardening mitigations.

Note that after this change, TEXTRELs can still be used in ports, as the
dynamic loader code is not changed. There are also uses of it in the
kernel, removing which are outside the scope of this PR. To allow those,
`-z,notext` is added.
2021-08-18 18:01:22 +02:00

70 lines
1.7 KiB
ArmAsm

/*
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <bits/sighow.h>
//
// /!\ Read setjmp.h before modifying this file!
//
.global setjmp
setjmp:
mov 4(%esp), %ecx // Grab jmp_buf argument
xor %eax, %eax // Grab val argument (hardcoded to zero)
jmp .Lsigset_common
.global sigsetjmp
sigsetjmp:
mov 4(%esp), %ecx // Grab jmp_buf argument
mov 8(%esp), %eax // Grab val argument
.Lsigset_common:
mov %eax, 24(%ecx) // Store val into did_save_signal_mask
movl $0, 28(%ecx) // Clear saved_signal_mask
test %eax, %eax
jz .Lsaveregs
lea 28(%ecx), %eax // Set argument oldset
push %eax
push $0 // Set argument set
push $0 // Set argument how
call sigprocmask@plt
add $12, %esp
.Lsaveregs:
mov (%esp), %edx // Grab return address
mov %ebx, (0 * 4)(%ecx) // Save registers
mov %esi, (1 * 4)(%ecx)
mov %edi, (2 * 4)(%ecx)
mov %ebp, (3 * 4)(%ecx)
mov %esp, (4 * 4)(%ecx)
mov %edx, (5 * 4)(%ecx)
xor %eax, %eax
ret
.global longjmp
longjmp:
mov 4(%esp), %ecx // Grab jmp_buf argument
mov 8(%esp), %eax // Grab val argument
test %eax, %eax
jnz .Lnonzero
mov $1, %eax
.Lnonzero:
mov (0 * 4)(%ecx), %ebx // Restore registers
mov (1 * 4)(%ecx), %esi
mov (2 * 4)(%ecx), %edi
mov (3 * 4)(%ecx), %ebp
//
// Until this point, the stack is still from the caller.
//
mov (4 * 4)(%ecx), %esp
mov (5 * 4)(%ecx), %edx
mov %edx, (%esp) // Patch return address
//
// From this point on, the former stack has been restored.
//
ret