git: 4e3aefb923ac - main - linux(4): Fixup waitid handling P_PGID idtype.

From: Dmitry Chagin <dchagin_at_FreeBSD.org>
Date: Thu, 31 Mar 2022 17:50:41 UTC
The branch main has been updated by dchagin:

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

commit 4e3aefb923ac1bd8e2a707b00239f171eab1231b
Author:     Dmitry Chagin <dchagin@FreeBSD.org>
AuthorDate: 2022-03-31 17:44:00 +0000
Commit:     Dmitry Chagin <dchagin@FreeBSD.org>
CommitDate: 2022-03-31 17:44:00 +0000

    linux(4): Fixup waitid handling P_PGID idtype.
    
    Since Linux 5.4, if id is zero, then wait for any child that is in the same
    process grop as the caller's process group.
    
    Differential revision:  https://reviews.freebsd.org/D31567
    MFC after:              2 weeks
---
 sys/compat/linux/linux_mib.h  |  2 ++
 sys/compat/linux/linux_misc.c | 12 ++++++++++--
 2 files changed, 12 insertions(+), 2 deletions(-)

diff --git a/sys/compat/linux/linux_mib.h b/sys/compat/linux/linux_mib.h
index 61a3a38a23ae..e2064903b28b 100644
--- a/sys/compat/linux/linux_mib.h
+++ b/sys/compat/linux/linux_mib.h
@@ -60,8 +60,10 @@ int	linux_kernver(struct thread *td);
 #define	LINUX_KERNVER_2004000	LINUX_KERNVER(2,4,0)
 #define	LINUX_KERNVER_2006000	LINUX_KERNVER(2,6,0)
 #define	LINUX_KERNVER_2006039	LINUX_KERNVER(2,6,39)
+#define	LINUX_KERNVER_5004000	LINUX_KERNVER(5,4,0)
 
 #define	linux_use26(t)		(linux_kernver(t) >= LINUX_KERNVER_2006000)
+#define	linux_use54(t)		(linux_kernver(t) >= LINUX_KERNVER_5004000)
 
 extern int linux_debug;
 extern int linux_default_openfiles;
diff --git a/sys/compat/linux/linux_misc.c b/sys/compat/linux/linux_misc.c
index 260eef258ddb..a4e5f913d03b 100644
--- a/sys/compat/linux/linux_misc.c
+++ b/sys/compat/linux/linux_misc.c
@@ -1097,6 +1097,8 @@ linux_waitid(struct thread *td, struct linux_waitid_args *args)
 {
 	idtype_t idtype;
 	int error, options;
+	struct proc *p;
+	pid_t id;
 
 	if (args->options & ~(LINUX_WNOHANG | LINUX_WNOWAIT | LINUX_WEXITED |
 	    LINUX_WSTOPPED | LINUX_WCONTINUED | __WCLONE | __WNOTHREAD | __WALL))
@@ -1108,6 +1110,7 @@ linux_waitid(struct thread *td, struct linux_waitid_args *args)
 		options |= WEXITED | WTRAPPED | WUNTRACED |
 		    WCONTINUED | WLINUXCLONE;
 
+	id = args->id;
 	switch (args->idtype) {
 	case LINUX_P_ALL:
 		idtype = P_ALL;
@@ -1118,7 +1121,12 @@ linux_waitid(struct thread *td, struct linux_waitid_args *args)
 		idtype = P_PID;
 		break;
 	case LINUX_P_PGID:
-		if (args->id <= 0)
+		if (linux_use54(td) && args->id == 0) {
+			p = td->td_proc;
+			PROC_LOCK(p);
+			id = p->p_pgid;
+			PROC_UNLOCK(p);
+		} else if (args->id <= 0)
 			return (EINVAL);
 		idtype = P_PGID;
 		break;
@@ -1129,7 +1137,7 @@ linux_waitid(struct thread *td, struct linux_waitid_args *args)
 		return (EINVAL);
 	}
 
-	error = linux_common_wait(td, idtype, args->id, NULL, options,
+	error = linux_common_wait(td, idtype, id, NULL, options,
 	    args->rusage, args->info);
 	td->td_retval[0] = 0;