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