diff options
author | Kamil Rytarowski <n54@gmx.com> | 2018-01-18 11:17:35 +0000 |
---|---|---|
committer | Kamil Rytarowski <n54@gmx.com> | 2018-01-18 11:17:35 +0000 |
commit | f38deca5161b50037e177d4ad7cc7fa0d371f30b (patch) | |
tree | e5026c868f282a758f7d74a31a9733a77c293855 | |
parent | 9da0b3ee35d1f5116d408c7b83a4215196a5dc92 (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
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; +} |