Hello, In testing against the 4.1 kernel, the syscall_sysctl testcase started failing even in the unconfined case. What the test program does is attempt to adjust the kernel.threads-max sysctl to be slightly larger and see if the operation succeeds by reading the value back out. It also attempts to save the original value and restore it. The test was failing because (in VMs at least) the default value chosen by the kernel for the kernel.threads-max setting was high enough that attempts to increase it would be ignored (likely to prevent too much use of kernel memory by threads), helpfully without any message being report to dmesg. Thus, the initial read of the current value would succeed, the write of that value + 1024 would appear to succeed, but then reading the value back out and comparing it to the expected value would fail, as it would still be the original value, not the expected new value.
This patch attempts to address this by first attempting to raise
the value, and if that does not appear to work, to then attempt
to lower it. It also refactors the code a bit by creating helper
functions to perform the actual sysctl(2) calls to make the code a
bit easier to read.
Nominated for 2.10 and 2.9.
---
tests/regression/apparmor/syscall_sysctl.c | 76 +++++++++++++++++++----------
1 file changed, 51 insertions(+), 25 deletions(-)
Index: b/tests/regression/apparmor/syscall_sysctl.c
===================================================================
--- a/tests/regression/apparmor/syscall_sysctl.c
+++ b/tests/regression/apparmor/syscall_sysctl.c
@@ -16,21 +16,44 @@
#include <string.h>
#define BUFSIZE 4096
+
+static int name[] = {CTL_KERN, KERN_MAX_THREADS};
+
+int read_max_threads(int *max_threads)
+{
+ size_t save_sz = sizeof(*max_threads);
+
+ if (sysctl(name, sizeof(name), max_threads, &save_sz, NULL, 0) == -1){
+ fprintf(stderr, "FAIL: sysctl read failed - %s\n",
+ strerror(errno));
+ return 1;
+ }
+ return 0;
+}
+
+int write_max_threads(int new_max_threads)
+{
+ size_t save_sz = sizeof(new_max_threads);
+
+ if (sysctl(name, sizeof(name), NULL, 0, &new_max_threads, save_sz) ==
-1){
+ fprintf(stderr, "FAIL: sysctl write failed - %s\n",
+ strerror(errno));
+ return 1;
+ }
+
+ return 0;
+}
+
int main(int argc, char *argv[])
{
int save_max_threads, new_max_threads, read_new_max_threads;
- size_t save_sz = sizeof(save_max_threads);
- int name[] = {CTL_KERN, KERN_MAX_THREADS};
int readonly = 0;
- if ((argc > 1) && strcmp(argv[1],"ro") == 0)
+ if ((argc > 1) && strcmp(argv[1],"ro") == 0)
readonly = 1;
- if (sysctl(name, sizeof(name), &save_max_threads, &save_sz, NULL, 0) ==
-1){
- fprintf(stderr, "FAIL: sysctl read failed - %s\n",
- strerror(errno));
+ if (read_max_threads(&save_max_threads) != 0)
return 1;
- }
/* printf("Kernel max threads (saved) is %d\n", save_max_threads); */
@@ -41,36 +64,39 @@ int main(int argc, char *argv[])
new_max_threads = save_max_threads + 1024;
- if (sysctl(name, sizeof(name), NULL, 0, &new_max_threads, save_sz) ==
-1){
- fprintf(stderr, "FAIL: sysctl write failed - %s\n",
- strerror(errno));
+ if (write_max_threads(new_max_threads) != 0)
return 1;
- }
- if (sysctl(name, sizeof(name), &read_new_max_threads, &save_sz, NULL,
0) == -1){
- fprintf(stderr, "FAIL: sysctl read failed - %s\n",
- strerror(errno));
+ if (read_max_threads(&read_new_max_threads) != 0)
return 1;
- }
/* printf("Kernel max threads (new) is %d\n", read_new_max_threads); */
if (read_new_max_threads != new_max_threads) {
- fprintf(stderr, "FAIL: read value does not match written
values\n");
- return 1;
+ /* the kernel possibly rejected our updated max threads
+ * as being too large; try decreasing max threads. */
+
+ new_max_threads = save_max_threads - 1024;
+
+ if (write_max_threads(new_max_threads) != 0)
+ return 1;
+
+ if (read_max_threads(&read_new_max_threads) != 0)
+ return 1;
+
+ /* printf("Kernel max threads (new, 2nd attempt) is %d\n",
read_new_max_threads); */
+
+ if (read_new_max_threads != new_max_threads) {
+ fprintf(stderr, "FAIL: read value does not match
written values\n");
+ return 1;
+ }
}
- if (sysctl(name, sizeof(name), NULL, 0, &save_max_threads, save_sz) ==
-1){
- fprintf(stderr, "FAIL: sysctl write failed - %s\n",
- strerror(errno));
+ if (write_max_threads(save_max_threads) != 0)
return 1;
- }
- if (sysctl(name, sizeof(name), &read_new_max_threads, &save_sz, NULL,
0) == -1){
- fprintf(stderr, "FAIL: sysctl read failed - %s\n",
- strerror(errno));
+ if (read_max_threads(&read_new_max_threads) != 0)
return 1;
- }
/* printf("Kernel max threads (saved) is %d\n", read_new_max_threads);*/
--
Steve Beattie
<[email protected]>
http://NxNW.org/~steve/
signature.asc
Description: Digital signature
-- AppArmor mailing list [email protected] Modify settings or unsubscribe at: https://lists.ubuntu.com/mailman/listinfo/apparmor
