aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKamil Rytarowski <n54@gmx.com>2018-01-18 11:17:35 +0000
committerKamil Rytarowski <n54@gmx.com>2018-01-18 11:17:35 +0000
commitf38deca5161b50037e177d4ad7cc7fa0d371f30b (patch)
treee5026c868f282a758f7d74a31a9733a77c293855
parent9da0b3ee35d1f5116d408c7b83a4215196a5dc92 (diff)
Add new NetBSD interceptors: getgrouplist(3) & getgroupmembership(3)
Summary: getgrouplist, getgroupmembership -- calculate group access list Sponsored by <The NetBSD Foundation> Reviewers: vitalybuka, joerg Reviewed By: vitalybuka Subscribers: llvm-commits, kubamracek, #sanitizers Tags: #sanitizers Differential Revision: https://reviews.llvm.org/D42064 git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@322836 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/sanitizer_common/sanitizer_common_interceptors.inc41
-rw-r--r--lib/sanitizer_common/sanitizer_platform_interceptors.h1
-rw-r--r--test/sanitizer_common/TestCases/NetBSD/getgrouplist.cc29
-rw-r--r--test/sanitizer_common/TestCases/NetBSD/getgroupmembership.cc30
4 files changed, 101 insertions, 0 deletions
diff --git a/lib/sanitizer_common/sanitizer_common_interceptors.inc b/lib/sanitizer_common/sanitizer_common_interceptors.inc
index 71e6aa8e3..f74aff774 100644
--- a/lib/sanitizer_common/sanitizer_common_interceptors.inc
+++ b/lib/sanitizer_common/sanitizer_common_interceptors.inc
@@ -6566,6 +6566,46 @@ INTERCEPTOR(int, faccessat, int fd, const char *path, int mode, int flags) {
#define INIT_FACCESSAT
#endif
+#if SANITIZER_INTERCEPT_GETGROUPLIST
+INTERCEPTOR(int, getgrouplist, const char *name, u32 basegid, u32 *groups,
+ int *ngroups) {
+ void *ctx;
+ int res;
+ COMMON_INTERCEPTOR_ENTER(ctx, getgrouplist, name, basegid, groups, ngroups);
+ if (name)
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1);
+ if (ngroups)
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, ngroups, sizeof(*ngroups));
+ res = REAL(getgrouplist)(name, basegid, groups, ngroups);
+ if (!res && groups && ngroups) {
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, groups, sizeof(*groups) * (*ngroups));
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ngroups, sizeof(*ngroups));
+ }
+ return res;
+}
+
+INTERCEPTOR(int, getgroupmembership, const char *name, u32 basegid, u32 *groups,
+ int maxgrp, int *ngroups) {
+ void *ctx;
+ int res;
+ COMMON_INTERCEPTOR_ENTER(ctx, getgroupmembership, name, basegid, groups, maxgrp, ngroups);
+ if (name)
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1);
+ res = REAL(getgroupmembership)(name, basegid, groups, maxgrp, ngroups);
+ if (!res && groups && ngroups) {
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, groups, sizeof(*groups) * (*ngroups));
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ngroups, sizeof(*ngroups));
+ }
+ return res;
+}
+
+#define INIT_GETGROUPLIST \
+ COMMON_INTERCEPT_FUNCTION(getgrouplist); \
+ COMMON_INTERCEPT_FUNCTION(getgroupmembership);
+#else
+#define INIT_GETGROUPLIST
+#endif
+
static void InitializeCommonInterceptors() {
static u64 metadata_mem[sizeof(MetadataHashMap) / sizeof(u64) + 1];
interceptor_metadata_map = new((void *)&metadata_mem) MetadataHashMap();
@@ -6784,6 +6824,7 @@ static void InitializeCommonInterceptors() {
INIT_GID_FROM_GROUP;
INIT_ACCESS;
INIT_FACCESSAT;
+ INIT_GETGROUPLIST;
#if SANITIZER_NETBSD
COMMON_INTERCEPT_FUNCTION(__libc_mutex_lock);
diff --git a/lib/sanitizer_common/sanitizer_platform_interceptors.h b/lib/sanitizer_common/sanitizer_platform_interceptors.h
index 1f992e810..bf37934ff 100644
--- a/lib/sanitizer_common/sanitizer_platform_interceptors.h
+++ b/lib/sanitizer_common/sanitizer_platform_interceptors.h
@@ -439,5 +439,6 @@
#define SANITIZER_INTERCEPT_GID_FROM_GROUP SI_NETBSD
#define SANITIZER_INTERCEPT_ACCESS SI_NETBSD
#define SANITIZER_INTERCEPT_FACCESSAT SI_NETBSD
+#define SANITIZER_INTERCEPT_GETGROUPLIST SI_NETBSD
#endif // #ifndef SANITIZER_PLATFORM_INTERCEPTORS_H
diff --git a/test/sanitizer_common/TestCases/NetBSD/getgrouplist.cc b/test/sanitizer_common/TestCases/NetBSD/getgrouplist.cc
new file mode 100644
index 000000000..49655542e
--- /dev/null
+++ b/test/sanitizer_common/TestCases/NetBSD/getgrouplist.cc
@@ -0,0 +1,29 @@
+// RUN: %clangxx -O0 -g %s -o %t && %run %t
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <grp.h>
+
+int main(void) {
+ gid_t *groups;
+ gid_t nobody;
+ int ngroups;
+
+ ngroups = sysconf(_SC_NGROUPS_MAX);
+ groups = (gid_t *)malloc(ngroups * sizeof(gid_t));
+ if (!groups)
+ exit(1);
+
+ if (gid_from_group("nobody", &nobody) == -1)
+ exit(1);
+
+ if (getgrouplist("nobody", nobody, groups, &ngroups))
+ exit(1);
+
+ if (groups && ngroups) {
+ free(groups);
+ exit(0);
+ }
+
+ return -1;
+}
diff --git a/test/sanitizer_common/TestCases/NetBSD/getgroupmembership.cc b/test/sanitizer_common/TestCases/NetBSD/getgroupmembership.cc
new file mode 100644
index 000000000..ee27ad6cf
--- /dev/null
+++ b/test/sanitizer_common/TestCases/NetBSD/getgroupmembership.cc
@@ -0,0 +1,30 @@
+// RUN: %clangxx -O0 -g %s -o %t && %run %t
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <grp.h>
+
+int main(void) {
+ gid_t *groups;
+ gid_t nobody;
+ int ngroups;
+ int maxgrp;
+
+ maxgrp = sysconf(_SC_NGROUPS_MAX);
+ groups = (gid_t *)malloc(maxgrp * sizeof(gid_t));
+ if (!groups)
+ exit(1);
+
+ if (gid_from_group("nobody", &nobody) == -1)
+ exit(1);
+
+ if (getgroupmembership("nobody", nobody, groups, maxgrp, &ngroups))
+ exit(1);
+
+ if (groups && ngroups) {
+ free(groups);
+ exit(0);
+ }
+
+ return -1;
+}