Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/arch/um/os-Linux/process.c
49156 views
1
// SPDX-License-Identifier: GPL-2.0
2
/*
3
* Copyright (C) 2015 Thomas Meyer ([email protected])
4
* Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
5
*/
6
7
#include <stdio.h>
8
#include <stdlib.h>
9
#include <unistd.h>
10
#include <errno.h>
11
#include <signal.h>
12
#include <fcntl.h>
13
#include <limits.h>
14
#include <linux/futex.h>
15
#include <sys/mman.h>
16
#include <sys/ptrace.h>
17
#include <sys/prctl.h>
18
#include <sys/wait.h>
19
#include <asm/unistd.h>
20
#include <init.h>
21
#include <longjmp.h>
22
#include <os.h>
23
#include <skas/skas.h>
24
25
void os_alarm_process(int pid)
26
{
27
if (pid <= 0)
28
return;
29
30
kill(pid, SIGALRM);
31
}
32
33
void os_kill_process(int pid, int reap_child)
34
{
35
if (pid <= 0)
36
return;
37
38
/* Block signals until child is reaped */
39
block_signals();
40
41
kill(pid, SIGKILL);
42
if (reap_child)
43
CATCH_EINTR(waitpid(pid, NULL, __WALL));
44
45
unblock_signals();
46
}
47
48
/* Kill off a ptraced child by all means available. kill it normally first,
49
* then PTRACE_KILL it, then PTRACE_CONT it in case it's in a run state from
50
* which it can't exit directly.
51
*/
52
53
void os_kill_ptraced_process(int pid, int reap_child)
54
{
55
if (pid <= 0)
56
return;
57
58
/* Block signals until child is reaped */
59
block_signals();
60
61
kill(pid, SIGKILL);
62
ptrace(PTRACE_KILL, pid);
63
ptrace(PTRACE_CONT, pid);
64
if (reap_child)
65
CATCH_EINTR(waitpid(pid, NULL, __WALL));
66
67
unblock_signals();
68
}
69
70
pid_t os_reap_child(void)
71
{
72
int status;
73
74
/* Try to reap a child */
75
return waitpid(-1, &status, WNOHANG);
76
}
77
78
/* Don't use the glibc version, which caches the result in TLS. It misses some
79
* syscalls, and also breaks with clone(), which does not unshare the TLS.
80
*/
81
82
int os_getpid(void)
83
{
84
return syscall(__NR_getpid);
85
}
86
87
int os_map_memory(void *virt, int fd, unsigned long long off, unsigned long len,
88
int r, int w, int x)
89
{
90
void *loc;
91
int prot;
92
93
prot = (r ? PROT_READ : 0) | (w ? PROT_WRITE : 0) |
94
(x ? PROT_EXEC : 0);
95
96
loc = mmap64((void *) virt, len, prot, MAP_SHARED | MAP_FIXED,
97
fd, off);
98
if (loc == MAP_FAILED)
99
return -errno;
100
return 0;
101
}
102
103
int os_protect_memory(void *addr, unsigned long len, int r, int w, int x)
104
{
105
int prot = ((r ? PROT_READ : 0) | (w ? PROT_WRITE : 0) |
106
(x ? PROT_EXEC : 0));
107
108
if (mprotect(addr, len, prot) < 0)
109
return -errno;
110
111
return 0;
112
}
113
114
int os_unmap_memory(void *addr, int len)
115
{
116
int err;
117
118
err = munmap(addr, len);
119
if (err < 0)
120
return -errno;
121
return 0;
122
}
123
124
#ifndef MADV_REMOVE
125
#define MADV_REMOVE KERNEL_MADV_REMOVE
126
#endif
127
128
int os_drop_memory(void *addr, int length)
129
{
130
int err;
131
132
err = madvise(addr, length, MADV_REMOVE);
133
if (err < 0)
134
err = -errno;
135
return err;
136
}
137
138
int __init can_drop_memory(void)
139
{
140
void *addr;
141
int fd, ok = 0;
142
143
printk(UM_KERN_INFO "Checking host MADV_REMOVE support...");
144
fd = create_mem_file(UM_KERN_PAGE_SIZE);
145
if (fd < 0) {
146
printk(UM_KERN_ERR "Creating test memory file failed, "
147
"err = %d\n", -fd);
148
goto out;
149
}
150
151
addr = mmap64(NULL, UM_KERN_PAGE_SIZE, PROT_READ | PROT_WRITE,
152
MAP_SHARED, fd, 0);
153
if (addr == MAP_FAILED) {
154
printk(UM_KERN_ERR "Mapping test memory file failed, "
155
"err = %d\n", -errno);
156
goto out_close;
157
}
158
159
if (madvise(addr, UM_KERN_PAGE_SIZE, MADV_REMOVE) != 0) {
160
printk(UM_KERN_ERR "MADV_REMOVE failed, err = %d\n", -errno);
161
goto out_unmap;
162
}
163
164
printk(UM_KERN_CONT "OK\n");
165
ok = 1;
166
167
out_unmap:
168
munmap(addr, UM_KERN_PAGE_SIZE);
169
out_close:
170
close(fd);
171
out:
172
return ok;
173
}
174
175
void init_new_thread_signals(void)
176
{
177
set_handler(SIGSEGV);
178
set_handler(SIGTRAP);
179
set_handler(SIGFPE);
180
set_handler(SIGILL);
181
set_handler(SIGBUS);
182
signal(SIGHUP, SIG_IGN);
183
set_handler(SIGIO);
184
/* We (currently) only use the child reaper IRQ in seccomp mode */
185
if (using_seccomp)
186
set_handler(SIGCHLD);
187
signal(SIGWINCH, SIG_IGN);
188
}
189
190
void os_set_pdeathsig(void)
191
{
192
prctl(PR_SET_PDEATHSIG, SIGKILL);
193
}
194
195
int os_futex_wait(void *uaddr, unsigned int val)
196
{
197
int r;
198
199
CATCH_EINTR(r = syscall(__NR_futex, uaddr, FUTEX_WAIT, val,
200
NULL, NULL, 0));
201
return r < 0 ? -errno : r;
202
}
203
204
int os_futex_wake(void *uaddr)
205
{
206
int r;
207
208
CATCH_EINTR(r = syscall(__NR_futex, uaddr, FUTEX_WAKE, INT_MAX,
209
NULL, NULL, 0));
210
return r < 0 ? -errno : r;
211
}
212
213