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>
