From bg@bg.sics.se  Fri Feb 25 14:30:52 2000
Return-Path: <bg@bg.sics.se>
Received: from bg.sics.se (bg.sics.se [193.10.66.124])
	by hub.freebsd.org (Postfix) with ESMTP id 59B9737BD7E
	for <FreeBSD-gnats-submit@freebsd.org>; Fri, 25 Feb 2000 14:30:47 -0800 (PST)
	(envelope-from bg@bg.sics.se)
Received: (from bg@localhost)
	by bg.sics.se (8.9.3/8.9.3) id XAA02587;
	Fri, 25 Feb 2000 23:30:52 +0100 (CET)
	(envelope-from bg)
Message-Id: <200002252230.XAA02587@bg.sics.se>
Date: Fri, 25 Feb 2000 23:30:52 +0100 (CET)
From: bg@sics.se
Sender: bg@bg.sics.se
Reply-To: bg@sics.se
To: FreeBSD-gnats-submit@freebsd.org
Cc: bg@sics.se
Subject: Linux emulator lacks setfsuid and setfsgid
X-Send-Pr-Version: 3.2

>Number:         16993
>Category:       kern
>Synopsis:       Linux emulator lacks setfsuid and setfsgid
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    marcel
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          change-request
>Submitter-Id:   current-users
>Arrival-Date:   Fri Feb 25 14:40:01 PST 2000
>Closed-Date:    Sun Jul 16 14:24:26 PDT 2000
>Last-Modified:  Sun Jul 16 14:27:08 PDT 2000
>Originator:     Bjoern Groenvall
>Release:        FreeBSD 3.4-RELEASE i386
>Organization:
SICS
>Environment:

FreeBSD 3.4-RELEASE.
Same problem exists under -current.

>Description:

Legato NetWorker has programs nsrwatch and nsradmin that don't work
under the Linux emulator because the setfsuid and setfsgid system
calls are missing.

>How-To-Repeat:

Run the following Linux program

int
main()
{
  setfsuid(geteuid());
}

and you will get a core dump.

>Fix:
	
Patch relative to FreeBSD 3.4-RELEASE.

Note that setfsuid is defined to return the current value of fsuid on
error rather than an error (sic).

--- linux_misc.c	2000/02/25 21:06:01	1.1
+++ linux_misc.c	2000/02/25 22:16:35
@@ -1366,3 +1366,23 @@
 
 	return error;
 }
+
+int
+linux_setfsuid(struct proc *p, struct linux_setfsuid_args *args)
+{
+	p->p_retval[0] = p->p_ucred->cr_uid;
+	if (args->uid == p->p_ucred->cr_uid)
+		return 0;
+	printf("Linux-emul(%d): setfsuid(%d) ignored\n", p->p_pid, args->uid);
+	return 0;
+}
+
+int
+linux_setfsgid(struct proc *p, struct linux_setfsgid_args *args)
+{
+	p->p_retval[0] = p->p_ucred->cr_gid;
+	if (args->gid == p->p_ucred->cr_gid)
+		return 0;
+	printf("Linux-emul(%d): setfsgid(%d) ignored\n", p->p_pid, args->gid);
+	return 0;
+}
--- linux_proto.h	2000/02/25 20:21:50	1.1
+++ linux_proto.h	2000/02/25 21:05:08
@@ -363,6 +363,12 @@
 struct	linux_bdflush_args {
 	register_t dummy;
 };
+struct	linux_setfsuid_args {
+	int     uid;    char uid_[PAD_(int)];
+};
+struct	linux_setfsgid_args {
+	int     gid;    char gid_[PAD_(int)];
+};
 struct	linux_personality_args {
 	int	per;	char per_[PAD_(int)];
 };
@@ -529,6 +535,8 @@
 int	linux_quotactl __P((struct proc *, struct linux_quotactl_args *));
 int	linux_getpgid __P((struct proc *, struct linux_getpgid_args *));
 int	linux_bdflush __P((struct proc *, struct linux_bdflush_args *));
+int	linux_setfsuid __P((struct proc *, struct linux_setfsuid_args *));
+int	linux_setfsgid __P((struct proc *, struct linux_setfsgid_args *));
 int	linux_personality __P((struct proc *, struct linux_personality_args *));
 int	linux_llseek __P((struct proc *, struct linux_llseek_args *));
 int	linux_getdents __P((struct proc *, struct linux_getdents_args *));
--- linux_sysent.c	2000/02/25 20:18:49	1.1
+++ linux_sysent.c	2000/02/25 21:02:20
@@ -153,8 +153,8 @@
 	{ 0, (sy_call_t *)nosys },			/* 135 = sysfs */
 	{ 1, (sy_call_t *)linux_personality },		/* 136 = linux_personality */
 	{ 0, (sy_call_t *)nosys },			/* 137 = afs_syscall */
-	{ 0, (sy_call_t *)nosys },			/* 138 = setfsuid */
-	{ 0, (sy_call_t *)nosys },			/* 139 = getfsuid */
+	{ 0, (sy_call_t *)linux_setfsuid },		/* 138 = linux_setfsuid */
+	{ 0, (sy_call_t *)linux_setfsgid },		/* 139 = linux_setfsgid */
 	{ 5, (sy_call_t *)linux_llseek },		/* 140 = linux_llseek */
 	{ 3, (sy_call_t *)linux_getdents },		/* 141 = linux_getdents */
 	{ 5, (sy_call_t *)linux_newselect },		/* 142 = linux_newselect */
--- syscalls.master	2000/02/25 20:19:23	1.1
+++ syscalls.master	2000/02/25 21:01:24
@@ -195,8 +195,8 @@
 135	UNIMPL	LINUX	sysfs
 136	STD	LINUX	{ int linux_personality(int per); }
 137	UNIMPL	LINUX	afs_syscall
-138	UNIMPL	LINUX	setfsuid
-139	UNIMPL	LINUX	getfsuid
+138	STD	LINUX	linux_setfsuid
+139	STD	LINUX	linux_setfsgid
 140	STD	LINUX	{ int linux_llseek(int fd, u_int32_t ohigh, \
 			    u_int32_t olow, caddr_t res, int whence); }
 141	STD	LINUX	{ int linux_getdents(int fd, void *dent, \

>Release-Note:
>Audit-Trail:
Responsible-Changed-From-To: freebsd-bugs->marcel 
Responsible-Changed-By: sheldonh 
Responsible-Changed-When: Tue Feb 29 08:11:51 PST 2000 
Responsible-Changed-Why:  
Over to the linuxulator's maintainer.  Please be patient while waiting 
for feedback; the maintainer is in the process of relocating at the 
moment and has limited access (if any) to the Internet. 
State-Changed-From-To: open->closed 
State-Changed-By: marcel 
State-Changed-When: Sun Jul 16 14:24:26 PDT 2000 
State-Changed-Why:  
An implementation derived from the patch has been committed to current. 
A MFC will normally take a couple of days. Thanks... 


http://www.freebsd.org/cgi/query-pr.cgi?pr=16993 
>Unformatted:
