[LTP] [PATCH] syscalls/setgroups: fix implicit SETGROUPS parameter casting

Stanislav Kholmanskikh
2013-08-16T07:11:18Z

One of parameters to setgroups() syscall is (gid_t *) pointer.
If TST_USE_COMPAT16_VSYSCALL is defined a pointer to GID_T is passed
instead (and sizeof(GID_T) < sizeof(gid_t)). It's not safe and
can result in unaligned access (and SIGBUS) on several platforms.

Signed-off-by: Stanislav Kholmanskikh <stanislav.kholmanskikh@oracle.com>
---
testcases/kernel/syscalls/setgroups/compat_16.h | 22 +++++++++++++++++++-
testcases/kernel/syscalls/setgroups/setgroups04.c | 6 ++++-
2 files changed, 25 insertions(+), 3 deletions(-)

diff --git a/testcases/kernel/syscalls/setgroups/compat_16.h b/testcases/kernel/syscalls/setgroups/compat_16.h
index 0de4e78..35723d6 100644
--- a/testcases/kernel/syscalls/setgroups/compat_16.h
+++ b/testcases/kernel/syscalls/setgroups/compat_16.h
@@ -32,9 +32,27 @@ extern void cleanup(void);
#ifdef TST_USE_COMPAT16_SYSCALL

long
-SETGROUPS(size_t gidsetsize, GID_T *list)
+SETGROUPS(size_t gidsetsize, GID_T *list16)
{
- return ltp_syscall(__NR_setgroups, gidsetsize, list);
+ int r;
+ int i;
+
+ gid_t *list32;
+
+ list32 = calloc(gidsetsize, sizeof(gid_t));
+ if (list32 == NULL)
+ tst_brkm(TBROK | TERRNO, NULL,
+ "calloc failed to allocate %zu bytes at %s:%d",
+ gidsetsize * sizeof(gid_t),
+ __FILE__, __LINE__);
+
+ for (i = 0; i < gidsetsize; i++)
+ list32[i] = list16[i];
+
+ r = ltp_syscall(__NR_setgroups, gidsetsize, list32);
+
+ free(list32);
+ return r;
}

int
diff --git a/testcases/kernel/syscalls/setgroups/setgroups04.c b/testcases/kernel/syscalls/setgroups/setgroups04.c
index 5932b4e..42ddda2 100644
--- a/testcases/kernel/syscalls/setgroups/setgroups04.c
+++ b/testcases/kernel/syscalls/setgroups/setgroups04.c
@@ -111,7 +111,11 @@ int main(int ac, char **av)
* verify that it fails with -1 return value and
* sets appropriate errno.
*/
- TEST(SETGROUPS(gidsetsize, sbrk(0)));
+#ifdef TST_USE_COMPAT16_SYSCALL
+ TEST(ltp_syscall(__NR_setgroups, gidsetsize, sbrk(0)));
+#else
+ TEST(setgroups(gidsetsize, sbrk(0)));
+#endif

if (TEST_RETURN != -1) {
tst_resm(TFAIL, "setgroups() returned %ld, "
--
1.7.1

------------------------------------------------------------------------------
Get 100% visibility into Java/.NET code with AppDynamics Lite!
It's a free troubleshooting tool designed for production.
Get down to code-level detail for bottlenecks, with <2% overhead.
Download for free and get started troubleshooting in minutes.