From 935f584f3d0278618cd15d2e7fc882494b8989df Mon Sep 17 00:00:00 2001 From: Nora Sandler Date: Mon, 26 Aug 2024 16:53:53 -0700 Subject: [PATCH] add noexec stack note and relevant tests; fixes #21 and #22 --- templates/stack_alignment_check.s.jinja | 7 ++-- test_framework/test_tests/test_programs.py | 8 +++++ .../unsigned_type_specifiers.c | 4 +-- .../valid/initialization/automatic_nested.c | 36 ++++++++----------- tests/chapter_4/valid/multi_short_circuit.c | 4 ++- tests/chapter_4/valid/precedence.c | 1 + .../stack_alignment_check_linux.s | 2 +- .../stack_alignment_check_osx.s | 1 - 8 files changed, 34 insertions(+), 29 deletions(-) diff --git a/templates/stack_alignment_check.s.jinja b/templates/stack_alignment_check.s.jinja index ff476b1f..725db9cf 100644 --- a/templates/stack_alignment_check.s.jinja +++ b/templates/stack_alignment_check.s.jinja @@ -1,6 +1,6 @@ {# macros #} {% set arg_operands=["%edi", "%esi", "%edx", "%ecx", "%r8d", "%r9d", "16(%rbp)", "24(%rbp)"] %} -{% macro alignment_check(fn_name, arg_count) %} +{% macro alignment_check(fn_name, arg_count) -%} {% set fn_label=id_prefix~fn_name %} .globl {{fn_label}} {{fn_label}}: @@ -30,9 +30,10 @@ call {{id_prefix}}exit{{plt_suffix}} popq %rbp retq -{% endmacro %} +{%- endmacro %} {# actual program starts here #} # generated from templates/{{ self._TemplateReference__context.name }} .text {{alignment_check("even_arguments", 8)}} -{{alignment_check("odd_arguments", 7)}} \ No newline at end of file +{{alignment_check("odd_arguments", 7)}} +{{execstack_note}} \ No newline at end of file diff --git a/test_framework/test_tests/test_programs.py b/test_framework/test_tests/test_programs.py index 25bc6cb4..1241aa13 100644 --- a/test_framework/test_tests/test_programs.py +++ b/test_framework/test_tests/test_programs.py @@ -66,6 +66,14 @@ def compile_and_run_sanitized(self, source_file: Path) -> None: "-O3", "-fsanitize=undefined", ] + if not basic.IS_OSX: + subproc_args.extend( + [ + # Linux only: executable stack should produce linker error (this catches missing execstack note in assembly test files) + "-Xlinker", + "--error-execstack", + ] + ) subproc_args.extend(build_compiler_args(source_file)) # compile it diff --git a/tests/chapter_12/valid/type_specifiers/unsigned_type_specifiers.c b/tests/chapter_12/valid/type_specifiers/unsigned_type_specifiers.c index 35dd2e97..38e0f274 100644 --- a/tests/chapter_12/valid/type_specifiers/unsigned_type_specifiers.c +++ b/tests/chapter_12/valid/type_specifiers/unsigned_type_specifiers.c @@ -30,7 +30,8 @@ int main(void) { } /* use unsigned type specifier in for loop - * we'll iterate through this loop 11 times before dropping below 0 and wrapping around + * we'll iterate through this loop 11 times before dropping below 0 and + * wrapping around */ int counter = 0; for (unsigned int index = 10; index < 4294967295U; index = index - 1) { @@ -43,4 +44,3 @@ int main(void) { return 0; } - diff --git a/tests/chapter_15/valid/initialization/automatic_nested.c b/tests/chapter_15/valid/initialization/automatic_nested.c index a373ebbc..4ad4929a 100644 --- a/tests/chapter_15/valid/initialization/automatic_nested.c +++ b/tests/chapter_15/valid/initialization/automatic_nested.c @@ -2,7 +2,7 @@ /* A fully initialized array of constants */ int test_simple(void) { - int arr[3][3] = { { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9 } }; + int arr[3][3] = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}}; // check the value of each element for (int i = 0; i < 3; i = i + 1) { @@ -13,7 +13,7 @@ int test_simple(void) { } } - return 1; // success + return 1; // success } /* A partially initialized array of constants. @@ -21,12 +21,11 @@ int test_simple(void) { * (including nested arrays) should be zeroed out. * */ int test_partial(void) { - // explicitly initialize only the first half of each array, // at each dimension int first_half_only[4][2][6] = { - {{1, 2, 3}}, - {{4, 5, 6}} + {{1, 2, 3}}, // first_half_only[0][0][0-2] + {{4, 5, 6}} // first_half_only[1][0][0-2] }; int expected = 1; @@ -34,7 +33,7 @@ int test_partial(void) { for (int j = 0; j < 2; j = j + 1) { for (int k = 0; k < 6; k = k + 1) { int val = first_half_only[i][j][k]; - if (i > 1 || j > 0 || k > 2 ) { + if (i > 1 || j > 0 || k > 2) { // this wasn't explicitly initialized, should be zero if (val) { return 0; @@ -49,15 +48,13 @@ int test_partial(void) { } } - return 1; // success + return 1; // success } - /* elements in a compound initializer may include non-constant expressions * and expressions of other types, which are converted to the right type * as if by assignment */ int test_non_constant_and_type_conversion(void) { - // first let's define some value (that can't be copy propagated // or constant-folded away in Part III) extern unsigned int three(void); @@ -66,8 +63,8 @@ int test_non_constant_and_type_conversion(void) { int *ptr = &negative_four; double arr[3][2] = { - { x, x / *ptr }, - { three() } + {x, x / *ptr}, + {three()}, }; if (arr[0][0] != 2000.0 || arr[0][1] != -500.0 || arr[1][0] != 3.0) { @@ -78,7 +75,7 @@ int test_non_constant_and_type_conversion(void) { return 0; } - return 1; // success + return 1; // success } // helper function for previous test @@ -89,20 +86,18 @@ unsigned int three(void) { /* Initializing an array must not corrupt other objects on the stack. */ long one = 1l; int test_preserve_stack(void) { - int i = -1; /* Initialize with expressions of long type - make sure they're truncated * before being copied into the array. * Also use an array of < 16 bytes so it's not 16-byte aligned, so there are * eightbytes that include both array elements and other values. - * Also leave last element uninitialized; in assembly, we should set it to zero without - * overwriting what follows + * Also leave last element uninitialized; in assembly, we should set it to + * zero without overwriting what follows */ - int arr[3][1] = { {one * 2l}, {one + three()} }; + int arr[3][1] = {{one * 2l}, {one + three()}}; unsigned int u = 2684366905; - if (i != -1) { return 0; } @@ -111,11 +106,11 @@ int test_preserve_stack(void) { return 0; } - if ( arr[0][0] != 2 || arr[1][0] != 4 || arr[2][0] != 0 ) { + if (arr[0][0] != 2 || arr[1][0] != 4 || arr[2][0] != 0) { return 0; } - return 1; // success + return 1; // success } int main(void) { @@ -135,6 +130,5 @@ int main(void) { return 4; } - return 0; // success + return 0; // success } - diff --git a/tests/chapter_4/valid/multi_short_circuit.c b/tests/chapter_4/valid/multi_short_circuit.c index edd0e89e..8d4912d9 100644 --- a/tests/chapter_4/valid/multi_short_circuit.c +++ b/tests/chapter_4/valid/multi_short_circuit.c @@ -1,5 +1,7 @@ #ifdef SUPPRESS_WARNINGS -#ifndef __clang__ +#ifdef __clang__ +#pragma clang diagnostic ignored "-Wlogical-op-parentheses" +#else #pragma GCC diagnostic ignored "-Wparentheses" #endif #endif diff --git a/tests/chapter_4/valid/precedence.c b/tests/chapter_4/valid/precedence.c index ebaad535..65eefabc 100644 --- a/tests/chapter_4/valid/precedence.c +++ b/tests/chapter_4/valid/precedence.c @@ -1,6 +1,7 @@ #ifdef SUPPRESS_WARNINGS #ifdef __clang__ #pragma clang diagnostic ignored "-Wconstant-logical-operand" +#pragma clang diagnostic ignored "-Wlogical-op-parentheses" #else #pragma GCC diagnostic ignored "-Wparentheses" #endif diff --git a/tests/chapter_9/valid/stack_arguments/stack_alignment_check_linux.s b/tests/chapter_9/valid/stack_arguments/stack_alignment_check_linux.s index 75102149..6e1e143c 100644 --- a/tests/chapter_9/valid/stack_arguments/stack_alignment_check_linux.s +++ b/tests/chapter_9/valid/stack_arguments/stack_alignment_check_linux.s @@ -40,7 +40,6 @@ even_arguments: call exit@PLT popq %rbp retq - .globl odd_arguments odd_arguments: pushq %rbp @@ -79,3 +78,4 @@ odd_arguments: call exit@PLT popq %rbp retq + .section ".note.GNU-stack","",@progbits diff --git a/tests/chapter_9/valid/stack_arguments/stack_alignment_check_osx.s b/tests/chapter_9/valid/stack_arguments/stack_alignment_check_osx.s index b2d94ad9..4a656dd5 100644 --- a/tests/chapter_9/valid/stack_arguments/stack_alignment_check_osx.s +++ b/tests/chapter_9/valid/stack_arguments/stack_alignment_check_osx.s @@ -40,7 +40,6 @@ Lfail_even_arguments: call _exit popq %rbp retq - .globl _odd_arguments _odd_arguments: pushq %rbp