Subject: kern/9335: Linux fsuid system calls
To: None <gnats-bugs@gnats.netbsd.org>
From: None <w.wnuk@zodiac.mimuw.edu.pl>
List: netbsd-bugs
Date: 02/02/2000 12:43:10
>Number:         9335
>Category:       kern
>Synopsis:       Linux fsuid system calls
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    kern-bug-people (Kernel Bug People)
>State:          open
>Class:          change-request
>Submitter-Id:   net
>Arrival-Date:   Wed Feb  2 12:42:00 2000
>Last-Modified:
>Originator:     Witold J. Wnuk
>Organization:
	MIMUW
>Release:        February 1
>Environment:
System: NetBSD grzyb.anal.net 1.4Q NetBSD 1.4Q (NGRZYB) #22: Tue Feb 1 15:12:01 CET 2000 witek@grzyb.anal.net:/empire/src/sys/arch/i386/compile/NGRZYB i386


>Description:
	Linux binaries that use setfsuid and getfsuid dumps core
	(Bad system call)
>How-To-Repeat:
	Run Linux binary statically linked or linked with original Linux
	libraries (eg. SuSe 6.3)
>Fix:
We don't support the fsuid concept, but:

o  returning uid in linux_sys_getfsuid seems perfectly right.

o  accepting fsuid == uid in linux_sys_setfsuid (and doing nothing)
   seems perfectly right too.

And following is quite common use of these two. In fact, both Slang
and ncurses (or does Slang just use ncurses?) do something like
setfsuid(getuid()) (and setfsuid(geteuid()), but it shouldn't
be a problem). 

In all other cases we should probably just return ENOSYS.

NetBSD version of Linux ncurses won't be needed this way (in suse
compat package) and statically linked binaries will be allowed to run.

patch follows (syscalls.master should be updated too):

Index: linux_misc.c
===================================================================
RCS file: /lfs/cvsroot/syssrc/sys/compat/linux/common/linux_misc.c,v
retrieving revision 1.62
diff -u -5 -r1.62 linux_misc.c
--- linux_misc.c        1999/12/16 15:09:49     1.62
+++ linux_misc.c        2000/01/30 20:44:12
@@ -904,10 +904,41 @@
                (uid_t)-1 : SCARG(uap, egid);
 
        return sys_setregid(p, &bsa, retval);
 }
 
+/*
+ * We have nonexistant fsuid == uid.
+ * If call is no-op return 0, otherwise ENOSYS.
+ */
+int
+linux_sys_setfsuid(p, v, retval)
+        struct proc *p;
+        void *v;
+        register_t *retval;
+{
+        struct linux_sys_setfsuid_args /* {
+                syscallarg(uid_t) uid;
+        } */ *uap = v;
+        uid_t uid;
+
+        uid = SCARG(uap, uid);
+        if (p->p_cred->p_ruid != uid)
+                return (ENOSYS);
+        else
+                return (0);
+}
+
+int
+linux_sys_getfsuid(p, v, retval)
+        struct proc *p;
+        void *v;
+        register_t *retval;
+{
+        return sys_getuid(p, v, retval);
+}
+
 int
 linux_sys___sysctl(p, v, retval)
        struct proc *p;
        void *v;
        register_t *retval;

>Audit-Trail:
>Unformatted: