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>