Skip to content

Commit 4c40c50

Browse files
authored
Add getgroups and setgroups (#619)
1 parent 3665232 commit 4c40c50

File tree

17 files changed

+280
-29
lines changed

17 files changed

+280
-29
lines changed

libc/calls/calls.h

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -98,9 +98,10 @@ int fork(void);
9898
int fsync(int);
9999
int ftruncate(int, int64_t);
100100
int getdomainname(char *, size_t);
101-
int getegid(void) nosideeffect;
102-
int geteuid(void) nosideeffect;
103-
int getgid(void) nosideeffect;
101+
uint32_t getegid(void) nosideeffect;
102+
uint32_t geteuid(void) nosideeffect;
103+
uint32_t getgid(void) nosideeffect;
104+
int getgroups(int size, uint32_t list[]);
104105
int gethostname(char *, size_t);
105106
int getloadavg(double *, int);
106107
int getpgid(int) libcesque;
@@ -112,7 +113,7 @@ int getresgid(uint32_t *, uint32_t *, uint32_t *);
112113
int getresuid(uint32_t *, uint32_t *, uint32_t *);
113114
int getsid(int) nosideeffect libcesque;
114115
int gettid(void) libcesque;
115-
int getuid(void) libcesque;
116+
uint32_t getuid(void) libcesque;
116117
int sys_iopl(int);
117118
int ioprio_get(int, int);
118119
int ioprio_set(int, int, int);
@@ -163,6 +164,7 @@ int seteuid(uint32_t);
163164
int setfsgid(int);
164165
int setfsuid(int);
165166
int setgid(int);
167+
int setgroups(size_t size, const uint32_t list[]);
166168
int setpgid(int, int);
167169
int setpgrp(void);
168170
int setpriority(int, unsigned, int);

libc/calls/getegid.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,22 +17,22 @@
1717
│ PERFORMANCE OF THIS SOFTWARE. │
1818
╚─────────────────────────────────────────────────────────────────────────────*/
1919
#include "libc/calls/calls.h"
20-
#include "libc/intrin/strace.internal.h"
2120
#include "libc/calls/syscall-sysv.internal.h"
2221
#include "libc/dce.h"
22+
#include "libc/intrin/strace.internal.h"
2323
#include "libc/runtime/runtime.h"
2424

2525
/**
2626
* Returns effective group ID of calling process.
2727
* @return group id
2828
*/
29-
int getegid(void) {
30-
int rc;
29+
uint32_t getegid(void) {
30+
uint32_t rc;
3131
if (!IsWindows()) {
3232
rc = sys_getegid();
3333
} else {
3434
rc = getgid();
3535
}
36-
STRACE("%s() → %d% m", "getegid", rc);
36+
STRACE("%s() → %u% m", "getegid", rc);
3737
return rc;
3838
}

libc/calls/geteuid.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,21 +17,21 @@
1717
│ PERFORMANCE OF THIS SOFTWARE. │
1818
╚─────────────────────────────────────────────────────────────────────────────*/
1919
#include "libc/calls/calls.h"
20-
#include "libc/intrin/strace.internal.h"
2120
#include "libc/calls/syscall-sysv.internal.h"
2221
#include "libc/dce.h"
22+
#include "libc/intrin/strace.internal.h"
2323

2424
/**
2525
* Returns effective user ID of calling process.
2626
* @return user id
2727
*/
28-
int geteuid(void) {
29-
int rc;
28+
uint32_t geteuid(void) {
29+
uint32_t rc;
3030
if (!IsWindows()) {
3131
rc = sys_geteuid();
3232
} else {
3333
rc = getuid();
3434
}
35-
STRACE("%s() → %d% m", "geteuid", rc);
35+
STRACE("%s() → %u% m", "geteuid", rc);
3636
return rc;
3737
}

libc/calls/getgroups.c

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
2+
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
3+
╞══════════════════════════════════════════════════════════════════════════════╡
4+
│ Copyright 2020 Justine Alexandra Roberts Tunney │
5+
│ │
6+
│ Permission to use, copy, modify, and/or distribute this software for │
7+
│ any purpose with or without fee is hereby granted, provided that the │
8+
│ above copyright notice and this permission notice appear in all copies. │
9+
│ │
10+
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
11+
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
12+
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
13+
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
14+
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
15+
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
16+
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
17+
│ PERFORMANCE OF THIS SOFTWARE. │
18+
╚─────────────────────────────────────────────────────────────────────────────*/
19+
#include "libc/calls/calls.h"
20+
#include "libc/calls/groups.internal.h"
21+
#include "libc/dce.h"
22+
#include "libc/intrin/asan.internal.h"
23+
#include "libc/intrin/describeflags.internal.h"
24+
#include "libc/intrin/strace.internal.h"
25+
#include "libc/sysv/errfuns.h"
26+
27+
/**
28+
* Get list of supplementary group IDs
29+
*
30+
* @param size - maximum number of items that can be stored in list
31+
* @param list - buffer to store output gid_t
32+
* @return -1 w/ EFAULT
33+
*/
34+
int getgroups(int size, uint32_t list[]) {
35+
int rc;
36+
if (IsAsan() && size && !__asan_is_valid(list, size * sizeof(list[0]))) {
37+
rc = efault();
38+
} else if (IsLinux() || IsNetbsd() || IsOpenbsd() || IsFreebsd() || IsXnu()) {
39+
rc = sys_getgroups(size, list);
40+
} else {
41+
rc = enosys();
42+
}
43+
STRACE("getgroups(%d, %s) → %d% m", size, DescribeGidList(rc, rc, list), rc);
44+
return rc;
45+
}

libc/calls/getuid.c

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,9 @@
1717
│ PERFORMANCE OF THIS SOFTWARE. │
1818
╚─────────────────────────────────────────────────────────────────────────────*/
1919
#include "libc/calls/calls.h"
20-
#include "libc/intrin/strace.internal.h"
2120
#include "libc/calls/syscall-sysv.internal.h"
2221
#include "libc/dce.h"
22+
#include "libc/intrin/strace.internal.h"
2323
#include "libc/macros.internal.h"
2424
#include "libc/nt/accounting.h"
2525
#include "libc/runtime/runtime.h"
@@ -50,15 +50,15 @@ static textwindows dontinline uint32_t GetUserNameHash(void) {
5050
* @asyncsignalsafe
5151
* @vforksafe
5252
*/
53-
int getuid(void) {
54-
int rc;
53+
uint32_t getuid(void) {
54+
uint32_t rc;
5555
if (!IsWindows()) {
5656
rc = sys_getuid();
5757
} else {
5858
rc = GetUserNameHash();
5959
}
6060

61-
STRACE("%s() → %d% m", "getuid", rc);
61+
STRACE("%s() → %u% m", "getuid", rc);
6262
return rc;
6363
}
6464

@@ -71,13 +71,13 @@ int getuid(void) {
7171
* @asyncsignalsafe
7272
* @vforksafe
7373
*/
74-
int getgid(void) {
75-
int rc;
74+
uint32_t getgid(void) {
75+
uint32_t rc;
7676
if (!IsWindows()) {
7777
rc = sys_getgid();
7878
} else {
7979
rc = GetUserNameHash();
8080
}
81-
STRACE("%s() → %d% m", "getgid", rc);
81+
STRACE("%s() → %u% m", "getgid", rc);
8282
return rc;
8383
}

libc/calls/groups.internal.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
#ifndef COSMOPOLITAN_LIBC_CALLS_GROUPS_INTERNAL_H_
2+
#define COSMOPOLITAN_LIBC_CALLS_GROUPS_INTERNAL_H_
3+
4+
#if !(__ASSEMBLER__ + __LINKER__ + 0)
5+
COSMOPOLITAN_C_START_
6+
7+
int sys_getgroups(int size, uint32_t list[]);
8+
int sys_setgroups(size_t size, uint32_t list[]);
9+
10+
const char *DescribeGidList(char[128], int, int, const uint32_t list[]);
11+
#define DescribeGidList(rc, length, gidlist) \
12+
DescribeGidList(alloca(128), rc, length, gidlist)
13+
14+
COSMOPOLITAN_C_END_
15+
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
16+
#endif /* COSMOPOLITAN_LIBC_CALLS_GROUPS_INTERNAL_H_ */

libc/calls/setgroups.c

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
2+
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
3+
╞══════════════════════════════════════════════════════════════════════════════╡
4+
│ Copyright 2020 Justine Alexandra Roberts Tunney │
5+
│ │
6+
│ Permission to use, copy, modify, and/or distribute this software for │
7+
│ any purpose with or without fee is hereby granted, provided that the │
8+
│ above copyright notice and this permission notice appear in all copies. │
9+
│ │
10+
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
11+
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
12+
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
13+
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
14+
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
15+
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
16+
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
17+
│ PERFORMANCE OF THIS SOFTWARE. │
18+
╚─────────────────────────────────────────────────────────────────────────────*/
19+
#include "libc/calls/calls.h"
20+
#include "libc/calls/groups.internal.h"
21+
#include "libc/dce.h"
22+
#include "libc/intrin/asan.internal.h"
23+
#include "libc/intrin/describeflags.internal.h"
24+
#include "libc/intrin/strace.internal.h"
25+
#include "libc/sysv/errfuns.h"
26+
27+
/**
28+
* Set list of supplementary group IDs
29+
*
30+
* @param size - number of items in list
31+
* @param list - input set of gid_t to set
32+
* @return -1 w/ EFAULT
33+
*/
34+
int setgroups(size_t size, const uint32_t list[]) {
35+
int rc;
36+
if (IsAsan() && size && !__asan_is_valid(list, size * sizeof(list[0]))) {
37+
rc = efault();
38+
} else if (IsLinux() || IsNetbsd() || IsOpenbsd() || IsFreebsd() || IsXnu()) {
39+
rc = sys_setgroups(size, list);
40+
} else {
41+
rc = enosys();
42+
}
43+
STRACE("setgroups(%u, %s) → %d% m", size, DescribeGidList(rc, size, list),
44+
rc);
45+
return rc;
46+
}

libc/intrin/describegidlist.c

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
2+
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
3+
╞══════════════════════════════════════════════════════════════════════════════╡
4+
│ Copyright 2021 Justine Alexandra Roberts Tunney │
5+
│ │
6+
│ Permission to use, copy, modify, and/or distribute this software for │
7+
│ any purpose with or without fee is hereby granted, provided that the │
8+
│ above copyright notice and this permission notice appear in all copies. │
9+
│ │
10+
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
11+
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
12+
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
13+
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
14+
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
15+
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
16+
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
17+
│ PERFORMANCE OF THIS SOFTWARE. │
18+
╚─────────────────────────────────────────────────────────────────────────────*/
19+
#include "libc/calls/groups.internal.h"
20+
#include "libc/dce.h"
21+
#include "libc/intrin/asan.internal.h"
22+
#include "libc/intrin/kprintf.h"
23+
#include "libc/intrin/popcnt.h"
24+
#include "libc/macros.internal.h"
25+
#include "libc/str/str.h"
26+
27+
#define N 128
28+
29+
const char *(DescribeGidList)(char buf[N], int rc, int size,
30+
const uint32_t list[]) {
31+
if ((rc == -1) || (size < 0)) return "n/a";
32+
if (!size) return "{}";
33+
if (!list) return "NULL";
34+
if ((!IsAsan() && kisdangerous(list)) ||
35+
(IsAsan() && !__asan_is_valid(list, size * sizeof(list[0])))) {
36+
ksnprintf(buf, N, "%p", list);
37+
return buf;
38+
}
39+
int i = 0, n = N;
40+
i += ksnprintf(buf + i, MAX(0, n - i), "{");
41+
unsigned c;
42+
for (c = 0; c < size && MAX(0, n - i) > 0; c++) {
43+
i += ksnprintf(buf + i, MAX(0, n - i), "%u, ", list[c]);
44+
}
45+
if (c == size) {
46+
if (buf[i - 1] == ' ') i--;
47+
if (buf[i - 1] == ',') i--;
48+
i += ksnprintf(buf + i, MAX(0, n - i), "}");
49+
}
50+
return buf;
51+
}

libc/isystem/grp.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#ifndef LIBC_ISYSTEM_GRP_H_
22
#define LIBC_ISYSTEM_GRP_H_
3+
#include "libc/calls/calls.h"
34
#include "third_party/musl/passwd.h"
45
#endif

libc/runtime/runtime.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,6 @@ int mprotect(void *, uint64_t, int) privileged;
8484
int msync(void *, size_t, int);
8585
void *sbrk(intptr_t);
8686
int brk(void *);
87-
int getgroups(int, uint32_t[]);
8887
long gethostid(void);
8988
int sethostid(long);
9089
char *getlogin(void);

0 commit comments

Comments
 (0)