Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/rw/uml

Pull UML fixes from Richard Weinberger:
"Special thanks goes to Toralf Föster for continuously testing UML and
reporting issues!"

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/rw/uml:
um: remove dead code
um: siginfo cleanup
uml: Fix which_tmpdir failure when /dev/shm is a symlink, and in other edge cases
um: Fix wait_stub_done() error handling
um: Mark stub pages mapping with VM_PFNMAP
um: Fix return value of strnlen_user()

+213 -61
+4 -4
arch/um/include/shared/frame_kern.h
··· 6 6 #ifndef __FRAME_KERN_H_ 7 7 #define __FRAME_KERN_H_ 8 8 9 - extern int setup_signal_stack_sc(unsigned long stack_top, int sig, 9 + extern int setup_signal_stack_sc(unsigned long stack_top, int sig, 10 10 struct k_sigaction *ka, 11 - struct pt_regs *regs, 11 + struct pt_regs *regs, 12 12 sigset_t *mask); 13 - extern int setup_signal_stack_si(unsigned long stack_top, int sig, 13 + extern int setup_signal_stack_si(unsigned long stack_top, int sig, 14 14 struct k_sigaction *ka, 15 - struct pt_regs *regs, siginfo_t *info, 15 + struct pt_regs *regs, struct siginfo *info, 16 16 sigset_t *mask); 17 17 18 18 #endif
+2 -2
arch/um/kernel/signal.c
··· 19 19 * OK, we're invoking a handler 20 20 */ 21 21 static void handle_signal(struct pt_regs *regs, unsigned long signr, 22 - struct k_sigaction *ka, siginfo_t *info) 22 + struct k_sigaction *ka, struct siginfo *info) 23 23 { 24 24 sigset_t *oldset = sigmask_to_save(); 25 25 int singlestep = 0; ··· 71 71 static int kern_do_signal(struct pt_regs *regs) 72 72 { 73 73 struct k_sigaction ka_copy; 74 - siginfo_t info; 74 + struct siginfo info; 75 75 int sig, handled_sig = 0; 76 76 77 77 while ((sig = get_signal_to_deliver(&info, &ka_copy, regs, NULL)) > 0) {
+1 -1
arch/um/kernel/skas/mmu.c
··· 123 123 /* dup_mmap already holds mmap_sem */ 124 124 err = install_special_mapping(mm, STUB_START, STUB_END - STUB_START, 125 125 VM_READ | VM_MAYREAD | VM_EXEC | 126 - VM_MAYEXEC | VM_DONTCOPY, 126 + VM_MAYEXEC | VM_DONTCOPY | VM_PFNMAP, 127 127 mm->context.stub_pages); 128 128 if (err) { 129 129 printk(KERN_ERR "install_special_mapping returned %d\n", err);
+1 -1
arch/um/kernel/skas/uaccess.c
··· 254 254 n = buffer_op((unsigned long) str, len, 0, strnlen_chunk, &count); 255 255 if (n == 0) 256 256 return count + 1; 257 - return -EFAULT; 257 + return 0; 258 258 } 259 259 EXPORT_SYMBOL(strnlen_user);
+189 -41
arch/um/os-Linux/mem.c
··· 53 53 } 54 54 55 55 /* 56 + * Remove bytes from the front of the buffer and refill it so that if there's a 57 + * partial string that we care about, it will be completed, and we can recognize 58 + * it. 59 + */ 60 + static int pop(int fd, char *buf, size_t size, size_t npop) 61 + { 62 + ssize_t n; 63 + size_t len = strlen(&buf[npop]); 64 + 65 + memmove(buf, &buf[npop], len + 1); 66 + n = read(fd, &buf[len], size - len - 1); 67 + if (n < 0) 68 + return -errno; 69 + 70 + buf[len + n] = '\0'; 71 + return 1; 72 + } 73 + 74 + /* 56 75 * This will return 1, with the first character in buf being the 57 76 * character following the next instance of c in the file. This will 58 77 * read the file as needed. If there's an error, -errno is returned; ··· 80 61 static int next(int fd, char *buf, size_t size, char c) 81 62 { 82 63 ssize_t n; 83 - size_t len; 84 64 char *ptr; 85 65 86 66 while ((ptr = strchr(buf, c)) == NULL) { ··· 92 74 buf[n] = '\0'; 93 75 } 94 76 95 - ptr++; 96 - len = strlen(ptr); 97 - memmove(buf, ptr, len + 1); 77 + return pop(fd, buf, size, ptr - buf + 1); 78 + } 79 + 80 + /* 81 + * Decode an octal-escaped and space-terminated path of the form used by 82 + * /proc/mounts. May be used to decode a path in-place. "out" must be at least 83 + * as large as the input. The output is always null-terminated. "len" gets the 84 + * length of the output, excluding the trailing null. Returns 0 if a full path 85 + * was successfully decoded, otherwise an error. 86 + */ 87 + static int decode_path(const char *in, char *out, size_t *len) 88 + { 89 + char *first = out; 90 + int c; 91 + int i; 92 + int ret = -EINVAL; 93 + while (1) { 94 + switch (*in) { 95 + case '\0': 96 + goto out; 97 + 98 + case ' ': 99 + ret = 0; 100 + goto out; 101 + 102 + case '\\': 103 + in++; 104 + c = 0; 105 + for (i = 0; i < 3; i++) { 106 + if (*in < '0' || *in > '7') 107 + goto out; 108 + c = (c << 3) | (*in++ - '0'); 109 + } 110 + *(unsigned char *)out++ = (unsigned char) c; 111 + break; 112 + 113 + default: 114 + *out++ = *in++; 115 + break; 116 + } 117 + } 118 + 119 + out: 120 + *out = '\0'; 121 + *len = out - first; 122 + return ret; 123 + } 124 + 125 + /* 126 + * Computes the length of s when encoded with three-digit octal escape sequences 127 + * for the characters in chars. 128 + */ 129 + static size_t octal_encoded_length(const char *s, const char *chars) 130 + { 131 + size_t len = strlen(s); 132 + while ((s = strpbrk(s, chars)) != NULL) { 133 + len += 3; 134 + s++; 135 + } 136 + 137 + return len; 138 + } 139 + 140 + enum { 141 + OUTCOME_NOTHING_MOUNTED, 142 + OUTCOME_TMPFS_MOUNT, 143 + OUTCOME_NON_TMPFS_MOUNT, 144 + }; 145 + 146 + /* Read a line of /proc/mounts data looking for a tmpfs mount at "path". */ 147 + static int read_mount(int fd, char *buf, size_t bufsize, const char *path, 148 + int *outcome) 149 + { 150 + int found; 151 + int match; 152 + char *space; 153 + size_t len; 154 + 155 + enum { 156 + MATCH_NONE, 157 + MATCH_EXACT, 158 + MATCH_PARENT, 159 + }; 160 + 161 + found = next(fd, buf, bufsize, ' '); 162 + if (found != 1) 163 + return found; 98 164 99 165 /* 100 - * Refill the buffer so that if there's a partial string that we care 101 - * about, it will be completed, and we can recognize it. 166 + * If there's no following space in the buffer, then this path is 167 + * truncated, so it can't be the one we're looking for. 102 168 */ 103 - n = read(fd, &buf[len], size - len - 1); 104 - if (n < 0) 105 - return -errno; 169 + space = strchr(buf, ' '); 170 + if (space) { 171 + match = MATCH_NONE; 172 + if (!decode_path(buf, buf, &len)) { 173 + if (!strcmp(buf, path)) 174 + match = MATCH_EXACT; 175 + else if (!strncmp(buf, path, len) 176 + && (path[len] == '/' || !strcmp(buf, "/"))) 177 + match = MATCH_PARENT; 178 + } 106 179 107 - buf[len + n] = '\0'; 108 - return 1; 180 + found = pop(fd, buf, bufsize, space - buf + 1); 181 + if (found != 1) 182 + return found; 183 + 184 + switch (match) { 185 + case MATCH_EXACT: 186 + if (!strncmp(buf, "tmpfs", strlen("tmpfs"))) 187 + *outcome = OUTCOME_TMPFS_MOUNT; 188 + else 189 + *outcome = OUTCOME_NON_TMPFS_MOUNT; 190 + break; 191 + 192 + case MATCH_PARENT: 193 + /* This mount obscures any previous ones. */ 194 + *outcome = OUTCOME_NOTHING_MOUNTED; 195 + break; 196 + } 197 + } 198 + 199 + return next(fd, buf, bufsize, '\n'); 109 200 } 110 201 111 202 /* which_tmpdir is called only during early boot */ ··· 233 106 */ 234 107 static void which_tmpdir(void) 235 108 { 236 - int fd, found; 237 - char buf[128] = { '\0' }; 109 + int fd; 110 + int found; 111 + int outcome; 112 + char *path; 113 + char *buf; 114 + size_t bufsize; 238 115 239 116 if (checked_tmpdir) 240 117 return; ··· 247 116 248 117 printf("Checking for tmpfs mount on /dev/shm..."); 249 118 119 + path = realpath("/dev/shm", NULL); 120 + if (!path) { 121 + printf("failed to check real path, errno = %d\n", errno); 122 + return; 123 + } 124 + printf("%s...", path); 125 + 126 + /* 127 + * The buffer needs to be able to fit the full octal-escaped path, a 128 + * space, and a trailing null in order to successfully decode it. 129 + */ 130 + bufsize = octal_encoded_length(path, " \t\n\\") + 2; 131 + 132 + if (bufsize < 128) 133 + bufsize = 128; 134 + 135 + buf = malloc(bufsize); 136 + if (!buf) { 137 + printf("malloc failed, errno = %d\n", errno); 138 + goto out; 139 + } 140 + buf[0] = '\0'; 141 + 250 142 fd = open("/proc/mounts", O_RDONLY); 251 143 if (fd < 0) { 252 144 printf("failed to open /proc/mounts, errno = %d\n", errno); 253 - return; 145 + goto out1; 254 146 } 255 147 148 + outcome = OUTCOME_NOTHING_MOUNTED; 256 149 while (1) { 257 - found = next(fd, buf, ARRAY_SIZE(buf), ' '); 258 - if (found != 1) 259 - break; 260 - 261 - if (!strncmp(buf, "/dev/shm", strlen("/dev/shm"))) 262 - goto found; 263 - 264 - found = next(fd, buf, ARRAY_SIZE(buf), '\n'); 150 + found = read_mount(fd, buf, bufsize, path, &outcome); 265 151 if (found != 1) 266 152 break; 267 153 } 268 154 269 - err: 270 - if (found == 0) 271 - printf("nothing mounted on /dev/shm\n"); 272 - else if (found < 0) 155 + if (found < 0) { 273 156 printf("read returned errno %d\n", -found); 157 + } else { 158 + switch (outcome) { 159 + case OUTCOME_TMPFS_MOUNT: 160 + printf("OK\n"); 161 + default_tmpdir = "/dev/shm"; 162 + break; 274 163 275 - out: 276 - close(fd); 164 + case OUTCOME_NON_TMPFS_MOUNT: 165 + printf("not tmpfs\n"); 166 + break; 277 167 278 - return; 279 - 280 - found: 281 - found = next(fd, buf, ARRAY_SIZE(buf), ' '); 282 - if (found != 1) 283 - goto err; 284 - 285 - if (strncmp(buf, "tmpfs", strlen("tmpfs"))) { 286 - printf("not tmpfs\n"); 287 - goto out; 168 + default: 169 + printf("nothing mounted on /dev/shm\n"); 170 + break; 171 + } 288 172 } 289 173 290 - printf("OK\n"); 291 - default_tmpdir = "/dev/shm"; 292 - goto out; 174 + close(fd); 175 + out1: 176 + free(buf); 177 + out: 178 + free(path); 293 179 } 294 180 295 181 static int __init make_tempfile(const char *template, char **out_tempname,
+4 -4
arch/um/os-Linux/signal.c
··· 25 25 [SIGIO] = sigio_handler, 26 26 [SIGVTALRM] = timer_handler }; 27 27 28 - static void sig_handler_common(int sig, siginfo_t *si, mcontext_t *mc) 28 + static void sig_handler_common(int sig, struct siginfo *si, mcontext_t *mc) 29 29 { 30 30 struct uml_pt_regs r; 31 31 int save_errno = errno; ··· 61 61 static int signals_enabled; 62 62 static unsigned int signals_pending; 63 63 64 - void sig_handler(int sig, siginfo_t *si, mcontext_t *mc) 64 + void sig_handler(int sig, struct siginfo *si, mcontext_t *mc) 65 65 { 66 66 int enabled; 67 67 ··· 120 120 panic("enabling signal stack failed, errno = %d\n", errno); 121 121 } 122 122 123 - static void (*handlers[_NSIG])(int sig, siginfo_t *si, mcontext_t *mc) = { 123 + static void (*handlers[_NSIG])(int sig, struct siginfo *si, mcontext_t *mc) = { 124 124 [SIGSEGV] = sig_handler, 125 125 [SIGBUS] = sig_handler, 126 126 [SIGILL] = sig_handler, ··· 162 162 while ((sig = ffs(pending)) != 0){ 163 163 sig--; 164 164 pending &= ~(1 << sig); 165 - (*handlers[sig])(sig, si, mc); 165 + (*handlers[sig])(sig, (struct siginfo *)si, mc); 166 166 } 167 167 168 168 /*
+12 -7
arch/um/os-Linux/skas/process.c
··· 54 54 55 55 void wait_stub_done(int pid) 56 56 { 57 - int n, status, err; 57 + int n, status, err, bad_stop = 0; 58 58 59 59 while (1) { 60 60 CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED | __WALL)); ··· 74 74 75 75 if (((1 << WSTOPSIG(status)) & STUB_DONE_MASK) != 0) 76 76 return; 77 + else 78 + bad_stop = 1; 77 79 78 80 bad_wait: 79 81 err = ptrace_dump_regs(pid); ··· 85 83 printk(UM_KERN_ERR "wait_stub_done : failed to wait for SIGTRAP, " 86 84 "pid = %d, n = %d, errno = %d, status = 0x%x\n", pid, n, errno, 87 85 status); 88 - fatal_sigsegv(); 86 + if (bad_stop) 87 + kill(pid, SIGKILL); 88 + else 89 + fatal_sigsegv(); 89 90 } 90 91 91 92 extern unsigned long current_stub_stack(void); ··· 414 409 if (WIFSTOPPED(status)) { 415 410 int sig = WSTOPSIG(status); 416 411 417 - ptrace(PTRACE_GETSIGINFO, pid, 0, &si); 412 + ptrace(PTRACE_GETSIGINFO, pid, 0, (struct siginfo *)&si); 418 413 419 414 switch (sig) { 420 415 case SIGSEGV: ··· 422 417 !ptrace_faultinfo) { 423 418 get_skas_faultinfo(pid, 424 419 &regs->faultinfo); 425 - (*sig_info[SIGSEGV])(SIGSEGV, &si, 420 + (*sig_info[SIGSEGV])(SIGSEGV, (struct siginfo *)&si, 426 421 regs); 427 422 } 428 423 else handle_segv(pid, regs); ··· 431 426 handle_trap(pid, regs, local_using_sysemu); 432 427 break; 433 428 case SIGTRAP: 434 - relay_signal(SIGTRAP, &si, regs); 429 + relay_signal(SIGTRAP, (struct siginfo *)&si, regs); 435 430 break; 436 431 case SIGVTALRM: 437 432 now = os_nsecs(); 438 433 if (now < nsecs) 439 434 break; 440 435 block_signals(); 441 - (*sig_info[sig])(sig, &si, regs); 436 + (*sig_info[sig])(sig, (struct siginfo *)&si, regs); 442 437 unblock_signals(); 443 438 nsecs = timer.it_value.tv_sec * 444 439 UM_NSEC_PER_SEC + ··· 452 447 case SIGFPE: 453 448 case SIGWINCH: 454 449 block_signals(); 455 - (*sig_info[sig])(sig, &si, regs); 450 + (*sig_info[sig])(sig, (struct siginfo *)&si, regs); 456 451 unblock_signals(); 457 452 break; 458 453 default:
-1
arch/x86/um/signal.c
··· 508 508 { 509 509 struct rt_sigframe __user *frame; 510 510 int err = 0; 511 - struct task_struct *me = current; 512 511 513 512 frame = (struct rt_sigframe __user *) 514 513 round_down(stack_top - sizeof(struct rt_sigframe), 16);