[LTP] [PATCH] sbrk: add new case sbrk03

Li Wang liwang@redhat.com
Thu Jun 23 10:44:36 CEST 2016


Signed-off-by: Li Wang <liwang@redhat.com>
---
 runtest/ltplite                         |  1 +
 runtest/syscalls                        |  1 +
 testcases/kernel/syscalls/.gitignore    |  1 +
 testcases/kernel/syscalls/sbrk/sbrk03.c | 81 +++++++++++++++++++++++++++++++++
 4 files changed, 84 insertions(+)
 create mode 100644 testcases/kernel/syscalls/sbrk/sbrk03.c

diff --git a/runtest/ltplite b/runtest/ltplite
index 54df7e0..cbb0397 100644
--- a/runtest/ltplite
+++ b/runtest/ltplite
@@ -676,6 +676,7 @@ rmdir05 rmdir05
 
 sbrk01 sbrk01
 sbrk02 sbrk02
+sbrk03 sbrk03
 
 sched_get_priority_max01 sched_get_priority_max01
 sched_get_priority_max02 sched_get_priority_max02
diff --git a/runtest/syscalls b/runtest/syscalls
index 6af3dad..5b959ca 100644
--- a/runtest/syscalls
+++ b/runtest/syscalls
@@ -915,6 +915,7 @@ rt_sigsuspend01 rt_sigsuspend01
 
 sbrk01 sbrk01
 sbrk02 sbrk02
+sbrk03 sbrk03
 
 sched_get_priority_max01 sched_get_priority_max01
 sched_get_priority_max02 sched_get_priority_max02
diff --git a/testcases/kernel/syscalls/.gitignore b/testcases/kernel/syscalls/.gitignore
index 63fc261..2b222b1 100644
--- a/testcases/kernel/syscalls/.gitignore
+++ b/testcases/kernel/syscalls/.gitignore
@@ -759,6 +759,7 @@
 /rt_sigtimedwait/rt_sigtimedwait01
 /sbrk/sbrk01
 /sbrk/sbrk02
+/sbrk/sbrk03
 /sched_get_priority_max/sched_get_priority_max01
 /sched_get_priority_max/sched_get_priority_max02
 /sched_get_priority_min/sched_get_priority_min01
diff --git a/testcases/kernel/syscalls/sbrk/sbrk03.c b/testcases/kernel/syscalls/sbrk/sbrk03.c
new file mode 100644
index 0000000..bdc4995
--- /dev/null
+++ b/testcases/kernel/syscalls/sbrk/sbrk03.c
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2016 Linux Test Project.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ * DESCRIPTION
+ *
+ * Total s390 2^31 addr space is 0x80000000.
+ *
+ *     0x80000000 - 0x10000000 = 0x70000000
+ *
+ * 0x70000000 is a valid positive intptr_t and adding it to the current offset
+ * produces a valid uintptr_t without overflow (since the MSB being set is OK),
+ * but that is irrelevant for s390 since it has 31-bit pointers and not 32-bit
+ * pointers. Consequently, the brk syscall behaves incorrectly with the invalid
+ * address and changes the program break to the overflowed address. The glibc
+ * part of the implementation detects this overflow and returns a failure with
+ * ENOMEM, but does not reset the program break.
+ *
+ * So the bug is in sbrk as well as the brk syscall. brk() should validate the
+ * address being passed and return an error. sbrk() should not result in a brk
+ * call at all for an invalid address. One could argue in favour of fixing brk
+ * in glibc, but it should be the kernel since one could call the syscall
+ * directly without using the glibc entry points.
+ *
+ * The kernel part was fixed on v3.15 by commits:
+ *     473a06572fcd (s390/compat: convert system call wrappers to C part 02)
+ *
+ * Note:
+ *     The reproducer should be built(gcc -m31) in 32bit on s390 platform
+ *
+ */
+
+#include <stdio.h>
+#include <unistd.h>
+#include "tst_test.h"
+
+static void sbrk_test(void)
+{
+#if defined(__s390__) && __WORDSIZE == 32
+	void *ret1, *ret2;
+
+	/* set bkr to 0x10000000 */
+	tst_res(TINFO, "initial brk: %d", brk((void *)0x10000000));
+
+	/* add 0x10000000, up to total of 0x20000000 */
+	tst_res(TINFO, "sbrk increm: %p", sbrk(0x10000000));
+	ret1 = sbrk(0);
+
+	/* sbrk() returns -1 on s390, but still does overflowed brk() */
+	tst_res(TINFO, "sbrk increm: %p", sbrk(0x70000000));
+	ret2 = sbrk(0);
+
+	if (ret1 != ret2) {
+		tst_res(TFAIL, "Bug! sbrk: %p", ret2);
+		return;
+	}
+
+	tst_res(TPASS, "sbrk verify: %p", ret2);
+#else
+	tst_res(TCONF, "Only works in 32bit on s390 series system");
+#endif
+}
+
+static struct tst_test test = {
+	.tid = "sbrk03",
+	.test_all = sbrk_test,
+};
-- 
1.8.3.1



More information about the ltp mailing list