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
27116173Sobrien#include <sys/cdefs.h>
28116173Sobrien__FBSDID("$FreeBSD$");
29116173Sobrien
30156874Sru#include "opt_compat.h"
31246290Sdchagin#include "opt_kdtrace.h"
32156874Sru
33177785Skib#include <sys/fcntl.h>
3482745Smarcel#include <sys/param.h>
35246290Sdchagin#include <sys/kernel.h>
3694621Sjhb#include <sys/lock.h>
37102954Sbde#include <sys/malloc.h>
3894621Sjhb#include <sys/mutex.h>
39164033Srwatson#include <sys/priv.h>
4082745Smarcel#include <sys/proc.h>
41246290Sdchagin#include <sys/sdt.h>
42102814Siedowse#include <sys/syscallsubr.h>
4382745Smarcel#include <sys/sysproto.h>
44102954Sbde#include <sys/systm.h>
4582745Smarcel
46140214Sobrien#ifdef COMPAT_LINUX32
47140214Sobrien#include <machine/../linux32/linux.h>
48140214Sobrien#include <machine/../linux32/linux32_proto.h>
49140214Sobrien#else
5082745Smarcel#include <machine/../linux/linux.h>
5182745Smarcel#include <machine/../linux/linux_proto.h>
52133816Stjr#endif
53102954Sbde
54246290Sdchagin#include <compat/linux/linux_dtrace.h>
5582745Smarcel#include <compat/linux/linux_util.h>
5682745Smarcel
57246290Sdchagin/* DTrace init */
58246290SdchaginLIN_SDT_PROVIDER_DECLARE(LINUX_DTRACE);
59246290Sdchagin
60246290Sdchagin/**
61246290Sdchagin * DTrace probes in this module.
62246290Sdchagin */
63246290SdchaginLIN_SDT_PROBE_DEFINE3(uid16, linux_chown16, entry, "char *", "l_uid16_t",
64246290Sdchagin    "l_gid16_t");
65246290SdchaginLIN_SDT_PROBE_DEFINE1(uid16, linux_chown16, conv_path, "char *");
66246290SdchaginLIN_SDT_PROBE_DEFINE1(uid16, linux_chown16, return, "int");
67246290SdchaginLIN_SDT_PROBE_DEFINE3(uid16, linux_lchown16, entry, "char *", "l_uid16_t",
68246290Sdchagin    "l_gid16_t");
69246290SdchaginLIN_SDT_PROBE_DEFINE1(uid16, linux_lchown16, conv_path, "char *");
70246290SdchaginLIN_SDT_PROBE_DEFINE1(uid16, linux_lchown16, return, "int");
71246290SdchaginLIN_SDT_PROBE_DEFINE2(uid16, linux_setgroups16, entry, "l_uint", "l_gid16_t *");
72246290SdchaginLIN_SDT_PROBE_DEFINE1(uid16, linux_setgroups16, copyin_error, "int");
73246290SdchaginLIN_SDT_PROBE_DEFINE1(uid16, linux_setgroups16, priv_check_cred_error, "int");
74246290SdchaginLIN_SDT_PROBE_DEFINE1(uid16, linux_setgroups16, return, "int");
75246290SdchaginLIN_SDT_PROBE_DEFINE2(uid16, linux_getgroups16, entry, "l_uint", "l_gid16_t *");
76246290SdchaginLIN_SDT_PROBE_DEFINE1(uid16, linux_getgroups16, copyout_error, "int");
77246290SdchaginLIN_SDT_PROBE_DEFINE1(uid16, linux_getgroups16, return, "int");
78246290SdchaginLIN_SDT_PROBE_DEFINE0(uid16, linux_getgid16, entry);
79246290SdchaginLIN_SDT_PROBE_DEFINE1(uid16, linux_getgid16, return, "int");
80246290SdchaginLIN_SDT_PROBE_DEFINE0(uid16, linux_getuid16, entry);
81246290SdchaginLIN_SDT_PROBE_DEFINE1(uid16, linux_getuid16, return, "int");
82246290SdchaginLIN_SDT_PROBE_DEFINE0(uid16, linux_getegid16, entry);
83246290SdchaginLIN_SDT_PROBE_DEFINE1(uid16, linux_getegid16, return, "int");
84246290SdchaginLIN_SDT_PROBE_DEFINE0(uid16, linux_geteuid16, entry);
85246290SdchaginLIN_SDT_PROBE_DEFINE1(uid16, linux_geteuid16, return, "int");
86246290SdchaginLIN_SDT_PROBE_DEFINE1(uid16, linux_setgid16, entry, "l_gid16_t");
87246290SdchaginLIN_SDT_PROBE_DEFINE1(uid16, linux_setgid16, return, "int");
88246290SdchaginLIN_SDT_PROBE_DEFINE1(uid16, linux_setuid16, entry, "l_uid16_t");
89246290SdchaginLIN_SDT_PROBE_DEFINE1(uid16, linux_setuid16, return, "int");
90262056SavgLIN_SDT_PROBE_DEFINE2(uid16, linux_setregid16, entry, "l_gid16_t", "l_gid16_t");
91246290SdchaginLIN_SDT_PROBE_DEFINE1(uid16, linux_setregid16, return, "int");
92246290SdchaginLIN_SDT_PROBE_DEFINE2(uid16, linux_setreuid16, entry, "l_uid16_t", "l_uid16_t");
93246290SdchaginLIN_SDT_PROBE_DEFINE1(uid16, linux_setreuid16, return, "int");
94246290SdchaginLIN_SDT_PROBE_DEFINE3(uid16, linux_setresgid16, entry, "l_gid16_t", "l_gid16_t",
95246290Sdchagin    "l_gid16_t");
96246290SdchaginLIN_SDT_PROBE_DEFINE1(uid16, linux_setresgid16, return, "int");
97246290SdchaginLIN_SDT_PROBE_DEFINE3(uid16, linux_setresuid16, entry, "l_uid16_t", "l_uid16_t",
98246290Sdchagin    "l_uid16_t");
99246290SdchaginLIN_SDT_PROBE_DEFINE1(uid16, linux_setresuid16, return, "int");
100246290Sdchagin
10182745SmarcelDUMMY(setfsuid16);
10282745SmarcelDUMMY(setfsgid16);
10382745SmarcelDUMMY(getresuid16);
10482745SmarcelDUMMY(getresgid16);
10582745Smarcel
106102814Siedowse#define	CAST_NOCHG(x)	((x == 0xFFFF) ? -1 : x)
10784916Smarcel
10882745Smarcelint
10983366Sjulianlinux_chown16(struct thread *td, struct linux_chown16_args *args)
11082745Smarcel{
111102814Siedowse	char *path;
112102814Siedowse	int error;
11382745Smarcel
114102814Siedowse	LCONVPATHEXIST(td, args->path, &path);
11582745Smarcel
116246290Sdchagin	/*
117246290Sdchagin	 * The DTrace probes have to be after the LCONVPATHEXIST, as
118246290Sdchagin	 * LCONVPATHEXIST may return on its own and we do not want to
119246290Sdchagin	 * have a stray entry without the corresponding return.
120246290Sdchagin	 */
121246290Sdchagin	LIN_SDT_PROBE3(uid16, linux_chown16, entry, args->path, args->uid,
122246290Sdchagin	    args->gid);
123246290Sdchagin	LIN_SDT_PROBE1(uid16, linux_chown16, conv_path, path);
124246290Sdchagin
125102814Siedowse	error = kern_chown(td, path, UIO_SYSSPACE, CAST_NOCHG(args->uid),
126102814Siedowse	    CAST_NOCHG(args->gid));
127102814Siedowse	LFREEPATH(path);
128246290Sdchagin
129246290Sdchagin	LIN_SDT_PROBE1(uid16, linux_chown16, return, error);
130102814Siedowse	return (error);
13182745Smarcel}
13282745Smarcel
13382745Smarcelint
13483366Sjulianlinux_lchown16(struct thread *td, struct linux_lchown16_args *args)
13582745Smarcel{
136102814Siedowse	char *path;
137102814Siedowse	int error;
13882745Smarcel
139102814Siedowse	LCONVPATHEXIST(td, args->path, &path);
14082745Smarcel
141246290Sdchagin	/*
142246290Sdchagin	 * The DTrace probes have to be after the LCONVPATHEXIST, as
143246290Sdchagin	 * LCONVPATHEXIST may return on its own and we do not want to
144246290Sdchagin	 * have a stray entry without the corresponding return.
145246290Sdchagin	 */
146246290Sdchagin	LIN_SDT_PROBE3(uid16, linux_lchown16, entry, args->path, args->uid,
147246290Sdchagin	    args->gid);
148246290Sdchagin	LIN_SDT_PROBE1(uid16, linux_lchown16, conv_path, path);
149246290Sdchagin
150102814Siedowse	error = kern_lchown(td, path, UIO_SYSSPACE, CAST_NOCHG(args->uid),
151102814Siedowse	    CAST_NOCHG(args->gid));
152102814Siedowse	LFREEPATH(path);
153246290Sdchagin
154246290Sdchagin	LIN_SDT_PROBE1(uid16, linux_lchown16, return, error);
155102814Siedowse	return (error);
15682745Smarcel}
15782745Smarcel
15882745Smarcelint
15983366Sjulianlinux_setgroups16(struct thread *td, struct linux_setgroups16_args *args)
16082745Smarcel{
16182745Smarcel	struct ucred *newcred, *oldcred;
162194498Sbrooks	l_gid16_t *linux_gidset;
16382745Smarcel	gid_t *bsd_gidset;
16482745Smarcel	int ngrp, error;
16594621Sjhb	struct proc *p;
16682745Smarcel
167246290Sdchagin	LIN_SDT_PROBE2(uid16, linux_setgroups16, entry, args->gidsetsize,
168246290Sdchagin	    args->gidset);
16982745Smarcel
17082745Smarcel	ngrp = args->gidsetsize;
171246290Sdchagin	if (ngrp < 0 || ngrp >= ngroups_max + 1) {
172246290Sdchagin		LIN_SDT_PROBE1(uid16, linux_setgroups16, return, EINVAL);
17394621Sjhb		return (EINVAL);
174246290Sdchagin	}
175194498Sbrooks	linux_gidset = malloc(ngrp * sizeof(*linux_gidset), M_TEMP, M_WAITOK);
176111797Sdes	error = copyin(args->gidset, linux_gidset, ngrp * sizeof(l_gid16_t));
177226640Sbrueffer	if (error) {
178246290Sdchagin		LIN_SDT_PROBE1(uid16, linux_setgroups16, copyin_error, error);
179246290Sdchagin		LIN_SDT_PROBE1(uid16, linux_setgroups16, return, error);
180226640Sbrueffer		free(linux_gidset, M_TEMP);
18194621Sjhb		return (error);
182226640Sbrueffer	}
18394621Sjhb	newcred = crget();
18494621Sjhb	p = td->td_proc;
18594621Sjhb	PROC_LOCK(p);
186194498Sbrooks	oldcred = crcopysafe(p, newcred);
18782745Smarcel
18882745Smarcel	/*
18982745Smarcel	 * cr_groups[0] holds egid. Setting the whole set from
19082745Smarcel	 * the supplied set will cause egid to be changed too.
19182745Smarcel	 * Keep cr_groups[0] unchanged to prevent that.
19282745Smarcel	 */
19382745Smarcel
194170587Srwatson	if ((error = priv_check_cred(oldcred, PRIV_CRED_SETGROUPS, 0)) != 0) {
19594621Sjhb		PROC_UNLOCK(p);
19694621Sjhb		crfree(newcred);
197246290Sdchagin
198246290Sdchagin		LIN_SDT_PROBE1(uid16, linux_setgroups16, priv_check_cred_error,
199246290Sdchagin		    error);
200194498Sbrooks		goto out;
20194621Sjhb	}
20282745Smarcel
20382745Smarcel	if (ngrp > 0) {
20482745Smarcel		newcred->cr_ngroups = ngrp + 1;
20582745Smarcel
20682745Smarcel		bsd_gidset = newcred->cr_groups;
20782745Smarcel		ngrp--;
20882745Smarcel		while (ngrp >= 0) {
20982745Smarcel			bsd_gidset[ngrp + 1] = linux_gidset[ngrp];
21082745Smarcel			ngrp--;
21182745Smarcel		}
21282745Smarcel	}
21382745Smarcel	else
21482745Smarcel		newcred->cr_ngroups = 1;
21582745Smarcel
21683366Sjulian	setsugid(td->td_proc);
21794621Sjhb	p->p_ucred = newcred;
21894621Sjhb	PROC_UNLOCK(p);
21982745Smarcel	crfree(oldcred);
220194498Sbrooks	error = 0;
221194498Sbrooksout:
222194498Sbrooks	free(linux_gidset, M_TEMP);
223246290Sdchagin
224246290Sdchagin	LIN_SDT_PROBE1(uid16, linux_setgroups16, return, error);
225194498Sbrooks	return (error);
22682745Smarcel}
22782745Smarcel
22882745Smarcelint
22983366Sjulianlinux_getgroups16(struct thread *td, struct linux_getgroups16_args *args)
23082745Smarcel{
23182745Smarcel	struct ucred *cred;
232194498Sbrooks	l_gid16_t *linux_gidset;
23382745Smarcel	gid_t *bsd_gidset;
23482745Smarcel	int bsd_gidsetsz, ngrp, error;
23582745Smarcel
236246290Sdchagin	LIN_SDT_PROBE2(uid16, linux_getgroups16, entry, args->gidsetsize,
237246290Sdchagin	    args->gidset);
23882745Smarcel
23991406Sjhb	cred = td->td_ucred;
24082745Smarcel	bsd_gidset = cred->cr_groups;
24182745Smarcel	bsd_gidsetsz = cred->cr_ngroups - 1;
24282745Smarcel
24382745Smarcel	/*
24482745Smarcel	 * cr_groups[0] holds egid. Returning the whole set
24582745Smarcel	 * here will cause a duplicate. Exclude cr_groups[0]
24682745Smarcel	 * to prevent that.
24782745Smarcel	 */
24882745Smarcel
24982745Smarcel	if ((ngrp = args->gidsetsize) == 0) {
25083366Sjulian		td->td_retval[0] = bsd_gidsetsz;
251246290Sdchagin
252246290Sdchagin		LIN_SDT_PROBE1(uid16, linux_getgroups16, return, 0);
25382745Smarcel		return (0);
25482745Smarcel	}
25582745Smarcel
256246290Sdchagin	if (ngrp < bsd_gidsetsz) {
257246290Sdchagin		LIN_SDT_PROBE1(uid16, linux_getgroups16, return, EINVAL);
25882745Smarcel		return (EINVAL);
259246290Sdchagin	}
26082745Smarcel
26182745Smarcel	ngrp = 0;
262194498Sbrooks	linux_gidset = malloc(bsd_gidsetsz * sizeof(*linux_gidset),
263194498Sbrooks	    M_TEMP, M_WAITOK);
26482745Smarcel	while (ngrp < bsd_gidsetsz) {
26582745Smarcel		linux_gidset[ngrp] = bsd_gidset[ngrp + 1];
26682745Smarcel		ngrp++;
26782745Smarcel	}
26882745Smarcel
269111797Sdes	error = copyout(linux_gidset, args->gidset, ngrp * sizeof(l_gid16_t));
270194498Sbrooks	free(linux_gidset, M_TEMP);
271246290Sdchagin	if (error) {
272246290Sdchagin		LIN_SDT_PROBE1(uid16, linux_getgroups16, copyout_error, error);
273246290Sdchagin		LIN_SDT_PROBE1(uid16, linux_getgroups16, return, error);
27482745Smarcel		return (error);
275246290Sdchagin	}
27682745Smarcel
27783366Sjulian	td->td_retval[0] = ngrp;
278246290Sdchagin
279246290Sdchagin	LIN_SDT_PROBE1(uid16, linux_getgroups16, return, 0);
28082745Smarcel	return (0);
28182745Smarcel}
28282745Smarcel
28382745Smarcel/*
28483366Sjulian * The FreeBSD native getgid(2) and getuid(2) also modify td->td_retval[1]
285166944Snetchild * when COMPAT_43 is defined. This clobbers registers that are assumed to
286166944Snetchild * be preserved. The following lightweight syscalls fixes this. See also
287166944Snetchild * linux_getpid(2), linux_getgid(2) and linux_getuid(2) in linux_misc.c
28882745Smarcel *
28982745Smarcel * linux_getgid16() - MP SAFE
29082745Smarcel * linux_getuid16() - MP SAFE
29182745Smarcel */
29282745Smarcel
29382745Smarcelint
29483366Sjulianlinux_getgid16(struct thread *td, struct linux_getgid16_args *args)
29582745Smarcel{
29683366Sjulian
297246290Sdchagin	LIN_SDT_PROBE0(uid16, linux_getgid16, entry);
298246290Sdchagin
29991406Sjhb	td->td_retval[0] = td->td_ucred->cr_rgid;
300246290Sdchagin
301246290Sdchagin	LIN_SDT_PROBE1(uid16, linux_getgid16, return, 0);
30282745Smarcel	return (0);
30382745Smarcel}
30482745Smarcel
30582745Smarcelint
30683366Sjulianlinux_getuid16(struct thread *td, struct linux_getuid16_args *args)
30782745Smarcel{
30883366Sjulian
309246290Sdchagin	LIN_SDT_PROBE0(uid16, linux_getuid16, entry);
310246290Sdchagin
31191406Sjhb	td->td_retval[0] = td->td_ucred->cr_ruid;
312246290Sdchagin
313246290Sdchagin	LIN_SDT_PROBE1(uid16, linux_getuid16, return, 0);
31482745Smarcel	return (0);
31582745Smarcel}
31682745Smarcel
31782745Smarcelint
31883366Sjulianlinux_getegid16(struct thread *td, struct linux_getegid16_args *args)
31982745Smarcel{
32082745Smarcel	struct getegid_args bsd;
321246290Sdchagin	int error;
32282745Smarcel
323246290Sdchagin	LIN_SDT_PROBE0(uid16, linux_getegid16, entry);
324246290Sdchagin
325246290Sdchagin	error = sys_getegid(td, &bsd);
326246290Sdchagin
327246290Sdchagin	LIN_SDT_PROBE1(uid16, linux_getegid16, return, error);
328246290Sdchagin	return (error);
32982745Smarcel}
33082745Smarcel
33182745Smarcelint
33283366Sjulianlinux_geteuid16(struct thread *td, struct linux_geteuid16_args *args)
33382745Smarcel{
33482745Smarcel	struct geteuid_args bsd;
335246290Sdchagin	int error;
33682745Smarcel
337246290Sdchagin	LIN_SDT_PROBE0(uid16, linux_geteuid16, entry);
338246290Sdchagin
339246290Sdchagin	error = sys_geteuid(td, &bsd);
340246290Sdchagin
341246290Sdchagin	LIN_SDT_PROBE1(uid16, linux_geteuid16, return, error);
342246290Sdchagin	return (error);
34382745Smarcel}
34482745Smarcel
34582745Smarcelint
34683366Sjulianlinux_setgid16(struct thread *td, struct linux_setgid16_args *args)
34782745Smarcel{
34882745Smarcel	struct setgid_args bsd;
349246290Sdchagin	int error;
35082745Smarcel
351246290Sdchagin	LIN_SDT_PROBE1(uid16, linux_setgid16, entry, args->gid);
352246290Sdchagin
35382745Smarcel	bsd.gid = args->gid;
354246290Sdchagin	error = sys_setgid(td, &bsd);
355246290Sdchagin
356246290Sdchagin	LIN_SDT_PROBE1(uid16, linux_setgid16, return, error);
357246290Sdchagin	return (error);
35882745Smarcel}
35982745Smarcel
36082745Smarcelint
36183366Sjulianlinux_setuid16(struct thread *td, struct linux_setuid16_args *args)
36282745Smarcel{
36382745Smarcel	struct setuid_args bsd;
364246290Sdchagin	int error;
36582745Smarcel
366246290Sdchagin	LIN_SDT_PROBE1(uid16, linux_setuid16, entry, args->uid);
367246290Sdchagin
36882745Smarcel	bsd.uid = args->uid;
369246290Sdchagin	error = sys_setuid(td, &bsd);
370246290Sdchagin
371246290Sdchagin	LIN_SDT_PROBE1(uid16, linux_setuid16, return, error);
372246290Sdchagin	return (error);
37382745Smarcel}
37482745Smarcel
37582745Smarcelint
37683366Sjulianlinux_setregid16(struct thread *td, struct linux_setregid16_args *args)
37782745Smarcel{
37882745Smarcel	struct setregid_args bsd;
379246290Sdchagin	int error;
38082745Smarcel
381246290Sdchagin	LIN_SDT_PROBE2(uid16, linux_setregid16, entry, args->rgid, args->egid);
382246290Sdchagin
38384916Smarcel	bsd.rgid = CAST_NOCHG(args->rgid);
38484916Smarcel	bsd.egid = CAST_NOCHG(args->egid);
385246290Sdchagin	error = sys_setregid(td, &bsd);
386246290Sdchagin
387246290Sdchagin	LIN_SDT_PROBE1(uid16, linux_setregid16, return, error);
388246290Sdchagin	return (error);
38982745Smarcel}
39082745Smarcel
39182745Smarcelint
39283366Sjulianlinux_setreuid16(struct thread *td, struct linux_setreuid16_args *args)
39382745Smarcel{
39482745Smarcel	struct setreuid_args bsd;
395246290Sdchagin	int error;
39682745Smarcel
397246290Sdchagin	LIN_SDT_PROBE2(uid16, linux_setreuid16, entry, args->ruid, args->euid);
398246290Sdchagin
39984916Smarcel	bsd.ruid = CAST_NOCHG(args->ruid);
40084916Smarcel	bsd.euid = CAST_NOCHG(args->euid);
401246290Sdchagin	error = sys_setreuid(td, &bsd);
402246290Sdchagin
403246290Sdchagin	LIN_SDT_PROBE1(uid16, linux_setreuid16, return, error);
404246290Sdchagin	return (error);
40582745Smarcel}
40682745Smarcel
40782745Smarcelint
40883366Sjulianlinux_setresgid16(struct thread *td, struct linux_setresgid16_args *args)
40982745Smarcel{
41082745Smarcel	struct setresgid_args bsd;
411246290Sdchagin	int error;
41282745Smarcel
413246290Sdchagin	LIN_SDT_PROBE3(uid16, linux_setresgid16, entry, args->rgid, args->egid,
414246290Sdchagin	    args->sgid);
415246290Sdchagin
41684916Smarcel	bsd.rgid = CAST_NOCHG(args->rgid);
41784916Smarcel	bsd.egid = CAST_NOCHG(args->egid);
41884916Smarcel	bsd.sgid = CAST_NOCHG(args->sgid);
419246290Sdchagin	error = sys_setresgid(td, &bsd);
420246290Sdchagin
421246290Sdchagin	LIN_SDT_PROBE1(uid16, linux_setresgid16, return, error);
422246290Sdchagin	return (error);
42382745Smarcel}
42482745Smarcel
42582745Smarcelint
42683366Sjulianlinux_setresuid16(struct thread *td, struct linux_setresuid16_args *args)
42782745Smarcel{
42882745Smarcel	struct setresuid_args bsd;
429246290Sdchagin	int error;
43082745Smarcel
431246290Sdchagin	LIN_SDT_PROBE3(uid16, linux_setresuid16, entry, args->ruid, args->euid,
432246290Sdchagin	    args->suid);
433246290Sdchagin
43484916Smarcel	bsd.ruid = CAST_NOCHG(args->ruid);
43584916Smarcel	bsd.euid = CAST_NOCHG(args->euid);
43684916Smarcel	bsd.suid = CAST_NOCHG(args->suid);
437246290Sdchagin	error = sys_setresuid(td, &bsd);
438246290Sdchagin
439246290Sdchagin	LIN_SDT_PROBE1(uid16, linux_setresuid16, return, error);
440246290Sdchagin	return (error);
44182745Smarcel}
442