git: 4cae9d803a95 - stable/13 - Remove PT_GET_SC_ARGS_ALL

From: Edward Tomasz Napierala <trasz_at_FreeBSD.org>
Date: Mon, 21 Feb 2022 13:48:53 UTC
The branch stable/13 has been updated by trasz:

URL: https://cgit.FreeBSD.org/src/commit/?id=4cae9d803a9562a003d00bf8f7b90674e011bae7

commit 4cae9d803a9562a003d00bf8f7b90674e011bae7
Author:     Konstantin Belousov <kib@FreeBSD.org>
AuthorDate: 2021-09-15 13:24:09 +0000
Commit:     Edward Tomasz Napierala <trasz@FreeBSD.org>
CommitDate: 2022-02-21 13:34:16 +0000

    Remove PT_GET_SC_ARGS_ALL
    
    Reimplement bdf0f24bb16d556a5b by checking for the caller' ABI in
    the implementation of PT_GET_SC_ARGS, and copying out everything if
    it is Linuxolator.
    
    Also fix a minor information leak: if PT_GET_SC_ARGS_ALL is done on the
    thread reused after other process, it allows to read some number of that
    thread last syscall arguments. Clear td_sa.args in thread_alloc().
    
    Reviewed by:    jhb
    Sponsored by:   The FreeBSD Foundation
    Differential revision:  https://reviews.freebsd.org/D31968
    
    (cherry picked from commit f575573ca57716395ad88b962388a55d755cf6a7)
---
 lib/libsysdecode/mktables             |  2 +-
 sys/amd64/linux/linux_ptrace.c        | 18 ++++++++++--------
 sys/compat/freebsd32/freebsd32_misc.c |  3 ---
 sys/kern/kern_thread.c                |  1 +
 sys/kern/sys_process.c                | 23 ++++-------------------
 sys/sys/ptrace.h                      |  4 ----
 6 files changed, 16 insertions(+), 35 deletions(-)

diff --git a/lib/libsysdecode/mktables b/lib/libsysdecode/mktables
index f044784717c0..77cfa15bd1f5 100644
--- a/lib/libsysdecode/mktables
+++ b/lib/libsysdecode/mktables
@@ -116,7 +116,7 @@ gen_table "nfssvcflags"     "NFSSVC_[A-Z0-9]+[[:space:]]+0x[0-9]+"         "nfs/
 gen_table "pathconfname"    "_PC_[A-Z4_]+[[:space:]]+[0-9]+"               "sys/unistd.h"
 gen_table "prio"            "PRIO_[A-Z]+[[:space:]]+[0-9]"                 "sys/resource.h"
 gen_table "procctlcmd"      "PROC_[A-Z_]+[[:space:]]+[0-9]"                 "sys/procctl.h"	"PROC_TRACE_CTL_"
-gen_table "ptraceop"        "PT_[[:alnum:]_]+[[:space:]]+[0-9]+"           "sys/ptrace.h"	"PT_GET_SC_ARGS_ALL"
+gen_table "ptraceop"        "PT_[[:alnum:]_]+[[:space:]]+[0-9]+"           "sys/ptrace.h"
 gen_table "quotactlcmds"    "Q_[A-Z]+[[:space:]]+0x[0-9]+"                 "ufs/ufs/quota.h"
 gen_table "rebootopt"       "RB_[A-Z]+[[:space:]]+0x[0-9]+"                "sys/reboot.h"
 gen_table "rforkflags"      "RF[A-Z]+[[:space:]]+\([0-9]+<<[0-9]+\)"       "sys/unistd.h"
diff --git a/sys/amd64/linux/linux_ptrace.c b/sys/amd64/linux/linux_ptrace.c
index fa400e0d3529..a29a3310dfcd 100644
--- a/sys/amd64/linux/linux_ptrace.c
+++ b/sys/amd64/linux/linux_ptrace.c
@@ -578,17 +578,19 @@ linux_ptrace_get_syscall_info(struct thread *td, pid_t pid,
 		si.op = LINUX_PTRACE_SYSCALL_INFO_ENTRY;
 		si.entry.nr = lwpinfo.pl_syscall_code;
 		/*
-		 * The reason for using PT_GET_SC_ARGS_ALL instead
-		 * of PT_GET_SC_ARGS is to emulate Linux bug which strace(1)
-		 * depends on: at initialization it tests whether ptrace works
-		 * by calling close(2), or some other single-argument syscall,
-		 * _with six arguments_, and then verifies whether it can
-		 * fetch them all using this API; otherwise it bails out.
+		 * The use of PT_GET_SC_ARGS there is special,
+		 * implementation of PT_GET_SC_ARGS for Linux-ABI
+		 * callers emulates Linux bug which strace(1) depends
+		 * on: at initialization it tests whether ptrace works
+		 * by calling close(2), or some other single-argument
+		 * syscall, _with six arguments_, and then verifies
+		 * whether it can fetch them all using this API;
+		 * otherwise it bails out.
 		 */
-		error = kern_ptrace(td, PT_GET_SC_ARGS_ALL, pid,
+		error = kern_ptrace(td, PT_GET_SC_ARGS, pid,
 		    &si.entry.args, sizeof(si.entry.args));
 		if (error != 0) {
-			linux_msg(td, "PT_GET_SC_ARGS_ALL failed with error %d",
+			linux_msg(td, "PT_GET_SC_ARGS failed with error %d",
 			    error);
 			return (error);
 		}
diff --git a/sys/compat/freebsd32/freebsd32_misc.c b/sys/compat/freebsd32/freebsd32_misc.c
index b7128debd97f..e56ab423f538 100644
--- a/sys/compat/freebsd32/freebsd32_misc.c
+++ b/sys/compat/freebsd32/freebsd32_misc.c
@@ -1025,9 +1025,6 @@ freebsd32_ptrace(struct thread *td, struct freebsd32_ptrace_args *uap)
 		r.pc.pc_limit = PAIR32TO64(off_t, r32.pc.pc_limit);
 		data = sizeof(r.pc);
 		break;
-	case PT_GET_SC_ARGS_ALL:
-		error = EINVAL;
-		break;
 	default:
 		addr = uap->addr;
 		break;
diff --git a/sys/kern/kern_thread.c b/sys/kern/kern_thread.c
index 48aac8e057b8..54254112b376 100644
--- a/sys/kern/kern_thread.c
+++ b/sys/kern/kern_thread.c
@@ -761,6 +761,7 @@ thread_alloc(int pages)
 		return (NULL);
 	}
 	td->td_tid = tid;
+	bzero(&td->td_sa.args, sizeof(td->td_sa.args));
 	cpu_thread_alloc(td);
 	EVENTHANDLER_DIRECT_INVOKE(thread_ctor, td);
 	return (td);
diff --git a/sys/kern/sys_process.c b/sys/kern/sys_process.c
index 75d950a57057..1b9c00179bda 100644
--- a/sys/kern/sys_process.c
+++ b/sys/kern/sys_process.c
@@ -532,9 +532,6 @@ sys_ptrace(struct thread *td, struct ptrace_args *uap)
 		else
 			error = copyin(uap->addr, &r.pc, uap->data);
 		break;
-	case PT_GET_SC_ARGS_ALL:
-		error = EINVAL;
-		break;
 	default:
 		addr = uap->addr;
 		break;
@@ -716,7 +713,6 @@ kern_ptrace(struct thread *td, int req, pid_t pid, void *addr, int data)
 	case PT_SET_EVENT_MASK:
 	case PT_DETACH:
 	case PT_GET_SC_ARGS:
-	case PT_GET_SC_ARGS_ALL:
 		sx_xlock(&proctree_lock);
 		proctree_locked = true;
 		break;
@@ -1016,21 +1012,10 @@ kern_ptrace(struct thread *td, int req, pid_t pid, void *addr, int data)
 			break;
 		}
 		bzero(addr, sizeof(td2->td_sa.args));
-		bcopy(td2->td_sa.args, addr, td2->td_sa.callp->sy_narg *
-		    sizeof(register_t));
-		break;
-
-	case PT_GET_SC_ARGS_ALL:
-		CTR1(KTR_PTRACE, "PT_GET_SC_ARGS_ALL: pid %d", p->p_pid);
-		if ((td2->td_dbgflags & (TDB_SCE | TDB_SCX)) == 0
-#ifdef COMPAT_FREEBSD32
-		    || (wrap32 && !safe)
-#endif
-		    ) {
-			error = EINVAL;
-			break;
-		}
-		bcopy(td2->td_sa.args, addr, sizeof(td2->td_sa.args));
+		/* See the explanation in linux_ptrace_get_syscall_info(). */
+		bcopy(td2->td_sa.args, addr, SV_PROC_ABI(td->td_proc) ==
+		    SV_ABI_LINUX ? sizeof(td2->td_sa.args) :
+		    td2->td_sa.callp->sy_narg * sizeof(register_t));
 		break;
 
 	case PT_GET_SC_RET:
diff --git a/sys/sys/ptrace.h b/sys/sys/ptrace.h
index de7a49576c30..4cd7a3fceaec 100644
--- a/sys/sys/ptrace.h
+++ b/sys/sys/ptrace.h
@@ -86,10 +86,6 @@
 #define	PT_VM_TIMESTAMP	40	/* Get VM version (timestamp) */
 #define	PT_VM_ENTRY	41	/* Get VM map (entry) */
 
-#ifdef _KERNEL
-#define	PT_GET_SC_ARGS_ALL	42	/* Used by linux(4) */
-#endif
-
 #define PT_FIRSTMACH    64	/* for machine-specific requests */
 #include <machine/ptrace.h>	/* machine-specific requests, if any */