Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 29 Dec 1998 06:15:07 -0800 (PST)
From:      marcel@scc.nl
To:        freebsd-gnats-submit@FreeBSD.ORG
Subject:   i386/9235: linux emu: {s|g}etgroups causing core dumps
Message-ID:  <199812291415.GAA03996@hub.freebsd.org>

next in thread | raw e-mail | index | archive | help

>Number:         9235
>Category:       i386
>Synopsis:       linux emu: {s|g}etgroups causing core dumps
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    freebsd-bugs
>State:          open
>Quarter:
>Keywords:
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Tue Dec 29 06:20:01 PST 1998
>Last-Modified:
>Originator:     Marcel Moolenaar
>Organization:
SCC vof
>Release:        -current
>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}

>Audit-Trail:
>Unformatted:

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-bugs" in the body of the message



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199812291415.GAA03996>