From nobody@FreeBSD.ORG Mon Jun 21 01:49:00 1999
Return-Path: <nobody@FreeBSD.ORG>
Received: by hub.freebsd.org (Postfix, from userid 32767)
	id 9137A151DB; Mon, 21 Jun 1999 01:48:52 -0700 (PDT)
Message-Id: <19990621084852.9137A151DB@hub.freebsd.org>
Date: Mon, 21 Jun 1999 01:48:52 -0700 (PDT)
From: petr.rehor@decros.cz
Sender: nobody@FreeBSD.ORG
To: freebsd-gnats-submit@freebsd.org
Subject: linux emu: getrusage causing core dumps
X-Send-Pr-Version: www-1.0

>Number:         12319
>Category:       kern
>Synopsis:       linux emu: getrusage causing core dumps
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    freebsd-bugs
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Mon Jun 21 01:50:01 PDT 1999
>Closed-Date:    Thu Aug 12 03:56:42 PDT 1999
>Last-Modified:  Thu Aug 12 03:58:44 PDT 1999
>Originator:     Petr Rehor
>Release:        FreeBSD 3.1-RELEASE
>Organization:
DECROS s.r.o.
>Environment:
>Description:
getrusage in linux emulator is directly mapped onto the native
FreeBSD version. Core dumps are caused for RUSAGE_BOTH (-2).
>How-To-Repeat:

>Fix:
Here's my patches (implemented like linux/kern/sys.c):

diff -u sys/i386/linux/linux_misc.c.orig sys/i386/linux/linux_misc.c
--- sys/i386/linux/linux_misc.c.orig	Wed Jan 27 21:51:40 1999
+++ sys/i386/linux/linux_misc.c	Mon Jun 14 21:37:29 1999
@@ -1212,3 +1212,30 @@
   p->p_retval[0] = ngrp;
   return (0);
 }
+
+int
+linux_getrusage(struct proc *p, struct linux_getrusage_args *uap)
+{
+  struct rusage rup;
+
+#ifdef DEBUG
+  printf("Linux-emul(%ld): getrusage(%d)\n", (long)p->p_pid, uap->who);
+#endif
+
+  bzero(&rup, sizeof(rup));
+  switch (uap->who) {
+     case RUSAGE_SELF:
+	ruadd(&rup, &p->p_stats->p_ru);
+	calcru(p, &rup.ru_utime, &rup.ru_stime, NULL);
+	break;
+     case RUSAGE_CHILDREN:
+	ruadd(&rup, &p->p_stats->p_cru);
+	break;
+     default:
+	ruadd(&rup, &p->p_stats->p_ru);
+	calcru(p, &rup.ru_utime, &rup.ru_stime, NULL);
+	ruadd(&rup, &p->p_stats->p_cru);
+	break;
+  }
+  return (copyout((caddr_t)&rup, (caddr_t)uap->rusage, sizeof(rup)));
+}
diff -u sys/i386/linux/linux_proto.h.orig sys/i386/linux/linux_proto.h
--- sys/i386/linux/linux_proto.h.orig	Wed Dec 30 22:01:33 1998
+++ sys/i386/linux/linux_proto.h	Mon Jun 14 19:33:55 1999
@@ -195,6 +195,10 @@
 struct	linux_sigpending_args {
 	linux_sigset_t *	mask;	char mask_[PAD_(linux_sigset_t *)];
 };
+struct	linux_getrusage_args {
+	int	who;	char who_[PAD_(int)];
+	struct rusage *	rusage;	char rusage_[PAD_(struct rusage *)];
+};
 struct	linux_getgroups_args {
 	u_int	gidsetsize;	char gidsetsize_[PAD_(u_int)];
 	linux_gid_t *	gidset;	char gidset_[PAD_(linux_gid_t *)];
@@ -437,6 +441,7 @@
 int	linux_sigsetmask __P((struct proc *, struct linux_sigsetmask_args *));
 int	linux_sigsuspend __P((struct proc *, struct linux_sigsuspend_args *));
 int	linux_sigpending __P((struct proc *, struct linux_sigpending_args *));
+int	linux_getrusage __P((struct proc *, struct linux_getrusage_args *));
 int	linux_getgroups __P((struct proc *, struct linux_getgroups_args *));
 int	linux_setgroups __P((struct proc *, struct linux_setgroups_args *));
 int	linux_select __P((struct proc *, struct linux_select_args *));
diff -u sys/i386/linux/linux_syscall.h.orig sys/i386/linux/linux_syscall.h
--- sys/i386/linux/linux_syscall.h.orig	Wed Dec 30 22:01:33 1998
+++ sys/i386/linux/linux_syscall.h	Mon Jun 14 19:33:55 1999
@@ -82,7 +82,7 @@
 #define	LINUX_SYS_osethostname	74
 #define	LINUX_SYS_osetrlimit	75
 #define	LINUX_SYS_ogetrlimit	76
-#define	LINUX_SYS_getrusage	77
+#define	LINUX_SYS_linux_getrusage	77
 #define	LINUX_SYS_gettimeofday	78
 #define	LINUX_SYS_settimeofday	79
 #define	LINUX_SYS_linux_getgroups	80
diff -u sys/i386/linux/linux_sysent.c.orig sys/i386/linux/linux_sysent.c
--- sys/i386/linux/linux_sysent.c.orig	Wed Dec 30 22:01:34 1998
+++ sys/i386/linux/linux_sysent.c	Mon Jun 14 19:33:55 1999
@@ -91,7 +91,7 @@
 	{ 2, (sy_call_t *)osethostname },		/* 74 = osethostname */
 	{ 2, (sy_call_t *)osetrlimit },			/* 75 = osetrlimit */
 	{ 2, (sy_call_t *)ogetrlimit },			/* 76 = ogetrlimit */
-	{ 2, (sy_call_t *)getrusage },			/* 77 = getrusage */
+	{ 2, (sy_call_t *)linux_getrusage },		/* 77 = linux_getrusage */
 	{ 2, (sy_call_t *)gettimeofday },		/* 78 = gettimeofday */
 	{ 2, (sy_call_t *)settimeofday },		/* 79 = settimeofday */
 	{ 2, (sy_call_t *)linux_getgroups },		/* 80 = linux_getgroups */
diff -u sys/i386/linux/syscalls.master.orig sys/i386/linux/syscalls.master
--- sys/i386/linux/syscalls.master.orig	Wed Dec 30 21:58:28 1998
+++ sys/i386/linux/syscalls.master	Mon Jun 14 19:31:39 1999
@@ -114,7 +114,7 @@
 			    struct ogetrlimit *rlp); }
 76	NOPROTO	LINUX	{ int ogetrlimit(u_int which, \
 			    struct ogetrlimit *rlp); }
-77	NOPROTO	LINUX	{ int getrusage(int who, struct rusage *rusage); }
+77	STD	LINUX	{ int linux_getrusage(int who, struct rusage *rusage); }
 78	NOPROTO	LINUX	{ int gettimeofday(struct timeval *tp, \
 			    struct timezone *tzp); }
 79	NOPROTO	LINUX	{ int settimeofday(struct timeval *tp, \

>Release-Note:
>Audit-Trail:

From: Marcel Moolenaar <marcel@scc.nl>
To: freebsd-gnats-submit@freebsd.org, petr.rehor@decros.cz
Cc:  
Subject: Re: kern/12319: linux emu: getrusage causing core dumps
Date: Tue, 10 Aug 1999 22:17:50 +0200

 The Linux getrusage syscall only accepts RUSAGE_SELF and RUSAGE_CHILDREN.
 RUSAGE_BOTH is only used internally. How does the emulated syscall differ
 from the Linux native syscall? Both return EINVAL for anything other than
 RUSAGE_SELF and RUSAGE_CHILDREN. How do you explain the coredump? Does the
 binary coredump on a Linux system? Do I miss something?
 
 Linux kernel
 	version:	2.2.10
 	file:		kernel/sys.c
 FreeBSD
 	version:	-current (7 aug 1999)
 	file:		kern/kern_resource.c
 
 -- 
 Marcel Moolenaar                                  mailto:marcel@scc.nl
 SCC Internetworking & Databases                     http://www.scc.nl/
 Amsterdam, The Netherlands                         tel: +31 20 4200655
 
State-Changed-From-To: open->closed 
State-Changed-By: marcel 
State-Changed-When: Thu Aug 12 03:56:42 PDT 1999 
State-Changed-Why:  
False alarm. The coredump was caused by something else. Unfortunately it is 
not known by what. The getrusage implementation is correct. 
>Unformatted:
