From nobody  Tue Dec 29 06:15:07 1998
Received: (from nobody@localhost)
          by hub.freebsd.org (8.8.8/8.8.8) id GAA03996;
          Tue, 29 Dec 1998 06:15:07 -0800 (PST)
          (envelope-from nobody)
Message-Id: <199812291415.GAA03996@hub.freebsd.org>
Date: Tue, 29 Dec 1998 06:15:07 -0800 (PST)
From: marcel@scc.nl
To: freebsd-gnats-submit@freebsd.org
Subject: linux emu: {s|g}etgroups causing core dumps
X-Send-Pr-Version: www-1.0

>Number:         9235
>Category:       i386
>Synopsis:       linux emu: {s|g}etgroups causing core dumps
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    sos
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Tue Dec 29 06:20:01 PST 1998
>Closed-Date:    Wed Dec 30 12:57:06 PST 1998
>Last-Modified:  Wed Dec 30 13:02:13 PST 1998
>Originator:     Marcel Moolenaar
>Release:        -current
>Organization:
SCC vof
>Environment:
FreeBSD scones.sup.scc.nl 3.0-CURRENT FreeBSD 3.0-CURRENT #0: Tue Dec 22 12:17:33 CET 1998     marcel@scones.sup.scc.nl:/usr/src/sys/compile/SCONES  i386

>Description:
{s|g}etgroups in the linux emulator are directly mapped onto the native
FreeBSD versions. Core dumps are caused by a mismatch in the gid_t data-
type. FreeBSD uses a 32-bit datatype, while Linux uses a 16-bit datatype.

>How-To-Repeat:
n/a
>Fix:
apply the following patches:

\begin{verbatim}
*** syscalls.master.orig        Tue Dec 29 14:09:24 1998
--- syscalls.master     Tue Dec 29 14:13:44 1998
***************
*** 119,126 ****
                            struct timezone *tzp); }
  79    NOPROTO LINUX   { int settimeofday(struct timeval *tp, \
                            struct timezone *tzp); }
! 80    NOPROTO LINUX   { int getgroups(u_int gidsetsize, gid_t *gidset); }
! 81    NOPROTO LINUX   { int setgroups(u_int gidsetsize, gid_t *gidset); }
  82    STD     LINUX   { int linux_select(struct linux_select_argv *ptr); }
  83    STD     LINUX   { int linux_symlink(char *path, char *to); }
  84    NOPROTO LINUX   { int ostat(char *path, struct ostat *up); }
--- 119,126 ----
                            struct timezone *tzp); }
  79    NOPROTO LINUX   { int settimeofday(struct timeval *tp, \
                            struct timezone *tzp); }
! 80    STD     LINUX   { int linux_getgroups(u_int gidsetsize, linux_gid_t *gid
set); }
! 81    STD     LINUX   { int linux_setgroups(u_int gidsetsize, linux_gid_t *gid
set); }
  82    STD     LINUX   { int linux_select(struct linux_select_argv *ptr); }
  83    STD     LINUX   { int linux_symlink(char *path, char *to); }
  84    NOPROTO LINUX   { int ostat(char *path, struct ostat *up); }
\end{verbatim}

\begin{verbatim}
*** linux_misc.c.orig   Tue Dec 29 14:02:29 1998
--- linux_misc.c        Tue Dec 29 14:45:05 1998
***************
*** 1171,1173 ****
--- 1171,1245 ----
        return setpriority(p, &bsd_args);
  }
  
+ int
+ linux_setgroups(p, uap)
+      struct proc *p;
+      struct linux_setgroups_args *uap;
+ {
+   struct pcred *pc = p->p_cred;
+   linux_gid_t linux_gidset[NGROUPS];
+   gid_t *bsd_gidset;
+   int ngrp, error;
+ 
+   if ((error = suser(pc->pc_ucred, &p->p_acflag)))
+     return error;
+ 
+   if (uap->gidsetsize > NGROUPS)
+     return EINVAL;
+ 
+   ngrp = uap->gidsetsize;
+   pc->pc_ucred = crcopy(pc->pc_ucred);
+   if (ngrp >= 1) {
+     if ((error = copyin((caddr_t)uap->gidset,
+                       (caddr_t)linux_gidset,
+                         ngrp * sizeof(linux_gid_t))))
+       return error;
+ 
+     pc->pc_ucred->cr_ngroups = ngrp;
+ 
+     bsd_gidset = pc->pc_ucred->cr_groups;
+     ngrp--;
+     while (ngrp >= 0) {
+       bsd_gidset[ngrp] = linux_gidset[ngrp];
+       ngrp--;
+     }
+   }
+   else
+     pc->pc_ucred->cr_ngroups = 1;
+ 
+   setsugid(p);
+   return 0;
+ }
+ 
+ int
+ linux_getgroups(p, uap)
+      struct proc *p;
+      struct linux_getgroups_args *uap;
+ {
+   struct pcred *pc = p->p_cred;
+   linux_gid_t linux_gidset[NGROUPS];
+   gid_t *bsd_gidset;
+   int ngrp, error;
+ 
+   if ((ngrp = uap->gidsetsize) == 0) {
+     p->p_retval[0] = pc->pc_ucred->cr_ngroups;
+     return 0;
+   }
+ 
+   if (ngrp < pc->pc_ucred->cr_ngroups)
+     return EINVAL;
+ 
+   ngrp = 0;
+   bsd_gidset = pc->pc_ucred->cr_groups;
+   while (ngrp < pc->pc_ucred->cr_ngroups) {
+     linux_gidset[ngrp] = bsd_gidset[ngrp];
+     ngrp++;
+   }
+ 
+   if ((error = copyout((caddr_t)linux_gidset, (caddr_t)uap->gidset,
+                        ngrp * sizeof(linux_gid_t))))
+     return error;
+ 
+   p->p_retval[0] = ngrp;
+   return (0);
+ }
\end{verbatim}

>Release-Note:
>Audit-Trail:
State-Changed-From-To: open->closed 
State-Changed-By: sos 
State-Changed-When: Wed Dec 30 12:57:06 PST 1998 
State-Changed-Why:  
Patch comitted. 


Responsible-Changed-From-To: freebsd-bugs->sos 
Responsible-Changed-By: sos 
Responsible-Changed-When: Wed Dec 30 12:57:06 PST 1998 
Responsible-Changed-Why:  
I'm the linuxulator guy. 
>Unformatted:
