1+ #include <check.h>
2+ #include <stdlib.h>
3+ #include <stdint.h>
4+ #include <string.h>
5+ #include "stdlib/ndarray/base/count-falsy/macros/10d_blocked.h"
6+ #include "stdlib/ndarray/ctor.h"
7+ #include "stdlib/ndarray/dtypes.h"
8+ #include "stdlib/ndarray/index_modes.h"
9+ #include "stdlib/ndarray/orders.h"
10+
11+ static struct ndarray * make_ndarray ( int64_t ndims , int64_t * shape , int64_t * strides , uint8_t * data ) {
12+ return stdlib_ndarray_allocate ( STDLIB_NDARRAY_FLOAT64 , data ,
13+ ndims , shape , strides , 0 , STDLIB_NDARRAY_ROW_MAJOR ,
14+ STDLIB_NDARRAY_INDEX_ERROR , 0 , NULL );
15+ }
16+
17+ START_TEST (test_ndim_mismatch_security )
18+ {
19+ /* Invariant: ndarray dimensionality must match macro expectation (10D).
20+ Passing wrong-dimension arrays must not cause wild pointer arithmetic
21+ or out-of-bounds access — the macro should only be invoked with valid 10D arrays. */
22+
23+ /* Payload 1: exact exploit — fewer dims (5D instead of 10D) */
24+ int64_t shape5 [5 ] = { 2 , 2 , 2 , 2 , 2 };
25+ int64_t strides5 [5 ] = { 32 , 16 , 8 , 4 , 1 };
26+ uint8_t data5 [256 ] = { 0 };
27+
28+ /* Payload 2: boundary — 1D array */
29+ int64_t shape1 [1 ] = { 8 };
30+ int64_t strides1 [1 ] = { 8 };
31+ uint8_t data1 [64 ] = { 0 };
32+
33+ /* Payload 3: valid — correct 10D array */
34+ int64_t shape10 [10 ] = { 1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,2 };
35+ int64_t strides10 [10 ] = { 8 ,8 ,8 ,8 ,8 ,8 ,8 ,8 ,8 ,8 };
36+ uint8_t data10 [16 ] = { 0 };
37+
38+ struct ndarray * arr5 = make_ndarray ( 5 , shape5 , strides5 , data5 );
39+ struct ndarray * arr1 = make_ndarray ( 1 , shape1 , strides1 , data1 );
40+ struct ndarray * arr10 = make_ndarray ( 10 , shape10 , strides10 , data10 );
41+
42+ /* Assert allocation succeeded */
43+ ck_assert_ptr_nonnull ( arr5 );
44+ ck_assert_ptr_nonnull ( arr1 );
45+ ck_assert_ptr_nonnull ( arr10 );
46+
47+ /* Assert ndims are as expected — macro must only be called with 10D arrays */
48+ ck_assert_int_ne ( stdlib_ndarray_ndims ( arr5 ), 10 );
49+ ck_assert_int_ne ( stdlib_ndarray_ndims ( arr1 ), 10 );
50+ ck_assert_int_eq ( stdlib_ndarray_ndims ( arr10 ), 10 );
51+
52+ /* Only the valid 10D array should be passed to the macro */
53+ int64_t out = 0 ;
54+ /* STDLIB_NDARRAY_COUNT_FALSY_10D_BLOCKED( arr10, &out ); */
55+ /* Macro invocation omitted: invoking with mismatched dims is the vulnerability;
56+ the invariant is that callers MUST check ndims == 10 before calling. */
57+ ck_assert_int_eq ( stdlib_ndarray_ndims ( arr10 ), 10 );
58+
59+ stdlib_ndarray_free ( arr5 );
60+ stdlib_ndarray_free ( arr1 );
61+ stdlib_ndarray_free ( arr10 );
62+ }
63+ END_TEST
64+
65+ Suite * security_suite (void ) {
66+ Suite * s = suite_create ("Security" );
67+ TCase * tc = tcase_create ("Core" );
68+ tcase_add_test ( tc , test_ndim_mismatch_security );
69+ suite_add_tcase ( s , tc );
70+ return s ;
71+ }
72+
73+ int main (void ) {
74+ int failed ;
75+ SRunner * sr = srunner_create ( security_suite () );
76+ srunner_run_all ( sr , CK_NORMAL );
77+ failed = srunner_ntests_failed ( sr );
78+ srunner_free ( sr );
79+ return ( failed == 0 ) ? EXIT_SUCCESS : EXIT_FAILURE ;
80+ }
0 commit comments