linux_uid16.c revision 82745
182745Smarcel/*- 282745Smarcel * Copyright (c) 2001 The FreeBSD Project 382745Smarcel * All rights reserved. 482745Smarcel * 582745Smarcel * Redistribution and use in source and binary forms, with or without 682745Smarcel * modification, are permitted provided that the following conditions 782745Smarcel * are met: 882745Smarcel * 1. Redistributions of source code must retain the above copyright 982745Smarcel * notice, this list of conditions and the following disclaimer. 1082745Smarcel * 2. Redistributions in binary form must reproduce the above copyright 1182745Smarcel * notice, this list of conditions and the following disclaimer in the 1282745Smarcel * documentation and/or other materials provided with the distribution. 1382745Smarcel * 1482745Smarcel * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 1582745Smarcel * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1682745Smarcel * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 1782745Smarcel * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 1882745Smarcel * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 1982745Smarcel * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2082745Smarcel * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2182745Smarcel * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2282745Smarcel * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2382745Smarcel * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2482745Smarcel * SUCH DAMAGE. 2582745Smarcel * 2682745Smarcel * $FreeBSD: head/sys/compat/linux/linux_uid16.c 82745 2001-09-01 18:11:45Z marcel $ 2782745Smarcel */ 2882745Smarcel 2982745Smarcel#include "opt_compat.h" 3082745Smarcel 3182745Smarcel#include <sys/param.h> 3282745Smarcel#include <sys/systm.h> 3382745Smarcel#include <sys/proc.h> 3482745Smarcel#include <sys/sysproto.h> 3582745Smarcel 3682745Smarcel#include <machine/../linux/linux.h> 3782745Smarcel#include <machine/../linux/linux_proto.h> 3882745Smarcel#include <compat/linux/linux_util.h> 3982745Smarcel 4082745SmarcelDUMMY(setfsuid16); 4182745SmarcelDUMMY(setfsgid16); 4282745SmarcelDUMMY(getresuid16); 4382745SmarcelDUMMY(getresgid16); 4482745Smarcel 4582745Smarcelint 4682745Smarcellinux_chown16(struct proc *p, struct linux_chown16_args *args) 4782745Smarcel{ 4882745Smarcel struct chown_args bsd; 4982745Smarcel caddr_t sg; 5082745Smarcel 5182745Smarcel sg = stackgap_init(); 5282745Smarcel CHECKALTEXIST(p, &sg, args->path); 5382745Smarcel 5482745Smarcel#ifdef DEBUG 5582745Smarcel if (ldebug(chown16)) 5682745Smarcel printf(ARGS(chown16, "%s, %d, %d"), args->path, args->uid, 5782745Smarcel args->gid); 5882745Smarcel#endif 5982745Smarcel 6082745Smarcel bsd.path = args->path; 6182745Smarcel bsd.uid = args->uid; 6282745Smarcel bsd.gid = args->gid; 6382745Smarcel return (chown(p, &bsd)); 6482745Smarcel} 6582745Smarcel 6682745Smarcelint 6782745Smarcellinux_lchown16(struct proc *p, struct linux_lchown16_args *args) 6882745Smarcel{ 6982745Smarcel struct lchown_args bsd; 7082745Smarcel caddr_t sg; 7182745Smarcel 7282745Smarcel sg = stackgap_init(); 7382745Smarcel CHECKALTEXIST(p, &sg, args->path); 7482745Smarcel 7582745Smarcel#ifdef DEBUG 7682745Smarcel if (ldebug(lchown16)) 7782745Smarcel printf(ARGS(lchown16, "%s, %d, %d"), args->path, args->uid, 7882745Smarcel args->gid); 7982745Smarcel#endif 8082745Smarcel 8182745Smarcel bsd.path = args->path; 8282745Smarcel bsd.uid = args->uid; 8382745Smarcel bsd.gid = args->gid; 8482745Smarcel return (lchown(p, &bsd)); 8582745Smarcel} 8682745Smarcel 8782745Smarcelint 8882745Smarcellinux_setgroups16(struct proc *p, struct linux_setgroups16_args *args) 8982745Smarcel{ 9082745Smarcel struct ucred *newcred, *oldcred; 9182745Smarcel l_gid16_t linux_gidset[NGROUPS]; 9282745Smarcel gid_t *bsd_gidset; 9382745Smarcel int ngrp, error; 9482745Smarcel 9582745Smarcel#ifdef DEBUG 9682745Smarcel if (ldebug(setgroups16)) 9782745Smarcel printf(ARGS(setgroups16, "%d, *"), args->gidsetsize); 9882745Smarcel#endif 9982745Smarcel 10082745Smarcel ngrp = args->gidsetsize; 10182745Smarcel oldcred = p->p_ucred; 10282745Smarcel 10382745Smarcel /* 10482745Smarcel * cr_groups[0] holds egid. Setting the whole set from 10582745Smarcel * the supplied set will cause egid to be changed too. 10682745Smarcel * Keep cr_groups[0] unchanged to prevent that. 10782745Smarcel */ 10882745Smarcel 10982745Smarcel if ((error = suser_xxx(oldcred, NULL, PRISON_ROOT)) != 0) 11082745Smarcel return (error); 11182745Smarcel 11282745Smarcel if (ngrp >= NGROUPS) 11382745Smarcel return (EINVAL); 11482745Smarcel 11582745Smarcel newcred = crdup(oldcred); 11682745Smarcel if (ngrp > 0) { 11782745Smarcel error = copyin((caddr_t)args->gidset, linux_gidset, 11882745Smarcel ngrp * sizeof(l_gid16_t)); 11982745Smarcel if (error) 12082745Smarcel return (error); 12182745Smarcel 12282745Smarcel newcred->cr_ngroups = ngrp + 1; 12382745Smarcel 12482745Smarcel bsd_gidset = newcred->cr_groups; 12582745Smarcel ngrp--; 12682745Smarcel while (ngrp >= 0) { 12782745Smarcel bsd_gidset[ngrp + 1] = linux_gidset[ngrp]; 12882745Smarcel ngrp--; 12982745Smarcel } 13082745Smarcel } 13182745Smarcel else 13282745Smarcel newcred->cr_ngroups = 1; 13382745Smarcel 13482745Smarcel setsugid(p); 13582745Smarcel p->p_ucred = newcred; 13682745Smarcel crfree(oldcred); 13782745Smarcel return (0); 13882745Smarcel} 13982745Smarcel 14082745Smarcelint 14182745Smarcellinux_getgroups16(struct proc *p, struct linux_getgroups16_args *args) 14282745Smarcel{ 14382745Smarcel struct ucred *cred; 14482745Smarcel l_gid16_t linux_gidset[NGROUPS]; 14582745Smarcel gid_t *bsd_gidset; 14682745Smarcel int bsd_gidsetsz, ngrp, error; 14782745Smarcel 14882745Smarcel#ifdef DEBUG 14982745Smarcel if (ldebug(getgroups16)) 15082745Smarcel printf(ARGS(getgroups16, "%d, *"), args->gidsetsize); 15182745Smarcel#endif 15282745Smarcel 15382745Smarcel cred = p->p_ucred; 15482745Smarcel bsd_gidset = cred->cr_groups; 15582745Smarcel bsd_gidsetsz = cred->cr_ngroups - 1; 15682745Smarcel 15782745Smarcel /* 15882745Smarcel * cr_groups[0] holds egid. Returning the whole set 15982745Smarcel * here will cause a duplicate. Exclude cr_groups[0] 16082745Smarcel * to prevent that. 16182745Smarcel */ 16282745Smarcel 16382745Smarcel if ((ngrp = args->gidsetsize) == 0) { 16482745Smarcel p->p_retval[0] = bsd_gidsetsz; 16582745Smarcel return (0); 16682745Smarcel } 16782745Smarcel 16882745Smarcel if (ngrp < bsd_gidsetsz) 16982745Smarcel return (EINVAL); 17082745Smarcel 17182745Smarcel ngrp = 0; 17282745Smarcel while (ngrp < bsd_gidsetsz) { 17382745Smarcel linux_gidset[ngrp] = bsd_gidset[ngrp + 1]; 17482745Smarcel ngrp++; 17582745Smarcel } 17682745Smarcel 17782745Smarcel error = copyout(linux_gidset, (caddr_t)args->gidset, 17882745Smarcel ngrp * sizeof(l_gid16_t)); 17982745Smarcel if (error) 18082745Smarcel return (error); 18182745Smarcel 18282745Smarcel p->p_retval[0] = ngrp; 18382745Smarcel return (0); 18482745Smarcel} 18582745Smarcel 18682745Smarcel/* 18782745Smarcel * The FreeBSD native getgid(2) and getuid(2) also modify p->p_retval[1] 18882745Smarcel * when COMPAT_43 or COMPAT_SUNOS is defined. This globbers registers that 18982745Smarcel * are assumed to be preserved. The following lightweight syscalls fixes 19082745Smarcel * this. See also linux_getpid(2), linux_getgid(2) and linux_getuid(2) in 19182745Smarcel * linux_misc.c 19282745Smarcel * 19382745Smarcel * linux_getgid16() - MP SAFE 19482745Smarcel * linux_getuid16() - MP SAFE 19582745Smarcel */ 19682745Smarcel 19782745Smarcelint 19882745Smarcellinux_getgid16(struct proc *p, struct linux_getgid16_args *args) 19982745Smarcel{ 20082745Smarcel p->p_retval[0] = p->p_ucred->cr_rgid; 20182745Smarcel return (0); 20282745Smarcel} 20382745Smarcel 20482745Smarcelint 20582745Smarcellinux_getuid16(struct proc *p, struct linux_getuid16_args *args) 20682745Smarcel{ 20782745Smarcel p->p_retval[0] = p->p_ucred->cr_ruid; 20882745Smarcel return (0); 20982745Smarcel} 21082745Smarcel 21182745Smarcelint 21282745Smarcellinux_getegid16(struct proc *p, struct linux_getegid16_args *args) 21382745Smarcel{ 21482745Smarcel struct getegid_args bsd; 21582745Smarcel 21682745Smarcel return (getegid(p, &bsd)); 21782745Smarcel} 21882745Smarcel 21982745Smarcelint 22082745Smarcellinux_geteuid16(struct proc *p, struct linux_geteuid16_args *args) 22182745Smarcel{ 22282745Smarcel struct geteuid_args bsd; 22382745Smarcel 22482745Smarcel return (geteuid(p, &bsd)); 22582745Smarcel} 22682745Smarcel 22782745Smarcelint 22882745Smarcellinux_setgid16(struct proc *p, struct linux_setgid16_args *args) 22982745Smarcel{ 23082745Smarcel struct setgid_args bsd; 23182745Smarcel 23282745Smarcel bsd.gid = args->gid; 23382745Smarcel return (setgid(p, &bsd)); 23482745Smarcel} 23582745Smarcel 23682745Smarcelint 23782745Smarcellinux_setuid16(struct proc *p, struct linux_setuid16_args *args) 23882745Smarcel{ 23982745Smarcel struct setuid_args bsd; 24082745Smarcel 24182745Smarcel bsd.uid = args->uid; 24282745Smarcel return (setuid(p, &bsd)); 24382745Smarcel} 24482745Smarcel 24582745Smarcelint 24682745Smarcellinux_setregid16(struct proc *p, struct linux_setregid16_args *args) 24782745Smarcel{ 24882745Smarcel struct setregid_args bsd; 24982745Smarcel 25082745Smarcel bsd.rgid = args->rgid; 25182745Smarcel bsd.egid = args->egid; 25282745Smarcel return (setregid(p, &bsd)); 25382745Smarcel} 25482745Smarcel 25582745Smarcelint 25682745Smarcellinux_setreuid16(struct proc *p, struct linux_setreuid16_args *args) 25782745Smarcel{ 25882745Smarcel struct setreuid_args bsd; 25982745Smarcel 26082745Smarcel bsd.ruid = args->ruid; 26182745Smarcel bsd.euid = args->euid; 26282745Smarcel return (setreuid(p, &bsd)); 26382745Smarcel} 26482745Smarcel 26582745Smarcelint 26682745Smarcellinux_setresgid16(struct proc *p, struct linux_setresgid16_args *args) 26782745Smarcel{ 26882745Smarcel struct setresgid_args bsd; 26982745Smarcel 27082745Smarcel bsd.rgid = args->rgid; 27182745Smarcel bsd.egid = args->egid; 27282745Smarcel bsd.sgid = args->sgid; 27382745Smarcel return (setresgid(p, &bsd)); 27482745Smarcel} 27582745Smarcel 27682745Smarcelint 27782745Smarcellinux_setresuid16(struct proc *p, struct linux_setresuid16_args *args) 27882745Smarcel{ 27982745Smarcel struct setresuid_args bsd; 28082745Smarcel 28182745Smarcel bsd.ruid = args->ruid; 28282745Smarcel bsd.euid = args->euid; 28382745Smarcel bsd.suid = args->suid; 28482745Smarcel return (setresuid(p, &bsd)); 28582745Smarcel} 286