1 // Copyright 2019 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
4 
5 //go:build linux
6 
7 #ifndef _GNU_SOURCE // setres[ug]id() API.
8 #define _GNU_SOURCE
9 #endif
10 
11 #include <grp.h>
12 #include <sys/types.h>
13 #include <unistd.h>
14 #include <errno.h>
15 #include "libcgo.h"
16 
17 /*
18  * Assumed POSIX compliant libc system call wrappers. For linux, the
19  * glibc/nptl/setxid mechanism ensures that POSIX semantics are
20  * honored for all pthreads (by default), and this in turn with cgo
21  * ensures that all Go threads launched with cgo are kept in sync for
22  * these function calls.
23  */
24 
25 // argset_t matches runtime/cgocall.go:argset.
26 typedef struct {
27 	uintptr_t* args;
28 	uintptr_t retval;
29 } argset_t;
30 
31 // libc backed posix-compliant syscalls.
32 
33 #define SET_RETVAL(fn) \
34   uintptr_t ret = (uintptr_t) fn ; \
35   if (ret == (uintptr_t) -1) {	   \
36     x->retval = (uintptr_t) errno; \
37   } else                           \
38     x->retval = ret
39 
40 void
_cgo_libc_setegid(argset_t * x)41 _cgo_libc_setegid(argset_t* x) {
42 	SET_RETVAL(setegid((gid_t) x->args[0]));
43 }
44 
45 void
_cgo_libc_seteuid(argset_t * x)46 _cgo_libc_seteuid(argset_t* x) {
47 	SET_RETVAL(seteuid((uid_t) x->args[0]));
48 }
49 
50 void
_cgo_libc_setgid(argset_t * x)51 _cgo_libc_setgid(argset_t* x) {
52 	SET_RETVAL(setgid((gid_t) x->args[0]));
53 }
54 
55 void
_cgo_libc_setgroups(argset_t * x)56 _cgo_libc_setgroups(argset_t* x) {
57 	SET_RETVAL(setgroups((size_t) x->args[0], (const gid_t *) x->args[1]));
58 }
59 
60 void
_cgo_libc_setregid(argset_t * x)61 _cgo_libc_setregid(argset_t* x) {
62 	SET_RETVAL(setregid((gid_t) x->args[0], (gid_t) x->args[1]));
63 }
64 
65 void
_cgo_libc_setresgid(argset_t * x)66 _cgo_libc_setresgid(argset_t* x) {
67 	SET_RETVAL(setresgid((gid_t) x->args[0], (gid_t) x->args[1],
68 			     (gid_t) x->args[2]));
69 }
70 
71 void
_cgo_libc_setresuid(argset_t * x)72 _cgo_libc_setresuid(argset_t* x) {
73 	SET_RETVAL(setresuid((uid_t) x->args[0], (uid_t) x->args[1],
74 			     (uid_t) x->args[2]));
75 }
76 
77 void
_cgo_libc_setreuid(argset_t * x)78 _cgo_libc_setreuid(argset_t* x) {
79 	SET_RETVAL(setreuid((uid_t) x->args[0], (uid_t) x->args[1]));
80 }
81 
82 void
_cgo_libc_setuid(argset_t * x)83 _cgo_libc_setuid(argset_t* x) {
84 	SET_RETVAL(setuid((uid_t) x->args[0]));
85 }
86