Date: Mon, 27 Apr 2020 04:47:02 +0000 (UTC) From: John Baldwin <jhb@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-12@freebsd.org Subject: svn commit: r360363 - in stable/12/sys: compat/linux kern Message-ID: <202004270447.03R4l2nB060579@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: jhb Date: Mon Apr 27 04:47:02 2020 New Revision: 360363 URL: https://svnweb.freebsd.org/changeset/base/360363 Log: MFC 350012: Always set td_errno to the error value of a system call. Early errors prior to a system call did not set td_errno. This commit sets td_errno for all errors during syscallenter(). As a result, syscallret() can now always use td_errno without checking TDP_NERRNO. Compared to the original commit, this change preserves the ABI of struct thread and instead adds explicit zero'ing of td_errno. Modified: stable/12/sys/compat/linux/linux_fork.c stable/12/sys/kern/kern_fork.c stable/12/sys/kern/kern_kthread.c stable/12/sys/kern/kern_thr.c stable/12/sys/kern/subr_syscall.c Directory Properties: stable/12/ (props changed) Modified: stable/12/sys/compat/linux/linux_fork.c ============================================================================== --- stable/12/sys/compat/linux/linux_fork.c Mon Apr 27 03:57:17 2020 (r360362) +++ stable/12/sys/compat/linux/linux_fork.c Mon Apr 27 04:47:02 2020 (r360363) @@ -310,6 +310,7 @@ linux_clone_thread(struct thread *td, struct linux_clo bzero(&newtd->td_startzero, __rangeof(struct thread, td_startzero, td_endzero)); newtd->td_pflags2 = 0; + newtd->td_errno = 0; bcopy(&td->td_startcopy, &newtd->td_startcopy, __rangeof(struct thread, td_startcopy, td_endcopy)); Modified: stable/12/sys/kern/kern_fork.c ============================================================================== --- stable/12/sys/kern/kern_fork.c Mon Apr 27 03:57:17 2020 (r360362) +++ stable/12/sys/kern/kern_fork.c Mon Apr 27 04:47:02 2020 (r360363) @@ -490,6 +490,7 @@ do_fork(struct thread *td, struct fork_req *fr, struct bzero(&td2->td_startzero, __rangeof(struct thread, td_startzero, td_endzero)); td2->td_pflags2 = 0; + td2->td_errno = 0; bcopy(&td->td_startcopy, &td2->td_startcopy, __rangeof(struct thread, td_startcopy, td_endcopy)); Modified: stable/12/sys/kern/kern_kthread.c ============================================================================== --- stable/12/sys/kern/kern_kthread.c Mon Apr 27 03:57:17 2020 (r360362) +++ stable/12/sys/kern/kern_kthread.c Mon Apr 27 04:47:02 2020 (r360363) @@ -284,6 +284,7 @@ kthread_add(void (*func)(void *), void *arg, struct pr bzero(&newtd->td_startzero, __rangeof(struct thread, td_startzero, td_endzero)); newtd->td_pflags2 = 0; + newtd->td_errno = 0; bcopy(&oldtd->td_startcopy, &newtd->td_startcopy, __rangeof(struct thread, td_startcopy, td_endcopy)); Modified: stable/12/sys/kern/kern_thr.c ============================================================================== --- stable/12/sys/kern/kern_thr.c Mon Apr 27 03:57:17 2020 (r360362) +++ stable/12/sys/kern/kern_thr.c Mon Apr 27 04:47:02 2020 (r360363) @@ -236,6 +236,7 @@ thread_create(struct thread *td, struct rtprio *rtp, bzero(&newtd->td_startzero, __rangeof(struct thread, td_startzero, td_endzero)); newtd->td_pflags2 = 0; + newtd->td_errno = 0; bcopy(&td->td_startcopy, &newtd->td_startcopy, __rangeof(struct thread, td_startcopy, td_endcopy)); newtd->td_proc = td->td_proc; Modified: stable/12/sys/kern/subr_syscall.c ============================================================================== --- stable/12/sys/kern/subr_syscall.c Mon Apr 27 03:57:17 2020 (r360362) +++ stable/12/sys/kern/subr_syscall.c Mon Apr 27 04:47:02 2020 (r360363) @@ -85,8 +85,10 @@ syscallenter(struct thread *td) (uintptr_t)td, "pid:%d", td->td_proc->p_pid, "arg0:%p", sa->args[0], "arg1:%p", sa->args[1], "arg2:%p", sa->args[2]); - if (error != 0) + if (error != 0) { + td->td_errno = error; goto retval; + } STOPEVENT(p, S_SCE, sa->narg); if ((p->p_flag & P_TRACED) != 0) { @@ -105,8 +107,10 @@ syscallenter(struct thread *td) if (KTRPOINT(td, KTR_SYSCALL)) ktrsyscall(sa->code, sa->narg, sa->args); #endif - if (error != 0) + if (error != 0) { + td->td_errno = error; goto retval; + } } #ifdef CAPABILITY_MODE @@ -116,14 +120,16 @@ syscallenter(struct thread *td) */ if (IN_CAPABILITY_MODE(td) && !(sa->callp->sy_flags & SYF_CAPENABLED)) { - error = ECAPMODE; + td->td_errno = error = ECAPMODE; goto retval; } #endif error = syscall_thread_enter(td, sa->callp); - if (error != 0) + if (error != 0) { + td->td_errno = error; goto retval; + } #ifdef KDTRACE_HOOKS /* Give the syscall:::entry DTrace probe a chance to fire. */ @@ -131,6 +137,9 @@ syscallenter(struct thread *td) (*systrace_probe_func)(sa, SYSTRACE_ENTRY, 0); #endif + /* Let system calls set td_errno directly. */ + td->td_pflags &= ~TDP_NERRNO; + AUDIT_SYSCALL_ENTER(sa->code, td); error = (sa->callp->sy_call)(td, sa->args); AUDIT_SYSCALL_EXIT(error, td); @@ -162,12 +171,12 @@ syscallenter(struct thread *td) } static inline void -syscallret(struct thread *td, int error) +syscallret(struct thread *td, int error __unused) { struct proc *p, *p2; struct syscall_args *sa; ksiginfo_t ksi; - int traced, error1; + int traced; KASSERT((td->td_pflags & TDP_FORKING) == 0, ("fork() did not clear TDP_FORKING upon completion")); @@ -176,12 +185,10 @@ syscallret(struct thread *td, int error) sa = &td->td_sa; if ((trap_enotcap || (p->p_flag2 & P2_TRAPCAP) != 0) && IN_CAPABILITY_MODE(td)) { - error1 = (td->td_pflags & TDP_NERRNO) == 0 ? error : - td->td_errno; - if (error1 == ENOTCAPABLE || error1 == ECAPMODE) { + if (td->td_errno == ENOTCAPABLE || td->td_errno == ECAPMODE) { ksiginfo_init_trap(&ksi); ksi.ksi_signo = SIGTRAP; - ksi.ksi_errno = error1; + ksi.ksi_errno = td->td_errno; ksi.ksi_code = TRAP_CAP; trapsignal(td, &ksi); } @@ -194,11 +201,9 @@ syscallret(struct thread *td, int error) #ifdef KTRACE if (KTRPOINT(td, KTR_SYSRET)) { - ktrsysret(sa->code, (td->td_pflags & TDP_NERRNO) == 0 ? - error : td->td_errno, td->td_retval[0]); + ktrsysret(sa->code, td->td_errno, td->td_retval[0]); } #endif - td->td_pflags &= ~TDP_NERRNO; if (p->p_flag & P_TRACED) { traced = 1;
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202004270447.03R4l2nB060579>