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 tag 'alpha-for-v7.1-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/lindholm/alpha

Pull alpha updates from Magnus Lindholm:
"One fix to silence pgprot_modify() compiler warnings, and one patch
adding SECCOMP/SECCOMP_FILTER support together with the syscall and
ptrace fixes needed for it"

* tag 'alpha-for-v7.1-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/lindholm/alpha:
alpha: Define pgprot_modify to silence tautological comparison warnings
alpha: add support for SECCOMP and SECCOMP_FILTER

+304 -24
+1 -1
Documentation/features/seccomp/seccomp-filter/arch-support.txt
··· 6 6 ----------------------- 7 7 | arch |status| 8 8 ----------------------- 9 - | alpha: | TODO | 9 + | alpha: | ok | 10 10 | arc: | TODO | 11 11 | arm: | ok | 12 12 | arm64: | ok |
+2
arch/alpha/Kconfig
··· 31 31 select GENERIC_SMP_IDLE_THREAD 32 32 select HAS_IOPORT 33 33 select HAVE_ARCH_AUDITSYSCALL 34 + select HAVE_ARCH_SECCOMP 35 + select HAVE_ARCH_SECCOMP_FILTER 34 36 select HAVE_MOD_ARCH_SPECIFIC 35 37 select LOCK_MM_AND_FIND_VMA 36 38 select MODULES_USE_ELF_RELA
+11
arch/alpha/include/asm/pgtable.h
··· 127 127 #define pgprot_noncached(prot) (prot) 128 128 129 129 /* 130 + * All caching attribute macros are identity on Alpha, so the generic 131 + * pgprot_modify() degenerates to tautological self-comparisons. 132 + * Override it to just return newprot directly. 133 + */ 134 + #define pgprot_modify pgprot_modify 135 + static inline pgprot_t pgprot_modify(pgprot_t oldprot, pgprot_t newprot) 136 + { 137 + return newprot; 138 + } 139 + 140 + /* 130 141 * On certain platforms whose physical address space can overlap KSEG, 131 142 * namely EV6 and above, we must re-twiddle the physaddr to restore the 132 143 * correct high-order bits.
+13
arch/alpha/include/asm/seccomp.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 + #ifndef _ASM_ALPHA_SECCOMP_H 3 + #define _ASM_ALPHA_SECCOMP_H 4 + 5 + #include <asm/unistd.h> 6 + #include <asm-generic/seccomp.h> 7 + #include <uapi/linux/audit.h> 8 + 9 + #define SECCOMP_ARCH_NATIVE AUDIT_ARCH_ALPHA 10 + #define SECCOMP_ARCH_NATIVE_NR NR_syscalls 11 + #define SECCOMP_ARCH_NATIVE_NAME "alpha" 12 + 13 + #endif /* _ASM_ALPHA_SECCOMP_H */
+89 -1
arch/alpha/include/asm/syscall.h
··· 3 3 #define _ASM_ALPHA_SYSCALL_H 4 4 5 5 #include <uapi/linux/audit.h> 6 + #include <linux/audit.h> 7 + #include <linux/sched.h> 8 + #include <linux/types.h> 9 + #include <asm/ptrace.h> 6 10 7 11 static inline int syscall_get_arch(struct task_struct *task) 8 12 { ··· 16 12 static inline long syscall_get_return_value(struct task_struct *task, 17 13 struct pt_regs *regs) 18 14 { 19 - return regs->r0; 15 + return regs->r19 ? -(long)regs->r0 : (long)regs->r0; 16 + } 17 + 18 + /* 19 + * Alpha syscall ABI / kernel conventions: 20 + * - PAL provides syscall number in r0 on entry. 21 + * - The kernel tracks the active syscall number in regs->r1 (mutable) and 22 + * preserves the original syscall number in regs->r2 for rollback/restart. 23 + * - Return value is in regs->r0, with regs->r19 ("a3") as the error flag 24 + * (0=success, 1=error; on error regs->r0 holds positive errno). 25 + */ 26 + 27 + static inline long syscall_get_nr(struct task_struct *task, 28 + struct pt_regs *regs) 29 + { 30 + return (long)regs->r1; 31 + } 32 + 33 + static inline void syscall_set_nr(struct task_struct *task, 34 + struct pt_regs *regs, 35 + long nr) 36 + { 37 + regs->r1 = (unsigned long)nr; 38 + } 39 + 40 + /* 41 + * Syscall arguments: 42 + * regs->r16..regs->r21 carry up to 6 syscall arguments on entry. 43 + * Note: regs->r19 is also used as "a3" (error flag) on syscall return. 44 + */ 45 + 46 + static inline void syscall_get_arguments(struct task_struct *task, 47 + struct pt_regs *regs, 48 + unsigned long *args) 49 + { 50 + args[0] = regs->r16; 51 + args[1] = regs->r17; 52 + args[2] = regs->r18; 53 + args[3] = regs->r19; 54 + args[4] = regs->r20; 55 + args[5] = regs->r21; 56 + } 57 + 58 + static inline void syscall_set_arguments(struct task_struct *task, 59 + struct pt_regs *regs, 60 + const unsigned long *args) 61 + { 62 + regs->r16 = args[0]; 63 + regs->r17 = args[1]; 64 + regs->r18 = args[2]; 65 + regs->r19 = args[3]; 66 + regs->r20 = args[4]; 67 + regs->r21 = args[5]; 68 + } 69 + /* 70 + * Set return value for a syscall. 71 + * Alpha uses r0 for return value and r19 ("a3") as the error indicator: 72 + * a3 = 0 => success 73 + * a3 = 1 => error, and userspace interprets r0 as errno (positive). 74 + * 75 + * The kernel reports errors to userspace by setting a3=1 and placing a 76 + * positive errno value in r0. Some syscall paths do this in entry.S, 77 + * while others (e.g. seccomp/ptrace helpers) use syscall_set_return_value(). 78 + */ 79 + 80 + static inline void syscall_set_return_value(struct task_struct *task, 81 + struct pt_regs *regs, 82 + int error, long val) 83 + { 84 + 85 + if (error) { 86 + /* error is negative errno in this tree */ 87 + regs->r0 = (unsigned long)(-error); /* positive errno */ 88 + regs->r19 = 1; /* a3 = error */ 89 + } else { 90 + regs->r0 = (unsigned long)val; 91 + regs->r19 = 0; /* a3 = success */ 92 + } 93 + } 94 + 95 + /* Restore the original syscall nr after seccomp/ptrace modified regs->r1. */ 96 + static inline void syscall_rollback(struct task_struct *task, 97 + struct pt_regs *regs) 98 + { 99 + regs->r1 = regs->r2; 20 100 } 21 101 22 102 #endif /* _ASM_ALPHA_SYSCALL_H */
+15 -1
arch/alpha/include/asm/thread_info.h
··· 56 56 * - pending work-to-be-done flags come first and must be assigned to be 57 57 * within bits 0 to 7 to fit in and immediate operand. 58 58 * 59 - * TIF_SYSCALL_TRACE is known to be 0 via blbs. 59 + * (Historically TIF_SYSCALL_TRACE was known to be 0 via blbs, but we may 60 + * also test multiple bits via masks now.) 60 61 */ 61 62 #define TIF_SYSCALL_TRACE 0 /* syscall trace active */ 62 63 #define TIF_NOTIFY_RESUME 1 /* callback before returning to user */ ··· 65 64 #define TIF_NEED_RESCHED 3 /* rescheduling necessary */ 66 65 #define TIF_SYSCALL_AUDIT 4 /* syscall audit active */ 67 66 #define TIF_NOTIFY_SIGNAL 5 /* signal notifications exist */ 67 + #define TIF_SECCOMP 6 /* seccomp syscall filtering active */ 68 68 #define TIF_DIE_IF_KERNEL 9 /* dik recursion lock */ 69 69 #define TIF_MEMDIE 13 /* is terminating due to OOM killer */ 70 70 #define TIF_POLLING_NRFLAG 14 /* idle is polling for TIF_NEED_RESCHED */ ··· 76 74 #define _TIF_NOTIFY_RESUME (1<<TIF_NOTIFY_RESUME) 77 75 #define _TIF_SYSCALL_AUDIT (1<<TIF_SYSCALL_AUDIT) 78 76 #define _TIF_NOTIFY_SIGNAL (1<<TIF_NOTIFY_SIGNAL) 77 + #define _TIF_SECCOMP (1<<TIF_SECCOMP) 79 78 #define _TIF_POLLING_NRFLAG (1<<TIF_POLLING_NRFLAG) 79 + 80 + /* 81 + * Work to do on syscall entry (in entry.S). 82 + * If you want this to exactly mirror what entry.S checks, keep it aligned 83 + * with the mask used before branching to syscall_trace_enter(). 84 + */ 85 + #ifdef CONFIG_AUDITSYSCALL 86 + # define _TIF_SYSCALL_WORK (_TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT | _TIF_SECCOMP) 87 + #else 88 + # define _TIF_SYSCALL_WORK (_TIF_SYSCALL_TRACE | _TIF_SECCOMP) 89 + #endif 80 90 81 91 /* Work to do on interrupt/exception return. */ 82 92 #define _TIF_WORK_MASK (_TIF_SIGPENDING | _TIF_NEED_RESCHED | \
+95 -16
arch/alpha/kernel/entry.S
··· 10 10 #include <asm/pal.h> 11 11 #include <asm/errno.h> 12 12 #include <asm/unistd.h> 13 + #include <linux/errno.h> 13 14 14 15 .text 15 16 .set noat ··· 35 34 .cfi_endproc 36 35 .size \func, . - \func 37 36 .endm 37 + 38 + /* 39 + * SYSCALL_SKIP_RETURN_RESTART_GATE 40 + * 41 + * Used when syscall dispatch is skipped (seccomp/ptrace injected nr=-1). 42 + * - Ensure we never return r0==-1 with a3==0 (success); convert to ENOSYS. 43 + * - Gate whether syscall restart is allowed by preserving restart context 44 + * only for ERESTART* returns. Result: 45 + * $26 = 0 => restart allowed 46 + * $26 = 1 => restart NOT allowed 47 + * $18 = preserved syscall nr (regs->r2) if restart allowed, else 0 48 + */ 49 + .macro SYSCALL_SKIP_RETURN_RESTART_GATE 50 + /* Fix up invalid "-1 success" return state. */ 51 + ldq $19, 72($sp) /* a3 */ 52 + bne $19, 1f /* already error => skip fixup */ 53 + 54 + ldq $20, 0($sp) /* r0 */ 55 + lda $21, -1($31) 56 + cmpeq $20, $21, $22 57 + beq $22, 1f /* r0 != -1 => skip fixup */ 58 + 59 + 60 + lda $20, ENOSYS($31) 61 + stq $20, 0($sp) /* r0 = ENOSYS */ 62 + lda $19, 1($31) 63 + stq $19, 72($sp) /* a3 = 1 */ 64 + 1: 65 + /* Restart gating: success is never restartable here. */ 66 + ldq $19, 72($sp) /* a3 */ 67 + beq $19, 3f /* success => not restartable */ 68 + 69 + ldq $20, 0($sp) /* r0 (positive errno if a3==1) */ 70 + lda $21, ERESTARTSYS($31) 71 + cmpeq $20, $21, $22 72 + bne $22, 2f 73 + lda $21, ERESTARTNOINTR($31) 74 + cmpeq $20, $21, $22 75 + bne $22, 2f 76 + lda $21, ERESTARTNOHAND($31) 77 + cmpeq $20, $21, $22 78 + bne $22, 2f 79 + lda $21, ERESTART_RESTARTBLOCK($31) 80 + cmpeq $20, $21, $22 81 + bne $22, 2f 82 + 83 + 3: /* Not a restart code (or success) => restart NOT allowed. */ 84 + addq $31, 1, $26 /* $26=1 => restart NOT allowed */ 85 + mov 0, $18 86 + br 4f 87 + 88 + 2: /* Restart allowed. */ 89 + ldq $18, 16($sp) /* preserved syscall nr (regs->r2) */ 90 + mov $31, $26 /* $26=0 => restart allowed */ 91 + br 4f 92 + 4: 93 + .endm 94 + 38 95 39 96 /* 40 97 * This defines the normal kernel pt-regs layout. ··· 484 425 mov $sp, $16 485 426 jsr $31, do_entDbg 486 427 CFI_END_OSF_FRAME entDbg 487 - 428 + 488 429 /* 489 430 * The system call entry point is special. Most importantly, it looks 490 431 * like a function call to userspace as far as clobbered registers. We ··· 494 435 * So much for theory. We don't take advantage of this yet. 495 436 * 496 437 * Note that a0-a2 are not saved by PALcode as with the other entry points. 438 + * 439 + * Alpha syscall ABI uses: 440 + * - r0 for return value 441 + * - r19 ("a3") as error indicator (0=success, 1=error; r0 holds errno) 442 + * 443 + * For seccomp/ptrace/generic syscall helpers we track the syscall 444 + * number separately: 445 + * - regs->r1: current (mutable) syscall number (may be changed or set to -1) 446 + * - regs->r2: original syscall number for restart/rollback 447 + * 448 + * On entry PAL provides the syscall number in r0; copy it into r1/r2. 497 449 */ 498 450 499 451 .align 4 ··· 517 447 .cfi_rel_offset $gp, 16 518 448 entSys: 519 449 SAVE_ALL 450 + ldq $1, 0($sp) /* syscall nr from saved r0 */ 451 + stq $1, 8($sp) /* regs->r1 = shadow syscall nr */ 452 + stq $1, 16($sp) /* regs->r2 = restart syscall nr */ 453 + 520 454 lda $8, 0x3fff 521 455 bic $sp, $8, $8 522 456 lda $4, NR_syscalls($31) ··· 536 462 .cfi_rel_offset $17, SP_OFF+32 537 463 .cfi_rel_offset $18, SP_OFF+40 538 464 #ifdef CONFIG_AUDITSYSCALL 539 - lda $6, _TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT 465 + lda $6, _TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT | _TIF_SECCOMP 540 466 and $3, $6, $3 541 467 bne $3, strace 542 468 #else 543 - blbs $3, strace /* check for SYSCALL_TRACE in disguise */ 469 + lda $6, _TIF_SYSCALL_TRACE | _TIF_SECCOMP 470 + and $3, $6, $3 471 + bne $3, strace 544 472 #endif 545 473 beq $4, 1f 546 474 ldq $27, 0($5) 547 - 1: jsr $26, ($27), sys_ni_syscall 475 + 1: ldq $0, 8($sp) /* syscall nr shadow (regs->r1) */ 476 + 477 + jsr $26, ($27), sys_ni_syscall 548 478 ldgp $gp, 0($26) 549 479 blt $0, $syscall_error /* the call failed */ 550 480 $ret_success: ··· 587 509 588 510 .align 3 589 511 $syscall_error: 590 - /* 591 - * Some system calls (e.g., ptrace) can return arbitrary 592 - * values which might normally be mistaken as error numbers. 593 - * Those functions must zero $0 (v0) directly in the stack 594 - * frame to indicate that a negative return value wasn't an 595 - * error number.. 596 - */ 597 - ldq $18, 0($sp) /* old syscall nr (zero if success) */ 598 - beq $18, $ret_success 512 + /* Restart syscall nr comes from saved r2 (preserved even if r0 overwritten). */ 513 + ldq $18, 16($sp) /* old syscall nr for restart */ 599 514 600 515 ldq $19, 72($sp) /* .. and this a3 */ 601 516 subq $31, $0, $0 /* with error in v0 */ ··· 652 581 jsr $26, syscall_trace_enter /* returns the syscall number */ 653 582 UNDO_SWITCH_STACK 654 583 584 + stq $0, 8($sp) /* regs->r1 = shadow syscall nr */ 585 + 655 586 /* get the arguments back.. */ 656 587 ldq $16, SP_OFF+24($sp) 657 588 ldq $17, SP_OFF+32($sp) ··· 661 588 ldq $19, 72($sp) 662 589 ldq $20, 80($sp) 663 590 ldq $21, 88($sp) 591 + 592 + /* nr == -1: internal skip-dispatch or userspace syscall(-1)? */ 593 + lda $6, -1($31) 594 + cmpeq $0, $6, $6 595 + bne $6, $strace_skip_call /* nr == -1 => dispatch */ 664 596 665 597 /* get the system call pointer.. */ 666 598 lda $1, NR_syscalls($31) ··· 685 607 stq $31, 72($sp) /* a3=0 => no error */ 686 608 stq $0, 0($sp) /* save return value */ 687 609 610 + $strace_skip_call: 611 + SYSCALL_SKIP_RETURN_RESTART_GATE 688 612 DO_SWITCH_STACK 689 613 jsr $26, syscall_trace_leave 690 614 UNDO_SWITCH_STACK ··· 694 614 695 615 .align 3 696 616 $strace_error: 697 - ldq $18, 0($sp) /* old syscall nr (zero if success) */ 698 - beq $18, $strace_success 617 + ldq $18, 16($sp) /* restart syscall nr */ 699 618 ldq $19, 72($sp) /* .. and this a3 */ 700 619 701 620 subq $31, $0, $0 /* with error in v0 */ ··· 713 634 mov $31, $26 /* tell "ret_from_sys_call" we can restart */ 714 635 br ret_from_sys_call 715 636 CFI_END_OSF_FRAME entSys 716 - 637 + 717 638 /* 718 639 * Save and restore the switch stack -- aka the balance of the user context. 719 640 */
+78 -5
arch/alpha/kernel/ptrace.c
··· 16 16 #include <linux/security.h> 17 17 #include <linux/signal.h> 18 18 #include <linux/audit.h> 19 + #include <linux/seccomp.h> 20 + #include <asm/syscall.h> 19 21 20 22 #include <linux/uaccess.h> 21 23 #include <asm/fpu.h> 22 24 23 25 #include "proto.h" 26 + #include <linux/uio.h> 24 27 25 28 #define DEBUG DBG_MEM 26 29 #undef DEBUG ··· 315 312 DBG(DBG_MEM, ("poke $%lu<-%#lx\n", addr, data)); 316 313 ret = put_reg(child, addr, data); 317 314 break; 315 + case PTRACE_GETREGSET: 316 + case PTRACE_SETREGSET: { 317 + struct iovec __user *uiov = (struct iovec __user *)data; 318 + struct iovec iov; 319 + struct pt_regs *regs; 320 + size_t len; 321 + 322 + /* Only support NT_PRSTATUS (general registers) for now. */ 323 + if (addr != NT_PRSTATUS) { 324 + ret = -EIO; 325 + break; 326 + } 327 + 328 + if (copy_from_user(&iov, uiov, sizeof(iov))) { 329 + ret = -EFAULT; 330 + break; 331 + } 332 + 333 + regs = task_pt_regs(child); 334 + len = min_t(size_t, iov.iov_len, sizeof(*regs)); 335 + 336 + if (request == PTRACE_GETREGSET) { 337 + if (copy_to_user(iov.iov_base, regs, len)) { 338 + ret = -EFAULT; 339 + break; 340 + } 341 + } else { 342 + /* 343 + * Allow writing back regs. This is needed by the TRACE_syscall 344 + * tests (they change PC/syscall nr/retval). 345 + */ 346 + if (copy_from_user(regs, iov.iov_base, len)) { 347 + ret = -EFAULT; 348 + break; 349 + } 350 + } 351 + 352 + /* Per API, update iov_len with amount transferred. */ 353 + iov.iov_len = len; 354 + if (copy_to_user(uiov, &iov, sizeof(iov))) { 355 + ret = -EFAULT; 356 + break; 357 + } 358 + 359 + ret = 0; 360 + break; 361 + } 362 + 318 363 default: 319 364 ret = ptrace_request(child, request, addr, data); 320 365 break; ··· 372 321 373 322 asmlinkage unsigned long syscall_trace_enter(void) 374 323 { 375 - unsigned long ret = 0; 376 324 struct pt_regs *regs = current_pt_regs(); 325 + 377 326 if (test_thread_flag(TIF_SYSCALL_TRACE) && 378 - ptrace_report_syscall_entry(current_pt_regs())) 379 - ret = -1UL; 380 - audit_syscall_entry(regs->r0, regs->r16, regs->r17, regs->r18, regs->r19); 381 - return ret ?: current_pt_regs()->r0; 327 + ptrace_report_syscall_entry(regs)) { 328 + syscall_set_nr(current, regs, -1); 329 + if (regs->r19 == 0 && regs->r0 == (unsigned long)-1) 330 + syscall_set_return_value(current, regs, -ENOSYS, 0); 331 + return -1UL; 332 + } 333 + 334 + /* 335 + * Do the secure computing after ptrace; failures should be fast. 336 + * If this fails, seccomp may already have set up the return value 337 + * (e.g. SECCOMP_RET_ERRNO / TRACE). 338 + */ 339 + if (secure_computing() == -1) { 340 + if (regs->r19 == 0 && regs->r0 == (unsigned long)-1) 341 + syscall_set_return_value(current, regs, -ENOSYS, 0); 342 + syscall_set_nr(current, regs, -1); 343 + return -1UL; 344 + } 345 + 346 + #ifdef CONFIG_AUDITSYSCALL 347 + audit_syscall_entry(syscall_get_nr(current, regs), 348 + regs->r16, regs->r17, regs->r18, regs->r19); 349 + #endif 350 + return syscall_get_nr(current, regs); 382 351 } 352 + 353 + 383 354 384 355 asmlinkage void 385 356 syscall_trace_leave(void)