Subject: compat linux setfsuid retval fix and getfsuid/setfsgid exchange
To: NetBSD kernel <tech-kern@netbsd.org>
From: Nicolas Joly <njoly@pasteur.fr>
List: tech-kern
Date: 12/21/2007 20:59:32
--9jxsPFA5p3P2qPhR
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline


Hi,

While making some regression tests under compat linux/linux32, i
noticed the following:

- setfsuid syscall is expected to return an uid, but our
  implementation always returns 0 on success.

- getfsuid ... AFAIK, this syscall never existed in Linux (seems to
  come from PR/9335). It should be replaced by setfsgid instead ...

I'd like to commit the attached patch which fix both.
Any objections ?

-- 
Nicolas Joly

Biological Software and Databanks.
Institut Pasteur, Paris.

--9jxsPFA5p3P2qPhR
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="netbsd-linuxfsuid.diff"

Index: sys/compat/linux/arch/alpha/syscalls.master
===================================================================
RCS file: /cvsroot/src/sys/compat/linux/arch/alpha/syscalls.master,v
retrieving revision 1.59
diff -u -p -r1.59 syscalls.master
--- sys/compat/linux/arch/alpha/syscalls.master	20 Dec 2007 23:02:51 -0000	1.59
+++ sys/compat/linux/arch/alpha/syscalls.master	21 Dec 2007 09:21:23 -0000
@@ -41,7 +41,6 @@
 ;			(i.e. reboot, msgrcv? )
 ;		make sure linux_foo() matches expected prototypes in .c files.
 ;		kill not used functions.  (ifdef the actual code)
-;		fix getfsuid in linux_misc.c
 ;		make linux_sys_sigreturn in linux_machdep.c use frame.extramask
 ;
 ; NOT USED = This syscall is not really used in Linux, except in its
@@ -519,7 +518,7 @@
 323	STD		{ int linux_sys_times(struct times *tms); }
 324	STD		{ int linux_sys_personality(int per); }
 325	STD		{ int linux_sys_setfsuid(uid_t uid); }
-326	UNIMPL		setfsgid
+326	STD		{ int linux_sys_setfsgid(gid_t gid); }
 327	UNIMPL		ustat
 328	STD		{ int linux_sys_statfs(const char *path, \
 			    struct linux_statfs *sp); }
Index: sys/compat/linux/arch/amd64/syscalls.master
===================================================================
RCS file: /cvsroot/src/sys/compat/linux/arch/amd64/syscalls.master,v
retrieving revision 1.20
diff -u -p -r1.20 syscalls.master
--- sys/compat/linux/arch/amd64/syscalls.master	20 Dec 2007 23:02:52 -0000	1.20
+++ sys/compat/linux/arch/amd64/syscalls.master	21 Dec 2007 09:21:24 -0000
@@ -272,7 +272,7 @@
 			    gid_t *sgid); }
 121	STD		{ int linux_sys_getpgid(int pid); }
 122	STD		{ int linux_sys_setfsuid(uid_t uid); }
-123	STD		{ int linux_sys_getfsuid(void); }
+123	STD		{ int linux_sys_setfsgid(gid_t gid); }
 124	NOARGS		{ pid_t sys_getsid(pid_t pid); }
 125	UNIMPL		capget
 126	UNIMPL		capset
Index: sys/compat/linux/arch/arm/syscalls.master
===================================================================
RCS file: /cvsroot/src/sys/compat/linux/arch/arm/syscalls.master,v
retrieving revision 1.30
diff -u -p -r1.30 syscalls.master
--- sys/compat/linux/arch/arm/syscalls.master	20 Dec 2007 23:02:52 -0000	1.30
+++ sys/compat/linux/arch/arm/syscalls.master	21 Dec 2007 09:21:25 -0000
@@ -236,7 +236,7 @@
 136	STD		{ int linux_sys_personality(int per); }
 137	UNIMPL		afs_syscall
 138	STD		{ int linux_sys_setfsuid(uid_t uid); }
-139	NOARGS		{ int linux_sys_getfsuid(void); }
+139	STD		{ int linux_sys_setfsgid(gid_t gid); }
 140	STD		{ int linux_sys_llseek(int fd, u_int32_t ohigh, \
 			    u_int32_t olow, void *res, int whence); }
 141	STD		{ int linux_sys_getdents(int fd, \
@@ -367,7 +367,7 @@
 213	NOARGS		setuid32 { int sys_setuid(uid_t uid); }
 214	NOARGS		setgid32 { int sys_setgid(gid_t gid); }
 215	NOARGS		setfsuid32 { int linux_sys_setfsuid(uid_t uid); }
-216	NOARGS		getfsuid32 { int linux_sys_getfsuid(void); }
+216	NOARGS		setfsgid32 { int linux_sys_setfsgid(gid_t gid); }
 217	STD		{ int linux_sys_getdents64(int fd, \
 			    struct linux_dirent64 *dent, unsigned int count); }
 218	UNIMPL		pivot_root
Index: sys/compat/linux/arch/i386/syscalls.master
===================================================================
RCS file: /cvsroot/src/sys/compat/linux/arch/i386/syscalls.master,v
retrieving revision 1.86
diff -u -p -r1.86 syscalls.master
--- sys/compat/linux/arch/i386/syscalls.master	20 Dec 2007 23:02:52 -0000	1.86
+++ sys/compat/linux/arch/i386/syscalls.master	21 Dec 2007 09:21:26 -0000
@@ -248,7 +248,7 @@
 136	STD		{ int linux_sys_personality(int per); }
 137	UNIMPL		afs_syscall
 138	NOARGS		linux_setfsuid16 { int linux_sys_setfsuid(uid_t uid); }
-139	NOARGS		linux_getfsuid16 { int linux_sys_getfsuid(void); }
+139	NOARGS		linux_setfsgid16 { int linux_sys_setfsgid(gid_t gid); }
 140	STD		{ int linux_sys_llseek(int fd, u_int32_t ohigh, \
 			    u_int32_t olow, void *res, int whence); }
 141	STD		{ int linux_sys_getdents(int fd, \
@@ -374,7 +374,7 @@
 213	NOARGS		{ int sys_setuid(uid_t uid); }
 214	NOARGS		{ int sys_setgid(gid_t gid); }
 215	STD		{ int linux_sys_setfsuid(uid_t uid); }
-216	NOARGS		{ int linux_sys_getfsuid(void); }
+216	STD		{ int linux_sys_setfsgid(gid_t gid); }
 217	UNIMPL		pivot_root
 218	NOARGS		{ int sys_mincore(void *addr, size_t len, char *vec); }
 219	NOARGS		{ int sys_madvise(void *addr, size_t len, int behav); }
Index: sys/compat/linux/arch/m68k/syscalls.master
===================================================================
RCS file: /cvsroot/src/sys/compat/linux/arch/m68k/syscalls.master,v
retrieving revision 1.56
diff -u -p -r1.56 syscalls.master
--- sys/compat/linux/arch/m68k/syscalls.master	20 Dec 2007 23:02:53 -0000	1.56
+++ sys/compat/linux/arch/m68k/syscalls.master	21 Dec 2007 09:21:27 -0000
@@ -253,7 +253,7 @@
 136	STD		{ int linux_sys_personality(int per); }
 137	UNIMPL		afs_syscall
 138	NOARGS		linux_setfsuid16 { int linux_sys_setfsuid(uid_t uid); }
-139	NOARGS		linux_getfsuid16 { int linux_sys_getfsuid(void); }
+139	NOARGS		linux_setfsgid16 { int linux_sys_setfsgid(gid_t gid); }
 140	STD		{ int linux_sys_llseek(int fd, u_int32_t ohigh, \
 			    u_int32_t olow, void *res, int whence); }
 141	STD		{ int linux_sys_getdents(int fd, \
@@ -379,7 +379,7 @@
 213	NOARGS		{ int sys_setuid(uid_t uid); }
 214	NOARGS		{ int sys_setgid(gid_t gid); }
 215	STD		{ int linux_sys_setfsuid(uid_t uid); }
-216	NOARGS		{ int linux_sys_getfsuid(void); }
+216	STD		{ int linux_sys_setfsgid(gid_t gid); }
 217	UNIMPL		/* unused */
 218	UNIMPL		/* unused */
 219	UNIMPL		/* unused */
Index: sys/compat/linux/arch/mips/syscalls.master
===================================================================
RCS file: /cvsroot/src/sys/compat/linux/arch/mips/syscalls.master,v
retrieving revision 1.25
diff -u -p -r1.25 syscalls.master
--- sys/compat/linux/arch/mips/syscalls.master	20 Dec 2007 23:02:53 -0000	1.25
+++ sys/compat/linux/arch/mips/syscalls.master	21 Dec 2007 09:21:28 -0000
@@ -240,7 +240,7 @@
 136	STD		{ int linux_sys_personality(int per); }
 137	UNIMPL		afs_syscall
 138	STD		{ int linux_sys_setfsuid(uid_t uid); }
-139	NOARGS		{ int linux_sys_getfsuid(void); }
+139	STD		{ int linux_sys_setfsgid(gid_t gid); }
 140	STD		{ int linux_sys_llseek(int fd, u_int32_t ohigh, \
 			    u_int32_t olow, void *res, int whence); }
 141	STD		{ int linux_sys_getdents(int fd, \
Index: sys/compat/linux/arch/powerpc/syscalls.master
===================================================================
RCS file: /cvsroot/src/sys/compat/linux/arch/powerpc/syscalls.master,v
retrieving revision 1.33
diff -u -p -r1.33 syscalls.master
--- sys/compat/linux/arch/powerpc/syscalls.master	20 Dec 2007 23:02:53 -0000	1.33
+++ sys/compat/linux/arch/powerpc/syscalls.master	21 Dec 2007 09:21:29 -0000
@@ -269,7 +269,7 @@
 136	STD		{ int linux_sys_personality(int per); }
 137	UNIMPL		afs_syscall
 138	STD		{ int linux_sys_setfsuid(uid_t uid); }
-139	NOARGS		{ int linux_sys_getfsuid(void); }
+139	STD		{ int linux_sys_setfsgid(gid_t gid); }
 140	STD		{ int linux_sys_llseek(int fd, u_int32_t ohigh, \
 			    u_int32_t olow, void *res, int whence); }
 141	STD		{ int linux_sys_getdents(int fd, \
Index: sys/compat/linux/common/linux_misc.c
===================================================================
RCS file: /cvsroot/src/sys/compat/linux/common/linux_misc.c,v
retrieving revision 1.190
diff -u -p -r1.190 linux_misc.c
--- sys/compat/linux/common/linux_misc.c	20 Dec 2007 23:02:55 -0000	1.190
+++ sys/compat/linux/common/linux_misc.c	21 Dec 2007 09:21:30 -0000
@@ -1159,18 +1159,26 @@ linux_sys_setfsuid(struct lwp *l, const 
 	 uid = SCARG(uap, uid);
 	 if (kauth_cred_getuid(l->l_cred) != uid)
 		 return sys_nosys(l, uap, retval);
-	 else
-		 return (0);
+
+	 *retval = uid;
+	 return 0;
 }
 
-/* XXX XXX XXX */
-# ifndef alpha
 int
-linux_sys_getfsuid(struct lwp *l, const void *uap, register_t *retval)
+linux_sys_setfsgid(struct lwp *l, const struct linux_sys_setfsgid_args *uap, register_t *retval)
 {
-	return sys_getuid(l, uap, retval);
+	/* {
+		syscallarg(gid_t) gid;
+	} */
+	gid_t gid;
+
+	gid = SCARG(uap, gid);
+	if (kauth_cred_getgid(l->l_cred) != gid)
+		return sys_nosys(l, uap, retval);
+
+	*retval = gid;
+	return 0;
 }
-# endif
 
 int
 linux_sys_setresuid(struct lwp *l, const struct linux_sys_setresuid_args *uap, register_t *retval)
Index: sys/compat/linux32/arch/amd64/syscalls.master
===================================================================
RCS file: /cvsroot/src/sys/compat/linux32/arch/amd64/syscalls.master,v
retrieving revision 1.21
diff -u -p -r1.21 syscalls.master
--- sys/compat/linux32/arch/amd64/syscalls.master	20 Dec 2007 23:02:57 -0000	1.21
+++ sys/compat/linux32/arch/amd64/syscalls.master	21 Dec 2007 09:21:31 -0000
@@ -236,7 +236,7 @@
 136	UNIMPL	personality
 137	UNIMPL	afs_syscall
 138	NOARGS	setfsuid16 { int linux32_sys_setfsuid(uid_t uid); }
-139	NOARGS	getfsuid16 { int linux_sys_getfsuid(void); }
+139	NOARGS	setfsgid16 { int linux32_sys_setfsgid(gid_t gid); }
 140	STD	{ int linux32_sys_llseek(int fd, u_int32_t ohigh, \
 		    u_int32_t olow, netbsd32_caddr_t res, int whence); }
 141	STD	{ int linux32_sys_getdents(int fd, \
@@ -352,7 +352,7 @@
 213 	NOARGS	{ int netbsd32_setuid(uid_t uid); }
 214	NOARGS	{ int netbsd32_setgid(gid_t gid); }
 215	STD	{ int linux32_sys_setfsuid(uid_t uid); }
-216	NOARGS	{ int linux_sys_getfsuid(void); }
+216	STD	{ int linux32_sys_setfsgid(gid_t gid); }
 217	UNIMPL	pivot_root
 218	UNIMPL	mincore
 219	NOARGS	{ int netbsd32_madvise(netbsd32_voidp addr, \
Index: sys/compat/linux32/common/linux32_unistd.c
===================================================================
RCS file: /cvsroot/src/sys/compat/linux32/common/linux32_unistd.c,v
retrieving revision 1.17
diff -u -p -r1.17 linux32_unistd.c
--- sys/compat/linux32/common/linux32_unistd.c	20 Dec 2007 23:02:59 -0000	1.17
+++ sys/compat/linux32/common/linux32_unistd.c	21 Dec 2007 09:21:31 -0000
@@ -577,6 +577,19 @@ linux32_sys_setfsuid(struct lwp *l, cons
 }
 
 int
+linux32_sys_setfsgid(struct lwp *l, const struct linux32_sys_setfsgid_args *uap, register_t *retval)
+{
+	/* {
+		syscallarg(gid_t) gid;
+	} */
+	struct linux_sys_setfsgid_args ua;
+
+	NETBSD32TO64_UAP(gid);
+
+	return linux_sys_setfsgid(l, &ua, retval);
+}
+
+int
 linux32_sys_setreuid16(struct lwp *l, const struct linux32_sys_setreuid16_args *uap, register_t *retval)
 {
 	/* {

--9jxsPFA5p3P2qPhR--