diff options
Diffstat (limited to 'arch/um/os-Linux')
-rw-r--r-- | arch/um/os-Linux/mem.c | 118 | ||||
-rw-r--r-- | arch/um/os-Linux/process.c | 8 | ||||
-rw-r--r-- | arch/um/os-Linux/skas/process.c | 36 | ||||
-rw-r--r-- | arch/um/os-Linux/start_up.c | 24 | ||||
-rw-r--r-- | arch/um/os-Linux/trap.c | 4 | ||||
-rw-r--r-- | arch/um/os-Linux/uaccess.c | 4 | ||||
-rw-r--r-- | arch/um/os-Linux/util.c | 2 |
7 files changed, 145 insertions, 51 deletions
diff --git a/arch/um/os-Linux/mem.c b/arch/um/os-Linux/mem.c index 71bb90a7606d..c6432e729241 100644 --- a/arch/um/os-Linux/mem.c +++ b/arch/um/os-Linux/mem.c | |||
@@ -8,6 +8,7 @@ | |||
8 | #include <fcntl.h> | 8 | #include <fcntl.h> |
9 | #include <sys/types.h> | 9 | #include <sys/types.h> |
10 | #include <sys/mman.h> | 10 | #include <sys/mman.h> |
11 | #include <sys/statfs.h> | ||
11 | #include "kern_util.h" | 12 | #include "kern_util.h" |
12 | #include "user.h" | 13 | #include "user.h" |
13 | #include "user_util.h" | 14 | #include "user_util.h" |
@@ -19,6 +20,7 @@ | |||
19 | 20 | ||
20 | #include <sys/param.h> | 21 | #include <sys/param.h> |
21 | 22 | ||
23 | static char *default_tmpdir = "/tmp"; | ||
22 | static char *tempdir = NULL; | 24 | static char *tempdir = NULL; |
23 | 25 | ||
24 | static void __init find_tempdir(void) | 26 | static void __init find_tempdir(void) |
@@ -34,7 +36,7 @@ static void __init find_tempdir(void) | |||
34 | break; | 36 | break; |
35 | } | 37 | } |
36 | if((dir == NULL) || (*dir == '\0')) | 38 | if((dir == NULL) || (*dir == '\0')) |
37 | dir = "/tmp"; | 39 | dir = default_tmpdir; |
38 | 40 | ||
39 | tempdir = malloc(strlen(dir) + 2); | 41 | tempdir = malloc(strlen(dir) + 2); |
40 | if(tempdir == NULL){ | 42 | if(tempdir == NULL){ |
@@ -46,6 +48,96 @@ static void __init find_tempdir(void) | |||
46 | strcat(tempdir, "/"); | 48 | strcat(tempdir, "/"); |
47 | } | 49 | } |
48 | 50 | ||
51 | /* This will return 1, with the first character in buf being the | ||
52 | * character following the next instance of c in the file. This will | ||
53 | * read the file as needed. If there's an error, -errno is returned; | ||
54 | * if the end of the file is reached, 0 is returned. | ||
55 | */ | ||
56 | static int next(int fd, char *buf, int size, char c) | ||
57 | { | ||
58 | int n; | ||
59 | char *ptr; | ||
60 | |||
61 | while((ptr = strchr(buf, c)) == NULL){ | ||
62 | n = read(fd, buf, size - 1); | ||
63 | if(n == 0) | ||
64 | return 0; | ||
65 | else if(n < 0) | ||
66 | return -errno; | ||
67 | |||
68 | buf[n] = '\0'; | ||
69 | } | ||
70 | |||
71 | ptr++; | ||
72 | memmove(buf, ptr, strlen(ptr) + 1); | ||
73 | return 1; | ||
74 | } | ||
75 | |||
76 | static int checked_tmpdir = 0; | ||
77 | |||
78 | /* Look for a tmpfs mounted at /dev/shm. I couldn't find a cleaner | ||
79 | * way to do this than to parse /proc/mounts. statfs will return the | ||
80 | * same filesystem magic number and fs id for both /dev and /dev/shm | ||
81 | * when they are both tmpfs, so you can't tell if they are different | ||
82 | * filesystems. Also, there seems to be no other way of finding the | ||
83 | * mount point of a filesystem from within it. | ||
84 | * | ||
85 | * If a /dev/shm tmpfs entry is found, then we switch to using it. | ||
86 | * Otherwise, we stay with the default /tmp. | ||
87 | */ | ||
88 | static void which_tmpdir(void) | ||
89 | { | ||
90 | int fd, found; | ||
91 | char buf[128] = { '\0' }; | ||
92 | |||
93 | if(checked_tmpdir) | ||
94 | return; | ||
95 | |||
96 | checked_tmpdir = 1; | ||
97 | |||
98 | printf("Checking for tmpfs mount on /dev/shm..."); | ||
99 | |||
100 | fd = open("/proc/mounts", O_RDONLY); | ||
101 | if(fd < 0){ | ||
102 | printf("failed to open /proc/mounts, errno = %d\n", errno); | ||
103 | return; | ||
104 | } | ||
105 | |||
106 | while(1){ | ||
107 | found = next(fd, buf, sizeof(buf) / sizeof(buf[0]), ' '); | ||
108 | if(found != 1) | ||
109 | break; | ||
110 | |||
111 | if(!strncmp(buf, "/dev/shm", strlen("/dev/shm"))) | ||
112 | goto found; | ||
113 | |||
114 | found = next(fd, buf, sizeof(buf) / sizeof(buf[0]), '\n'); | ||
115 | if(found != 1) | ||
116 | break; | ||
117 | } | ||
118 | |||
119 | err: | ||
120 | if(found == 0) | ||
121 | printf("nothing mounted on /dev/shm\n"); | ||
122 | else if(found < 0) | ||
123 | printf("read returned errno %d\n", -found); | ||
124 | |||
125 | return; | ||
126 | |||
127 | found: | ||
128 | found = next(fd, buf, sizeof(buf) / sizeof(buf[0]), ' '); | ||
129 | if(found != 1) | ||
130 | goto err; | ||
131 | |||
132 | if(strncmp(buf, "tmpfs", strlen("tmpfs"))){ | ||
133 | printf("not tmpfs\n"); | ||
134 | return; | ||
135 | } | ||
136 | |||
137 | printf("OK\n"); | ||
138 | default_tmpdir = "/dev/shm"; | ||
139 | } | ||
140 | |||
49 | /* | 141 | /* |
50 | * This proc still used in tt-mode | 142 | * This proc still used in tt-mode |
51 | * (file: kernel/tt/ptproxy/proxy.c, proc: start_debugger). | 143 | * (file: kernel/tt/ptproxy/proxy.c, proc: start_debugger). |
@@ -56,6 +148,7 @@ int make_tempfile(const char *template, char **out_tempname, int do_unlink) | |||
56 | char *tempname; | 148 | char *tempname; |
57 | int fd; | 149 | int fd; |
58 | 150 | ||
151 | which_tmpdir(); | ||
59 | tempname = malloc(MAXPATHLEN); | 152 | tempname = malloc(MAXPATHLEN); |
60 | 153 | ||
61 | find_tempdir(); | 154 | find_tempdir(); |
@@ -137,3 +230,26 @@ int create_mem_file(unsigned long long len) | |||
137 | } | 230 | } |
138 | return(fd); | 231 | return(fd); |
139 | } | 232 | } |
233 | |||
234 | |||
235 | void check_tmpexec(void) | ||
236 | { | ||
237 | void *addr; | ||
238 | int err, fd = create_tmp_file(UM_KERN_PAGE_SIZE); | ||
239 | |||
240 | addr = mmap(NULL, UM_KERN_PAGE_SIZE, | ||
241 | PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE, fd, 0); | ||
242 | printf("Checking PROT_EXEC mmap in %s...",tempdir); | ||
243 | fflush(stdout); | ||
244 | if(addr == MAP_FAILED){ | ||
245 | err = errno; | ||
246 | perror("failed"); | ||
247 | if(err == EPERM) | ||
248 | printf("%s must be not mounted noexec\n",tempdir); | ||
249 | exit(1); | ||
250 | } | ||
251 | printf("OK\n"); | ||
252 | munmap(addr, UM_KERN_PAGE_SIZE); | ||
253 | |||
254 | close(fd); | ||
255 | } | ||
diff --git a/arch/um/os-Linux/process.c b/arch/um/os-Linux/process.c index 8176b0b52047..3505f44f8a25 100644 --- a/arch/um/os-Linux/process.c +++ b/arch/um/os-Linux/process.c | |||
@@ -190,7 +190,7 @@ int os_unmap_memory(void *addr, int len) | |||
190 | } | 190 | } |
191 | 191 | ||
192 | #ifndef MADV_REMOVE | 192 | #ifndef MADV_REMOVE |
193 | #define MADV_REMOVE 0x5 /* remove these pages & resources */ | 193 | #define MADV_REMOVE KERNEL_MADV_REMOVE |
194 | #endif | 194 | #endif |
195 | 195 | ||
196 | int os_drop_memory(void *addr, int length) | 196 | int os_drop_memory(void *addr, int length) |
@@ -216,7 +216,7 @@ int can_drop_memory(void) | |||
216 | } | 216 | } |
217 | 217 | ||
218 | addr = mmap64(NULL, UM_KERN_PAGE_SIZE, PROT_READ | PROT_WRITE, | 218 | addr = mmap64(NULL, UM_KERN_PAGE_SIZE, PROT_READ | PROT_WRITE, |
219 | MAP_PRIVATE, fd, 0); | 219 | MAP_SHARED, fd, 0); |
220 | if(addr == MAP_FAILED){ | 220 | if(addr == MAP_FAILED){ |
221 | printk("Mapping test memory file failed, err = %d\n", -errno); | 221 | printk("Mapping test memory file failed, err = %d\n", -errno); |
222 | return 0; | 222 | return 0; |
@@ -266,11 +266,11 @@ void init_new_thread_signals(int altstack) | |||
266 | 266 | ||
267 | int run_kernel_thread(int (*fn)(void *), void *arg, void **jmp_ptr) | 267 | int run_kernel_thread(int (*fn)(void *), void *arg, void **jmp_ptr) |
268 | { | 268 | { |
269 | sigjmp_buf buf; | 269 | jmp_buf buf; |
270 | int n, enable; | 270 | int n, enable; |
271 | 271 | ||
272 | *jmp_ptr = &buf; | 272 | *jmp_ptr = &buf; |
273 | n = UML_SIGSETJMP(&buf, enable); | 273 | n = UML_SETJMP(&buf, enable); |
274 | if(n != 0) | 274 | if(n != 0) |
275 | return(n); | 275 | return(n); |
276 | (*fn)(arg); | 276 | (*fn)(arg); |
diff --git a/arch/um/os-Linux/skas/process.c b/arch/um/os-Linux/skas/process.c index 045ae0037456..0776bc18ca85 100644 --- a/arch/um/os-Linux/skas/process.c +++ b/arch/um/os-Linux/skas/process.c | |||
@@ -434,7 +434,7 @@ void new_thread(void *stack, void **switch_buf_ptr, void **fork_buf_ptr, | |||
434 | void (*handler)(int)) | 434 | void (*handler)(int)) |
435 | { | 435 | { |
436 | unsigned long flags; | 436 | unsigned long flags; |
437 | sigjmp_buf switch_buf, fork_buf; | 437 | jmp_buf switch_buf, fork_buf; |
438 | int enable; | 438 | int enable; |
439 | 439 | ||
440 | *switch_buf_ptr = &switch_buf; | 440 | *switch_buf_ptr = &switch_buf; |
@@ -450,7 +450,7 @@ void new_thread(void *stack, void **switch_buf_ptr, void **fork_buf_ptr, | |||
450 | */ | 450 | */ |
451 | flags = get_signals(); | 451 | flags = get_signals(); |
452 | block_signals(); | 452 | block_signals(); |
453 | if(UML_SIGSETJMP(&fork_buf, enable) == 0) | 453 | if(UML_SETJMP(&fork_buf, enable) == 0) |
454 | new_thread_proc(stack, handler); | 454 | new_thread_proc(stack, handler); |
455 | 455 | ||
456 | remove_sigstack(); | 456 | remove_sigstack(); |
@@ -466,35 +466,35 @@ void new_thread(void *stack, void **switch_buf_ptr, void **fork_buf_ptr, | |||
466 | 466 | ||
467 | void thread_wait(void *sw, void *fb) | 467 | void thread_wait(void *sw, void *fb) |
468 | { | 468 | { |
469 | sigjmp_buf buf, **switch_buf = sw, *fork_buf; | 469 | jmp_buf buf, **switch_buf = sw, *fork_buf; |
470 | int enable; | 470 | int enable; |
471 | 471 | ||
472 | *switch_buf = &buf; | 472 | *switch_buf = &buf; |
473 | fork_buf = fb; | 473 | fork_buf = fb; |
474 | if(UML_SIGSETJMP(&buf, enable) == 0) | 474 | if(UML_SETJMP(&buf, enable) == 0) |
475 | siglongjmp(*fork_buf, INIT_JMP_REMOVE_SIGSTACK); | 475 | siglongjmp(*fork_buf, INIT_JMP_REMOVE_SIGSTACK); |
476 | } | 476 | } |
477 | 477 | ||
478 | void switch_threads(void *me, void *next) | 478 | void switch_threads(void *me, void *next) |
479 | { | 479 | { |
480 | sigjmp_buf my_buf, **me_ptr = me, *next_buf = next; | 480 | jmp_buf my_buf, **me_ptr = me, *next_buf = next; |
481 | int enable; | 481 | int enable; |
482 | 482 | ||
483 | *me_ptr = &my_buf; | 483 | *me_ptr = &my_buf; |
484 | if(UML_SIGSETJMP(&my_buf, enable) == 0) | 484 | if(UML_SETJMP(&my_buf, enable) == 0) |
485 | UML_SIGLONGJMP(next_buf, 1); | 485 | UML_LONGJMP(next_buf, 1); |
486 | } | 486 | } |
487 | 487 | ||
488 | static sigjmp_buf initial_jmpbuf; | 488 | static jmp_buf initial_jmpbuf; |
489 | 489 | ||
490 | /* XXX Make these percpu */ | 490 | /* XXX Make these percpu */ |
491 | static void (*cb_proc)(void *arg); | 491 | static void (*cb_proc)(void *arg); |
492 | static void *cb_arg; | 492 | static void *cb_arg; |
493 | static sigjmp_buf *cb_back; | 493 | static jmp_buf *cb_back; |
494 | 494 | ||
495 | int start_idle_thread(void *stack, void *switch_buf_ptr, void **fork_buf_ptr) | 495 | int start_idle_thread(void *stack, void *switch_buf_ptr, void **fork_buf_ptr) |
496 | { | 496 | { |
497 | sigjmp_buf **switch_buf = switch_buf_ptr; | 497 | jmp_buf **switch_buf = switch_buf_ptr; |
498 | int n, enable; | 498 | int n, enable; |
499 | 499 | ||
500 | set_handler(SIGWINCH, (__sighandler_t) sig_handler, | 500 | set_handler(SIGWINCH, (__sighandler_t) sig_handler, |
@@ -502,7 +502,7 @@ int start_idle_thread(void *stack, void *switch_buf_ptr, void **fork_buf_ptr) | |||
502 | SIGVTALRM, -1); | 502 | SIGVTALRM, -1); |
503 | 503 | ||
504 | *fork_buf_ptr = &initial_jmpbuf; | 504 | *fork_buf_ptr = &initial_jmpbuf; |
505 | n = UML_SIGSETJMP(&initial_jmpbuf, enable); | 505 | n = UML_SETJMP(&initial_jmpbuf, enable); |
506 | switch(n){ | 506 | switch(n){ |
507 | case INIT_JMP_NEW_THREAD: | 507 | case INIT_JMP_NEW_THREAD: |
508 | new_thread_proc((void *) stack, new_thread_handler); | 508 | new_thread_proc((void *) stack, new_thread_handler); |
@@ -512,7 +512,7 @@ int start_idle_thread(void *stack, void *switch_buf_ptr, void **fork_buf_ptr) | |||
512 | break; | 512 | break; |
513 | case INIT_JMP_CALLBACK: | 513 | case INIT_JMP_CALLBACK: |
514 | (*cb_proc)(cb_arg); | 514 | (*cb_proc)(cb_arg); |
515 | UML_SIGLONGJMP(cb_back, 1); | 515 | UML_LONGJMP(cb_back, 1); |
516 | break; | 516 | break; |
517 | case INIT_JMP_HALT: | 517 | case INIT_JMP_HALT: |
518 | kmalloc_ok = 0; | 518 | kmalloc_ok = 0; |
@@ -523,12 +523,12 @@ int start_idle_thread(void *stack, void *switch_buf_ptr, void **fork_buf_ptr) | |||
523 | default: | 523 | default: |
524 | panic("Bad sigsetjmp return in start_idle_thread - %d\n", n); | 524 | panic("Bad sigsetjmp return in start_idle_thread - %d\n", n); |
525 | } | 525 | } |
526 | UML_SIGLONGJMP(*switch_buf, 1); | 526 | UML_LONGJMP(*switch_buf, 1); |
527 | } | 527 | } |
528 | 528 | ||
529 | void initial_thread_cb_skas(void (*proc)(void *), void *arg) | 529 | void initial_thread_cb_skas(void (*proc)(void *), void *arg) |
530 | { | 530 | { |
531 | sigjmp_buf here; | 531 | jmp_buf here; |
532 | int enable; | 532 | int enable; |
533 | 533 | ||
534 | cb_proc = proc; | 534 | cb_proc = proc; |
@@ -536,8 +536,8 @@ void initial_thread_cb_skas(void (*proc)(void *), void *arg) | |||
536 | cb_back = &here; | 536 | cb_back = &here; |
537 | 537 | ||
538 | block_signals(); | 538 | block_signals(); |
539 | if(UML_SIGSETJMP(&here, enable) == 0) | 539 | if(UML_SETJMP(&here, enable) == 0) |
540 | UML_SIGLONGJMP(&initial_jmpbuf, INIT_JMP_CALLBACK); | 540 | UML_LONGJMP(&initial_jmpbuf, INIT_JMP_CALLBACK); |
541 | unblock_signals(); | 541 | unblock_signals(); |
542 | 542 | ||
543 | cb_proc = NULL; | 543 | cb_proc = NULL; |
@@ -548,13 +548,13 @@ void initial_thread_cb_skas(void (*proc)(void *), void *arg) | |||
548 | void halt_skas(void) | 548 | void halt_skas(void) |
549 | { | 549 | { |
550 | block_signals(); | 550 | block_signals(); |
551 | UML_SIGLONGJMP(&initial_jmpbuf, INIT_JMP_HALT); | 551 | UML_LONGJMP(&initial_jmpbuf, INIT_JMP_HALT); |
552 | } | 552 | } |
553 | 553 | ||
554 | void reboot_skas(void) | 554 | void reboot_skas(void) |
555 | { | 555 | { |
556 | block_signals(); | 556 | block_signals(); |
557 | UML_SIGLONGJMP(&initial_jmpbuf, INIT_JMP_REBOOT); | 557 | UML_LONGJMP(&initial_jmpbuf, INIT_JMP_REBOOT); |
558 | } | 558 | } |
559 | 559 | ||
560 | void switch_mm_skas(struct mm_id *mm_idp) | 560 | void switch_mm_skas(struct mm_id *mm_idp) |
diff --git a/arch/um/os-Linux/start_up.c b/arch/um/os-Linux/start_up.c index 387e26af301a..503148504009 100644 --- a/arch/um/os-Linux/start_up.c +++ b/arch/um/os-Linux/start_up.c | |||
@@ -296,29 +296,7 @@ static void __init check_ptrace(void) | |||
296 | check_sysemu(); | 296 | check_sysemu(); |
297 | } | 297 | } |
298 | 298 | ||
299 | extern int create_tmp_file(unsigned long long len); | 299 | extern void check_tmpexec(void); |
300 | |||
301 | static void check_tmpexec(void) | ||
302 | { | ||
303 | void *addr; | ||
304 | int err, fd = create_tmp_file(UM_KERN_PAGE_SIZE); | ||
305 | |||
306 | addr = mmap(NULL, UM_KERN_PAGE_SIZE, | ||
307 | PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE, fd, 0); | ||
308 | printf("Checking PROT_EXEC mmap in /tmp..."); | ||
309 | fflush(stdout); | ||
310 | if(addr == MAP_FAILED){ | ||
311 | err = errno; | ||
312 | perror("failed"); | ||
313 | if(err == EPERM) | ||
314 | printf("/tmp must be not mounted noexec\n"); | ||
315 | exit(1); | ||
316 | } | ||
317 | printf("OK\n"); | ||
318 | munmap(addr, UM_KERN_PAGE_SIZE); | ||
319 | |||
320 | close(fd); | ||
321 | } | ||
322 | 300 | ||
323 | void os_early_checks(void) | 301 | void os_early_checks(void) |
324 | { | 302 | { |
diff --git a/arch/um/os-Linux/trap.c b/arch/um/os-Linux/trap.c index a9f6b26f9828..90b29ae9af46 100644 --- a/arch/um/os-Linux/trap.c +++ b/arch/um/os-Linux/trap.c | |||
@@ -35,7 +35,7 @@ void os_fill_handlinfo(struct kern_handlers h) | |||
35 | 35 | ||
36 | void do_longjmp(void *b, int val) | 36 | void do_longjmp(void *b, int val) |
37 | { | 37 | { |
38 | sigjmp_buf *buf = b; | 38 | jmp_buf *buf = b; |
39 | 39 | ||
40 | UML_SIGLONGJMP(buf, val); | 40 | UML_LONGJMP(buf, val); |
41 | } | 41 | } |
diff --git a/arch/um/os-Linux/uaccess.c b/arch/um/os-Linux/uaccess.c index 166fb66995df..e523719330b2 100644 --- a/arch/um/os-Linux/uaccess.c +++ b/arch/um/os-Linux/uaccess.c | |||
@@ -16,9 +16,9 @@ unsigned long __do_user_copy(void *to, const void *from, int n, | |||
16 | unsigned long *faddrp = (unsigned long *) fault_addr, ret; | 16 | unsigned long *faddrp = (unsigned long *) fault_addr, ret; |
17 | int enable; | 17 | int enable; |
18 | 18 | ||
19 | sigjmp_buf jbuf; | 19 | jmp_buf jbuf; |
20 | *fault_catcher = &jbuf; | 20 | *fault_catcher = &jbuf; |
21 | if(UML_SIGSETJMP(&jbuf, enable) == 0){ | 21 | if(UML_SETJMP(&jbuf, enable) == 0){ |
22 | (*op)(to, from, n); | 22 | (*op)(to, from, n); |
23 | ret = 0; | 23 | ret = 0; |
24 | *faulted_out = 0; | 24 | *faulted_out = 0; |
diff --git a/arch/um/os-Linux/util.c b/arch/um/os-Linux/util.c index e32065e2fdc8..c47a2a7ce70e 100644 --- a/arch/um/os-Linux/util.c +++ b/arch/um/os-Linux/util.c | |||
@@ -104,7 +104,7 @@ void setup_hostinfo(void) | |||
104 | int setjmp_wrapper(void (*proc)(void *, void *), ...) | 104 | int setjmp_wrapper(void (*proc)(void *, void *), ...) |
105 | { | 105 | { |
106 | va_list args; | 106 | va_list args; |
107 | sigjmp_buf buf; | 107 | jmp_buf buf; |
108 | int n; | 108 | int n; |
109 | 109 | ||
110 | n = sigsetjmp(buf, 1); | 110 | n = sigsetjmp(buf, 1); |