summaryrefslogtreecommitdiff
path: root/test/tx/cmake/module_qemu/tests/test_module_privileged.c
blob: 288117dd07b94e0c77a7d77e9bb5ee721996a27d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
/***************************************************************************
 * Copyright (c) 2026 Eclipse ThreadX contributors
 *
 * This program and the accompanying materials are made available under the
 * terms of the MIT License which is available at
 * https://opensource.org/licenses/MIT.
 *
 * AI Disclosure: This file was largely AI-generated by Claude Code (Opus 5.5).
 * The AI-generated portions may be considered public domain (CC0-1.0)
 * and not subject to the project's licence. The human contributor has
 * reviewed and verified that the code is correct.
 *
 * SPDX-License-Identifier: MIT and CC0-1.0
 **************************************************************************/


/**************************************************************************/
/**************************************************************************/
/**                                                                       */
/** ThreadX Test                                                          */
/**                                                                       */
/**   Module execution harness: privileged, unprotected module            */
/**                                                                       */
/**************************************************************************/
/**************************************************************************/

/* The same module built privileged and without memory protection.  It runs
   with the kernel's privileges, so the read that faults in the protected image
   succeeds here, which shows that the fault in that image comes from the
   module's protection and not from the address itself.  Its kernel services
   must work just as the protected module's do.  */

#include "harness_checks.h"

#define MODULE_WAIT_TICKS       ((ULONG) 500UL)
#define PRIVILEGED_PROPERTIES   ((ULONG) 0x02000000UL)  /* GNU; privileged, no memory protection */
#define KERNEL_WORD_VALUE       ((ULONG) 0x6B65726EUL)

extern UCHAR                    module_services_privileged[];

static TXM_MODULE_INSTANCE      test_module;
static volatile ULONG           kernel_word = KERNEL_WORD_VALUE;


VOID  harness_test(VOID)
{
ULONG   available_before;

    harness_print("Module privileged: unprotected module reads kernel memory\n");

    available_before = harness_module_pool_available();

    harness_shared_clear();
    MODULE_SHARED[MODULE_IN_CYCLE] =       1UL;
    MODULE_SHARED[MODULE_IN_KERNEL_WORD] = (ULONG) &kernel_word;

    harness_expect("memory load", (ULONG) txm_module_manager_memory_load(&test_module, "services privileged",
                                                                         (VOID *) module_services_privileged),
                   (ULONG) TX_SUCCESS);
    harness_expect("module properties", test_module.txm_module_instance_property_flags, PRIVILEGED_PROPERTIES);
    harness_expect("module start", (ULONG) txm_module_manager_start(&test_module), (ULONG) TX_SUCCESS);
    harness_expect("module finished", (ULONG) harness_wait_for_module(MODULE_WAIT_TICKS), (ULONG) TX_TRUE);

    harness_check_services(1UL);
    harness_expect("module ran privileged", MODULE_SHARED[MODULE_OUT_CONTROL] & CONTROL_NPRIV, 0UL);
    harness_expect("kernel read completed", MODULE_SHARED[MODULE_OUT_KERNEL_READ_DONE], 1UL);
    harness_expect("kernel value read", MODULE_SHARED[MODULE_OUT_KERNEL_VALUE], KERNEL_WORD_VALUE);
    harness_expect("no memory fault", harness_fault_count, 0UL);

    harness_expect("module stop", (ULONG) txm_module_manager_stop(&test_module), (ULONG) TX_SUCCESS);
    harness_expect("module unload", (ULONG) txm_module_manager_unload(&test_module), (ULONG) TX_SUCCESS);
    harness_expect("module memory returned", harness_module_pool_available(), available_before);
}