Skip to content
Navigation Menu
Toggle navigation
Sign in
In this repository
All GitHub Enterprise
↵
Jump to
↵
No suggested jump to results
In this repository
All GitHub Enterprise
↵
Jump to
↵
In this organization
All GitHub Enterprise
↵
Jump to
↵
In this repository
All GitHub Enterprise
↵
Jump to
↵
Sign in
Reseting focus
You signed in with another tab or window.
Reload
to refresh your session.
You signed out in another tab or window.
Reload
to refresh your session.
You switched accounts on another tab or window.
Reload
to refresh your session.
Dismiss alert
{{ message }}
mariux64
/
linux
Public
Notifications
You must be signed in to change notification settings
Fork
0
Star
0
Code
Issues
2
Pull requests
0
Actions
Projects
0
Wiki
Security
Insights
Additional navigation options
Code
Issues
Pull requests
Actions
Projects
Wiki
Security
Insights
Files
cfac6df
Documentation
arch
alpha
arc
arm
arm64
avr32
blackfin
c6x
cris
frv
h8300
hexagon
ia64
m32r
m68k
metag
microblaze
mips
mn10300
nios2
openrisc
parisc
powerpc
s390
score
sh
sparc
tile
um
unicore32
x86
boot
configs
crypto
entry
events
hyperv
ia32
include
kernel
acpi
apic
cpu
fpu
kprobes
.gitignore
Makefile
alternative.c
amd_gart_64.c
amd_nb.c
apb_timer.c
aperture_64.c
apm_32.c
asm-offsets.c
asm-offsets_32.c
asm-offsets_64.c
audit_64.c
bootflag.c
check.c
cpuid.c
crash.c
crash_dump_32.c
crash_dump_64.c
devicetree.c
doublefault.c
dumpstack.c
dumpstack_32.c
dumpstack_64.c
e820.c
early-quirks.c
early_printk.c
ebda.c
espfix_64.c
ftrace.c
head32.c
head64.c
head_32.S
head_64.S
hpet.c
hw_breakpoint.c
i8237.c
i8253.c
i8259.c
io_delay.c
ioport.c
irq.c
irq_32.c
irq_64.c
irq_work.c
irqinit.c
itmt.c
jump_label.c
kdebugfs.c
kexec-bzimage64.c
kgdb.c
ksysfs.c
kvm.c
kvmclock.c
ldt.c
livepatch.c
machine_kexec_32.c
machine_kexec_64.c
mcount_64.S
mmconf-fam10h_64.c
module.c
mpparse.c
msr.c
nmi.c
nmi_selftest.c
paravirt-spinlocks.c
paravirt.c
paravirt_patch_32.c
paravirt_patch_64.c
pci-calgary_64.c
pci-dma.c
pci-iommu_table.c
pci-nommu.c
pci-swiotlb.c
pcspeaker.c
perf_regs.c
platform-quirks.c
pmem.c
probe_roms.c
process.c
process_32.c
process_64.c
ptrace.c
pvclock.c
quirks.c
reboot.c
reboot_fixups_32.c
relocate_kernel_32.S
relocate_kernel_64.S
resource.c
rtc.c
setup.c
setup_percpu.c
signal.c
signal_compat.c
smp.c
smpboot.c
stacktrace.c
step.c
sys_x86_64.c
sysfb.c
sysfb_efi.c
sysfb_simplefb.c
tboot.c
tce_64.c
time.c
tls.c
tls.h
topology.c
trace_clock.c
tracepoint.c
traps.c
tsc.c
tsc_msr.c
tsc_sync.c
unwind_frame.c
unwind_guess.c
uprobes.c
verify_cpu.S
vm86_32.c
vmlinux.lds.S
vsmp_64.c
x86_init.c
kvm
lguest
lib
math-emu
mm
net
oprofile
pci
platform
power
purgatory
ras
realmode
tools
um
video
xen
.gitignore
Kbuild
Kconfig
Kconfig.cpu
Kconfig.debug
Makefile
Makefile.um
Makefile_32.cpu
xtensa
.gitignore
Kconfig
block
certs
crypto
drivers
firmware
fs
include
init
ipc
kernel
lib
mm
net
samples
scripts
security
sound
tools
usr
virt
.cocciconfig
.get_maintainer.ignore
.gitattributes
.gitignore
.mailmap
COPYING
CREDITS
Kbuild
Kconfig
MAINTAINERS
Makefile
README
Breadcrumbs
linux
/
arch
/
x86
/
kernel
/
signal_compat.c
Copy path
Blame
Blame
Latest commit
History
History
228 lines (198 loc) · 6.97 KB
Breadcrumbs
linux
/
arch
/
x86
/
kernel
/
signal_compat.c
Top
File metadata and controls
Code
Blame
228 lines (198 loc) · 6.97 KB
Raw
#include <linux/compat.h> #include <linux/uaccess.h> #include <linux/ptrace.h> /* * The compat_siginfo_t structure and handing code is very easy * to break in several ways. It must always be updated when new * updates are made to the main siginfo_t, and * copy_siginfo_to_user32() must be updated when the * (arch-independent) copy_siginfo_to_user() is updated. * * It is also easy to put a new member in the compat_siginfo_t * which has implicit alignment which can move internal structure * alignment around breaking the ABI. This can happen if you, * for instance, put a plain 64-bit value in there. */ static inline void signal_compat_build_tests(void) { int _sifields_offset = offsetof(compat_siginfo_t, _sifields); /* * If adding a new si_code, there is probably new data in * the siginfo. Make sure folks bumping the si_code * limits also have to look at this code. Make sure any * new fields are handled in copy_siginfo_to_user32()! */ BUILD_BUG_ON(NSIGILL != 8); BUILD_BUG_ON(NSIGFPE != 8); BUILD_BUG_ON(NSIGSEGV != 4); BUILD_BUG_ON(NSIGBUS != 5); BUILD_BUG_ON(NSIGTRAP != 4); BUILD_BUG_ON(NSIGCHLD != 6); BUILD_BUG_ON(NSIGSYS != 1); /* This is part of the ABI and can never change in size: */ BUILD_BUG_ON(sizeof(compat_siginfo_t) != 128); /* * The offsets of all the (unioned) si_fields are fixed * in the ABI, of course. Make sure none of them ever * move and are always at the beginning: */ BUILD_BUG_ON(offsetof(compat_siginfo_t, _sifields) != 3 * sizeof(int)); #define CHECK_CSI_OFFSET(name) BUILD_BUG_ON(_sifields_offset != offsetof(compat_siginfo_t, _sifields.name)) /* * Ensure that the size of each si_field never changes. * If it does, it is a sign that the * copy_siginfo_to_user32() code below needs to updated * along with the size in the CHECK_SI_SIZE(). * * We repeat this check for both the generic and compat * siginfos. * * Note: it is OK for these to grow as long as the whole * structure stays within the padding size (checked * above). */ #define CHECK_CSI_SIZE(name, size) BUILD_BUG_ON(size != sizeof(((compat_siginfo_t *)0)->_sifields.name)) #define CHECK_SI_SIZE(name, size) BUILD_BUG_ON(size != sizeof(((siginfo_t *)0)->_sifields.name)) CHECK_CSI_OFFSET(_kill); CHECK_CSI_SIZE (_kill, 2*sizeof(int)); CHECK_SI_SIZE (_kill, 2*sizeof(int)); CHECK_CSI_OFFSET(_timer); CHECK_CSI_SIZE (_timer, 5*sizeof(int)); CHECK_SI_SIZE (_timer, 6*sizeof(int)); CHECK_CSI_OFFSET(_rt); CHECK_CSI_SIZE (_rt, 3*sizeof(int)); CHECK_SI_SIZE (_rt, 4*sizeof(int)); CHECK_CSI_OFFSET(_sigchld); CHECK_CSI_SIZE (_sigchld, 5*sizeof(int)); CHECK_SI_SIZE (_sigchld, 8*sizeof(int)); CHECK_CSI_OFFSET(_sigchld_x32); CHECK_CSI_SIZE (_sigchld_x32, 7*sizeof(int)); /* no _sigchld_x32 in the generic siginfo_t */ CHECK_CSI_OFFSET(_sigfault); CHECK_CSI_SIZE (_sigfault, 4*sizeof(int)); CHECK_SI_SIZE (_sigfault, 8*sizeof(int)); CHECK_CSI_OFFSET(_sigpoll); CHECK_CSI_SIZE (_sigpoll, 2*sizeof(int)); CHECK_SI_SIZE (_sigpoll, 4*sizeof(int)); CHECK_CSI_OFFSET(_sigsys); CHECK_CSI_SIZE (_sigsys, 3*sizeof(int)); CHECK_SI_SIZE (_sigsys, 4*sizeof(int)); /* any new si_fields should be added here */ } void sigaction_compat_abi(struct k_sigaction *act, struct k_sigaction *oact) { /* Don't leak in-kernel non-uapi flags to user-space */ if (oact) oact->sa.sa_flags &= ~(SA_IA32_ABI | SA_X32_ABI); if (!act) return; /* Don't let flags to be set from userspace */ act->sa.sa_flags &= ~(SA_IA32_ABI | SA_X32_ABI); if (in_ia32_syscall()) act->sa.sa_flags |= SA_IA32_ABI; if (in_x32_syscall()) act->sa.sa_flags |= SA_X32_ABI; } int __copy_siginfo_to_user32(compat_siginfo_t __user *to, const siginfo_t *from, bool x32_ABI) { int err = 0; signal_compat_build_tests(); if (!access_ok(VERIFY_WRITE, to, sizeof(compat_siginfo_t))) return -EFAULT; put_user_try { /* If you change siginfo_t structure, please make sure that this code is fixed accordingly. It should never copy any pad contained in the structure to avoid security leaks, but must copy the generic 3 ints plus the relevant union member. */ put_user_ex(from->si_signo, &to->si_signo); put_user_ex(from->si_errno, &to->si_errno); put_user_ex((short)from->si_code, &to->si_code); if (from->si_code < 0) { put_user_ex(from->si_pid, &to->si_pid); put_user_ex(from->si_uid, &to->si_uid); put_user_ex(ptr_to_compat(from->si_ptr), &to->si_ptr); } else { /* * First 32bits of unions are always present: * si_pid === si_band === si_tid === si_addr(LS half) */ put_user_ex(from->_sifields._pad[0], &to->_sifields._pad[0]); switch (from->si_code >> 16) { case __SI_FAULT >> 16: if (from->si_signo == SIGBUS && (from->si_code == BUS_MCEERR_AR || from->si_code == BUS_MCEERR_AO)) put_user_ex(from->si_addr_lsb, &to->si_addr_lsb); if (from->si_signo == SIGSEGV) { if (from->si_code == SEGV_BNDERR) { compat_uptr_t lower = (unsigned long)from->si_lower; compat_uptr_t upper = (unsigned long)from->si_upper; put_user_ex(lower, &to->si_lower); put_user_ex(upper, &to->si_upper); } if (from->si_code == SEGV_PKUERR) put_user_ex(from->si_pkey, &to->si_pkey); } break; case __SI_SYS >> 16: put_user_ex(from->si_syscall, &to->si_syscall); put_user_ex(from->si_arch, &to->si_arch); break; case __SI_CHLD >> 16: if (!x32_ABI) { put_user_ex(from->si_utime, &to->si_utime); put_user_ex(from->si_stime, &to->si_stime); } else { put_user_ex(from->si_utime, &to->_sifields._sigchld_x32._utime); put_user_ex(from->si_stime, &to->_sifields._sigchld_x32._stime); } put_user_ex(from->si_status, &to->si_status); /* FALL THROUGH */ default: case __SI_KILL >> 16: put_user_ex(from->si_uid, &to->si_uid); break; case __SI_POLL >> 16: put_user_ex(from->si_fd, &to->si_fd); break; case __SI_TIMER >> 16: put_user_ex(from->si_overrun, &to->si_overrun); put_user_ex(ptr_to_compat(from->si_ptr), &to->si_ptr); break; /* This is not generated by the kernel as of now. */ case __SI_RT >> 16: case __SI_MESGQ >> 16: put_user_ex(from->si_uid, &to->si_uid); put_user_ex(from->si_int, &to->si_int); break; } } } put_user_catch(err); return err; } /* from syscall's path, where we know the ABI */ int copy_siginfo_to_user32(compat_siginfo_t __user *to, const siginfo_t *from) { return __copy_siginfo_to_user32(to, from, in_x32_syscall()); } int copy_siginfo_from_user32(siginfo_t *to, compat_siginfo_t __user *from) { int err = 0; u32 ptr32; if (!access_ok(VERIFY_READ, from, sizeof(compat_siginfo_t))) return -EFAULT; get_user_try { get_user_ex(to->si_signo, &from->si_signo); get_user_ex(to->si_errno, &from->si_errno); get_user_ex(to->si_code, &from->si_code); get_user_ex(to->si_pid, &from->si_pid); get_user_ex(to->si_uid, &from->si_uid); get_user_ex(ptr32, &from->si_ptr); to->si_ptr = compat_ptr(ptr32); } get_user_catch(err); return err; }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
You can’t perform that action at this time.