diff options
Diffstat (limited to 'common_modules/module_manager/src/txm_module_manager_util.c')
| -rw-r--r-- | common_modules/module_manager/src/txm_module_manager_util.c | 1023 |
1 files changed, 1020 insertions, 3 deletions
diff --git a/common_modules/module_manager/src/txm_module_manager_util.c b/common_modules/module_manager/src/txm_module_manager_util.c index 78031b5f..f3c8beef 100644 --- a/common_modules/module_manager/src/txm_module_manager_util.c +++ b/common_modules/module_manager/src/txm_module_manager_util.c @@ -9,6 +9,8 @@ * SPDX-License-Identifier: MIT **************************************************************************/ +// Portions of this file were generated with AI assistance. + /**************************************************************************/ /**************************************************************************/ @@ -25,6 +27,15 @@ #define TX_SOURCE_CODE +#include "tx_api.h" +#include "tx_thread.h" +#include "tx_timer.h" +#include "tx_queue.h" +#include "tx_event_flags.h" +#include "tx_semaphore.h" +#include "tx_mutex.h" +#include "tx_block_pool.h" +#include "tx_byte_pool.h" #include "txm_module.h" #include "txm_module_manager_util.h" @@ -270,7 +281,7 @@ UINT return_value; /* 09-30-2020 Scott Larson Initial Version 6.1 */ /* */ /**************************************************************************/ -UINT _txm_module_manager_object_name_compare(CHAR *search_name, UINT search_name_length, CHAR *object_name) +UINT _txm_module_manager_object_name_compare(CHAR *search_name, UINT search_name_length, TX_NAME_CONST CHAR *object_name) { CHAR search_name_char; @@ -461,11 +472,525 @@ UINT _txm_module_manager_param_check_object_for_use(TXM_MODULE_INSTANCE *modu return(TX_FALSE); } - /* Determine if the object pointer is inside the module object pool. */ + /* Determine if the object is outside the calling module. */ if (TXM_MODULE_MANAGER_ENSURE_OUTSIDE_MODULE(module_instance, object_ptr, object_size) == TX_FALSE) { - /* Object pointer is not inside the object pool, which is invalid. */ + /* Object pointer is not outside the module, which is invalid. */ + return(TX_FALSE); + } + + /* Being outside the module does not make an address an object. The manager's + object pool is outside every module, so an address shifted into the interior of + one of this module's own privileged allocations satisfies the test above while + denoting no object at all, and the bytes the shifted address then presents as a + control block are bytes the module chose through ordinary create and set + services. An address in the object pool is therefore only usable if it is the + exact address the manager handed out for an allocation of this size. + + This function is given a size rather than a type, so it can go no further than + that: it cannot establish which type of object it is, and it cannot authenticate + an application-owned object outside the pool. Dispatchers in this repository use + _txm_module_manager_param_check_typed_object_for_use, which does both. */ + if ((_txm_module_manager_object_pool_created == TX_TRUE) && + (object_ptr >= (ALIGN_TYPE) _txm_module_manager_object_pool.tx_byte_pool_start) && + (object_ptr < (ALIGN_TYPE) (_txm_module_manager_object_pool.tx_byte_pool_start + _txm_module_manager_object_pool.tx_byte_pool_size))) + { + + if (_txm_module_manager_allocated_object_check(module_instance, object_ptr, object_size) == TX_FALSE) + { + + /* An address in the object pool that is not the exact start of one of this + module's allocations, which is invalid. */ + return(TX_FALSE); + } + } + + /* Define application-specific object memory check. */ +#ifdef TXM_MODULE_MANGER_APPLICATION_VALID_OBJECT_MEMORY_CHECK + + /* Bring in the application-spefic objeft memory check, defined by the user. */ + TXM_MODULE_MANGER_APPLICATION_VALID_OBJECT_MEMORY_CHECK +#endif /* TXM_MODULE_MANGER_APPLICATION_VALID_OBJECT_MEMORY_ENABLE */ + + /* Everything is okay with the object, return TX_TRUE. */ + return(TX_TRUE); +} + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _txm_module_manager_object_type_size_get PORTABLE C */ +/* 6.4.3 */ +/* AUTHOR */ +/* */ +/* Eclipse ThreadX contributors */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function returns the size of the control block belonging to a */ +/* module object type. It is the size a service of that type is */ +/* entitled to dereference, and the size the manager recorded when it */ +/* allocated object memory for that type. */ +/* */ +/* INPUT */ +/* */ +/* object_type Module object type */ +/* object_size Destination for the control block */ +/* size of that type */ +/* */ +/* OUTPUT */ +/* */ +/* TX_TRUE Known object type */ +/* TX_FALSE Unknown object type */ +/* */ +/* CALLS */ +/* */ +/* None */ +/* */ +/* CALLED BY */ +/* */ +/* _txm_module_manager_param_check_typed_object_for_use */ +/* Module object authentication */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-2026 Eclipse ThreadX Initial Version 6.4.3 */ +/* contributors */ +/* */ +/**************************************************************************/ +UINT _txm_module_manager_object_type_size_get(UINT object_type, ULONG *object_size) +{ + +UINT status; + + + /* Assume the type is one this manager knows. */ + status = TX_TRUE; + + switch (object_type) + { + + case TXM_BLOCK_POOL_OBJECT: + + *object_size = (ULONG) sizeof(TX_BLOCK_POOL); + break; + + case TXM_BYTE_POOL_OBJECT: + + *object_size = (ULONG) sizeof(TX_BYTE_POOL); + break; + + case TXM_EVENT_FLAGS_OBJECT: + + *object_size = (ULONG) sizeof(TX_EVENT_FLAGS_GROUP); + break; + + case TXM_MUTEX_OBJECT: + + *object_size = (ULONG) sizeof(TX_MUTEX); + break; + + case TXM_QUEUE_OBJECT: + + *object_size = (ULONG) sizeof(TX_QUEUE); + break; + + case TXM_SEMAPHORE_OBJECT: + + *object_size = (ULONG) sizeof(TX_SEMAPHORE); + break; + + case TXM_THREAD_OBJECT: + + *object_size = (ULONG) sizeof(TX_THREAD); + break; + + case TXM_TIMER_OBJECT: + + *object_size = (ULONG) sizeof(TX_TIMER); + break; + + default: + + /* Not a type the manager authenticates. Report it rather than guessing a + size, so that a caller cannot be given a range to validate that has no + relationship to the object the service will dereference. */ + *object_size = ((ULONG) 0); + status = TX_FALSE; + break; + } + + return(status); +} + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _txm_module_manager_allocated_object_find PORTABLE C */ +/* 6.4.3 */ +/* AUTHOR */ +/* */ +/* Eclipse ThreadX contributors */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function returns the manager's private header for the object */ +/* allocation an address names, or TX_NULL when the address names */ +/* none of the specified module's allocations. The size the */ +/* allocation was made for is reported to callers that ask for it. */ +/* */ +/* The allocation list is the manager's own record, built as it hands */ +/* object memory out, and it is searched rather than reached through */ +/* a header taken from in front of the caller's address. That order */ +/* is what makes the answer both correct and safe. */ +/* */ +/* Correct, because the address immediately after a header is the */ +/* only address in an allocation that the manager ever gave out, so */ +/* an address chosen inside an allocation is distinguishable from the */ +/* start of one. Reading a header cannot make that distinction: the */ +/* bytes in front of an interior address are part of the object, and */ +/* a module places values there through ordinary services. */ +/* */ +/* Safe, because the caller's address is only ever compared, never */ +/* dereferenced. An address that belongs to no allocation of this */ +/* module -- an object the application owns, an object another module */ +/* owns, or an address nowhere near the object pool -- is rejected */ +/* without a privileged read of the words in front of it. */ +/* */ +/* INPUT */ +/* */ +/* module_instance Requesting module instance pointer*/ +/* object_ptr Address of object memory area */ +/* object_size_ptr Address to return the size the */ +/* allocation was made for, or */ +/* TX_NULL to not return it */ +/* */ +/* OUTPUT */ +/* */ +/* allocation The allocation's private header, */ +/* or TX_NULL when the address */ +/* names none of this module's */ +/* */ +/* CALLS */ +/* */ +/* None */ +/* */ +/* CALLED BY */ +/* */ +/* _txm_module_manager_allocated_object_check */ +/* Module object ownership check */ +/* _txm_module_manager_object_deallocate Module object deallocation */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-2026 Eclipse ThreadX Initial Version 6.4.3 */ +/* contributors */ +/* */ +/**************************************************************************/ +TXM_MODULE_ALLOCATED_OBJECT *_txm_module_manager_allocated_object_find(TXM_MODULE_INSTANCE *module_instance, ALIGN_TYPE object_ptr, ULONG *object_size_ptr) +{ + +TX_INTERRUPT_SAVE_AREA + +TXM_MODULE_ALLOCATED_OBJECT *allocated_object_ptr; +TXM_MODULE_ALLOCATED_OBJECT *found_object_ptr; +ULONG objects_examined; + + + /* Assume the address names none of this module's allocations. */ + found_object_ptr = TX_NULL; + + /* Determine if there is a module whose allocations can be searched. A request + that does not come from a module owns no allocation. */ + if (module_instance == TX_NULL) + { + + /* Nothing to search, and nothing to report. */ + return(TX_NULL); + } + + /* Disable interrupts. The allocation list is maintained by threads holding the + manager protection mutex, so a scan that runs to completion with interrupts + disabled cannot observe it being changed, and unlike taking the mutex it adds + no blocking point and no priority inversion to a kernel request. */ + TX_DISABLE + + allocated_object_ptr = module_instance -> txm_module_instance_object_list_head; + objects_examined = ((ULONG) 0); + + /* Loop through the objects allocated to this module. The loop is bounded by the + count the manager maintains alongside the list, so the cost of one search is + bounded by the number of objects this module has allocated, and a list whose + links have been damaged cannot make the scan run on. */ + while ((objects_examined < module_instance -> txm_module_instance_object_list_count) && + (allocated_object_ptr != TX_NULL)) + { + + /* The address the module was given is the one immediately after the private + header, so that is the only address in this allocation that names it. */ + if (((ALIGN_TYPE) (allocated_object_ptr + 1)) == object_ptr) + { + + /* Found it. An address matches at most one allocation, so there is + nothing further to look at. */ + found_object_ptr = allocated_object_ptr; + + /* Report the size this allocation was made for, if the caller asked for + it. It is read here, inside the scan, so that the answer cannot be + taken from a header that stopped being one after the search. */ + if (object_size_ptr != TX_NULL) + { + + *object_size_ptr = allocated_object_ptr -> txm_module_object_size; + } + + break; + } + + /* Move to the next allocated object. */ + objects_examined++; + allocated_object_ptr = allocated_object_ptr -> txm_module_allocated_object_next; + } + + /* Restore interrupts. */ + TX_RESTORE + + return(found_object_ptr); +} + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _txm_module_manager_allocated_object_check PORTABLE C */ +/* 6.4.3 */ +/* AUTHOR */ +/* */ +/* Eclipse ThreadX contributors */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function determines whether an address is the exact address */ +/* the manager handed the specified module for one of its object */ +/* allocations, and whether that allocation is the size the caller */ +/* expects. */ +/* */ +/* This is the question of ownership, and it is deliberately a */ +/* separate question from whether an object is there at all. A */ +/* module may hold, and legitimately use, a pointer to an object it */ +/* does not own: the manager hands application-owned objects to */ +/* modules by name through its object lookup service, and sharing an */ +/* object is what that service is for. Destroying one is not sharing */ +/* it, so the delete services ask this question in addition to the */ +/* ones that establish that the address denotes a usable object. */ +/* */ +/* INPUT */ +/* */ +/* module_instance Requesting module instance pointer*/ +/* object_ptr Address of object memory area */ +/* object_size Expected size of the allocation */ +/* */ +/* OUTPUT */ +/* */ +/* TX_TRUE An exact allocation of that size */ +/* TX_FALSE Anything else */ +/* */ +/* CALLS */ +/* */ +/* _txm_module_manager_allocated_object_find */ +/* Find the module's allocation */ +/* */ +/* CALLED BY */ +/* */ +/* txm_module_manager_* Module manager functions */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-2026 Eclipse ThreadX Initial Version 6.4.3 */ +/* contributors */ +/* */ +/**************************************************************************/ +UINT _txm_module_manager_allocated_object_check(TXM_MODULE_INSTANCE *module_instance, ALIGN_TYPE object_ptr, ULONG object_size) +{ + +ULONG allocated_size; +UINT status; + + + /* Assume the address is not one of this module's allocations. */ + status = TX_FALSE; + + /* Initialize the size, so that nothing is read if no allocation is found. */ + allocated_size = ((ULONG) 0); + + /* Determine if the address is the exact start of one of this module's + allocations. */ + if (_txm_module_manager_allocated_object_find(module_instance, object_ptr, &allocated_size) != TX_NULL) + { + + /* Is the allocation the size the caller expects? An allocation made for a + smaller object does not become a larger one because a service was asked + to treat it as one. */ + if (allocated_size == object_size) + { + + status = TX_TRUE; + } + } + + return(status); +} + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _txm_module_manager_param_check_typed_object_for_use */ +/* PORTABLE C */ +/* 6.4.3 */ +/* AUTHOR */ +/* */ +/* Eclipse ThreadX contributors */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function authenticates a kernel object a module has named, */ +/* before a privileged service is allowed to dereference it. It */ +/* establishes that the address is the exact address of a live kernel */ +/* object of the type the service expects. */ +/* */ +/* The address is accepted only if it is on the kernel's created list */ +/* for that type. That list is the record the create and delete */ +/* services maintain, so being on it establishes at once that the */ +/* address is an object start rather than an address inside an object, */ +/* that the object is of this type, and that it has not been deleted. */ +/* It is also how an object the application created and shared with a */ +/* module is authenticated, since the manager allocated no such object */ +/* and has no record of its own to consult. */ +/* */ +/* Nothing a module can influence is used to establish a type. In */ +/* particular the control block ID is not, on its own, evidence of */ +/* anything: a module can arrange for the value of an ID to appear */ +/* inside an object it legitimately owns, which is what lets a shifted */ +/* pointer pass an ID test, and distinct object types of equal size */ +/* exist, so an ID is not even a type at an address known to be an */ +/* object start. It is checked, after the created list has settled the */ +/* question, because it is the check the _txe_ services make and it is */ +/* compiled away with them under TX_DISABLE_ERROR_CHECKING. */ +/* */ +/* INPUT */ +/* */ +/* module_instance Requesting module instance pointer*/ +/* object_ptr Address of object memory area */ +/* object_type Module object type the service */ +/* expects */ +/* */ +/* OUTPUT */ +/* */ +/* TX_TRUE Authenticated object pointer */ +/* TX_FALSE Invalid object pointer */ +/* */ +/* CALLS */ +/* */ +/* _txm_module_manager_object_type_size_get */ +/* Get control block size */ +/* _txm_module_manager_created_object_type_check */ +/* Check kernel created list */ +/* _txm_module_manager_object_id_check Check control block ID */ +/* */ +/* CALLED BY */ +/* */ +/* txm_module_manager_* Module manager functions */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-2026 Eclipse ThreadX Initial Version 6.4.3 */ +/* contributors */ +/* */ +/**************************************************************************/ +UINT _txm_module_manager_param_check_typed_object_for_use(TXM_MODULE_INSTANCE *module_instance, ALIGN_TYPE object_ptr, UINT object_type) +{ + +ULONG object_size; +UINT exact_object; + + + /* Determine if the object pointer is NULL. */ + if ((void *) object_ptr == TX_NULL) + { + + /* Object pointer is NULL, which is invalid. */ + return(TX_FALSE); + } + + /* Pickup the size of the control block this type of service dereferences. */ + if (_txm_module_manager_object_type_size_get(object_type, &object_size) == TX_FALSE) + { + + /* Not an object type this manager authenticates, so it cannot be used. */ + return(TX_FALSE); + } + + /* Determine if the object is outside the calling module. A kernel object inside + the module's own memory is one the module can write behind the kernel's back, + so it is rejected here as it always has been. This also rejects a size that + wraps when added to the address. */ + if (TXM_MODULE_MANAGER_ENSURE_OUTSIDE_MODULE(module_instance, object_ptr, object_size) == TX_FALSE) + { + + /* Object pointer is not outside the module, which is invalid. */ + return(TX_FALSE); + } + + /* Establish that the address is the exact address of a live object of this type, + from the kernel's created list for the type. That list is the record the create + and delete services maintain, so being on it establishes at once that the + address is an object start, that the object is of this type, and that it has not + been deleted. + + It is deliberately the only ground on which an address is accepted. The + manager's own allocation list would establish the address and the size of an + object a module allocated, and would do it by walking a shorter list, but it + records no type, and the type cannot then be taken from the control block + itself: distinct object types of equal size exist -- on a 32-bit target a byte + pool, a mutex and a timer are all the same size -- so a control block whose ID + has been made to read as one of them would be accepted as that type. Nothing a + module can influence is used to establish a type. + + The address is not dereferenced to reach this decision. An address a module + named is not read until a kernel record says there is an object there. */ + exact_object = _txm_module_manager_created_object_type_check(object_ptr, object_type); + + if (exact_object == TX_FALSE) + { + + /* The address is not the start of a live object of this type. */ + return(TX_FALSE); + } + + /* The address is a live object of the requested type. Confirm it against the + control block's own ID, which is the check the _txe_ services would make and + which is compiled away with them under TX_DISABLE_ERROR_CHECKING. */ + if (_txm_module_manager_object_id_check(object_ptr, object_type) == TX_FALSE) + { + + /* The created list and the control block disagree, so the object is not in a + state the manager is prepared to vouch for. */ return(TX_FALSE); } @@ -485,6 +1010,498 @@ UINT _txm_module_manager_param_check_object_for_use(TXM_MODULE_INSTANCE *modu /* */ /* FUNCTION RELEASE */ /* */ +/* _txm_module_manager_created_object_type_check PORTABLE C */ +/* 6.4.3 */ +/* AUTHOR */ +/* */ +/* Eclipse ThreadX contributors */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function determines whether an address is the exact address */ +/* of an object on the kernel's created list for a module object type. */ +/* */ +/* The created list is the record the create and delete services */ +/* maintain, so being on it establishes at once that the address is an */ +/* object start rather than an address inside an object, that the */ +/* object is of this type, and that it has not been deleted. It is */ +/* also the only record of an object the application created and */ +/* shared with a module, since the manager allocated no such object. */ +/* */ +/* Nothing the module can influence is consulted. In particular the */ +/* control block ID is not: a module can arrange for the value of an */ +/* ID to appear inside memory it owns, and distinct object types of */ +/* equal size exist, so an ID is not evidence that an object is there */ +/* nor of what type it is. */ +/* */ +/* INPUT */ +/* */ +/* object_ptr Address of object memory area */ +/* object_type Module object type */ +/* */ +/* OUTPUT */ +/* */ +/* TX_TRUE A created object of that type */ +/* TX_FALSE Anything else */ +/* */ +/* CALLS */ +/* */ +/* None */ +/* */ +/* CALLED BY */ +/* */ +/* _txm_module_manager_live_object_check Module object liveness check */ +/* _txm_module_manager_param_check_typed_object_for_use */ +/* Module object authentication */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-2026 Eclipse ThreadX Initial Version 6.4.3 */ +/* contributors */ +/* */ +/**************************************************************************/ +UINT _txm_module_manager_created_object_type_check(ALIGN_TYPE object_ptr, UINT object_type) +{ + +TX_INTERRUPT_SAVE_AREA + +ULONG objects_examined; +ULONG objects_created; +ALIGN_TYPE candidate_ptr; +UINT status; +TX_BLOCK_POOL *block_pool_ptr; +TX_BYTE_POOL *byte_pool_ptr; +TX_EVENT_FLAGS_GROUP *event_flags_ptr; +TX_MUTEX *mutex_ptr; +TX_QUEUE *queue_ptr; +TX_SEMAPHORE *semaphore_ptr; +TX_THREAD *thread_ptr; +TX_TIMER *timer_ptr; + + + /* Assume the address is not on the created list for this type. */ + status = TX_FALSE; + + /* Disable interrupts. The created lists are maintained with interrupts disabled, + so a scan that runs to completion this way sees a consistent list, and it adds + no blocking point to a kernel request. The cost of one check is bounded by the + number of objects of this type the system has created, which is the price of + authenticating an object the manager did not allocate; a module using its own + allocated objects does not reach this function. */ + TX_DISABLE + + /* Start each list from its head and pick up the count that bounds the walk, so a + list whose links have been damaged cannot make the scan run on. */ + switch (object_type) + { + + case TXM_BLOCK_POOL_OBJECT: + + block_pool_ptr = _tx_block_pool_created_ptr; + objects_created = _tx_block_pool_created_count; + objects_examined = ((ULONG) 0); + + while ((objects_examined < objects_created) && (block_pool_ptr != TX_NULL)) + { + candidate_ptr = (ALIGN_TYPE) block_pool_ptr; + if (candidate_ptr == object_ptr) + { + status = TX_TRUE; + break; + } + objects_examined++; + block_pool_ptr = block_pool_ptr -> tx_block_pool_created_next; + } + break; + + case TXM_BYTE_POOL_OBJECT: + + byte_pool_ptr = _tx_byte_pool_created_ptr; + objects_created = _tx_byte_pool_created_count; + objects_examined = ((ULONG) 0); + + while ((objects_examined < objects_created) && (byte_pool_ptr != TX_NULL)) + { + candidate_ptr = (ALIGN_TYPE) byte_pool_ptr; + if (candidate_ptr == object_ptr) + { + status = TX_TRUE; + break; + } + objects_examined++; + byte_pool_ptr = byte_pool_ptr -> tx_byte_pool_created_next; + } + break; + + case TXM_EVENT_FLAGS_OBJECT: + + event_flags_ptr = _tx_event_flags_created_ptr; + objects_created = _tx_event_flags_created_count; + objects_examined = ((ULONG) 0); + + while ((objects_examined < objects_created) && (event_flags_ptr != TX_NULL)) + { + candidate_ptr = (ALIGN_TYPE) event_flags_ptr; + if (candidate_ptr == object_ptr) + { + status = TX_TRUE; + break; + } + objects_examined++; + event_flags_ptr = event_flags_ptr -> tx_event_flags_group_created_next; + } + break; + + case TXM_MUTEX_OBJECT: + + mutex_ptr = _tx_mutex_created_ptr; + objects_created = _tx_mutex_created_count; + objects_examined = ((ULONG) 0); + + while ((objects_examined < objects_created) && (mutex_ptr != TX_NULL)) + { + candidate_ptr = (ALIGN_TYPE) mutex_ptr; + if (candidate_ptr == object_ptr) + { + status = TX_TRUE; + break; + } + objects_examined++; + mutex_ptr = mutex_ptr -> tx_mutex_created_next; + } + break; + + case TXM_QUEUE_OBJECT: + + queue_ptr = _tx_queue_created_ptr; + objects_created = _tx_queue_created_count; + objects_examined = ((ULONG) 0); + + while ((objects_examined < objects_created) && (queue_ptr != TX_NULL)) + { + candidate_ptr = (ALIGN_TYPE) queue_ptr; + if (candidate_ptr == object_ptr) + { + status = TX_TRUE; + break; + } + objects_examined++; + queue_ptr = queue_ptr -> tx_queue_created_next; + } + break; + + case TXM_SEMAPHORE_OBJECT: + + semaphore_ptr = _tx_semaphore_created_ptr; + objects_created = _tx_semaphore_created_count; + objects_examined = ((ULONG) 0); + + while ((objects_examined < objects_created) && (semaphore_ptr != TX_NULL)) + { + candidate_ptr = (ALIGN_TYPE) semaphore_ptr; + if (candidate_ptr == object_ptr) + { + status = TX_TRUE; + break; + } + objects_examined++; + semaphore_ptr = semaphore_ptr -> tx_semaphore_created_next; + } + break; + + case TXM_THREAD_OBJECT: + + thread_ptr = _tx_thread_created_ptr; + objects_created = _tx_thread_created_count; + objects_examined = ((ULONG) 0); + + while ((objects_examined < objects_created) && (thread_ptr != TX_NULL)) + { + candidate_ptr = (ALIGN_TYPE) thread_ptr; + if (candidate_ptr == object_ptr) + { + status = TX_TRUE; + break; + } + objects_examined++; + thread_ptr = thread_ptr -> tx_thread_created_next; + } + break; + + case TXM_TIMER_OBJECT: + + timer_ptr = _tx_timer_created_ptr; + objects_created = _tx_timer_created_count; + objects_examined = ((ULONG) 0); + + while ((objects_examined < objects_created) && (timer_ptr != TX_NULL)) + { + candidate_ptr = (ALIGN_TYPE) timer_ptr; + if (candidate_ptr == object_ptr) + { + status = TX_TRUE; + break; + } + objects_examined++; + timer_ptr = timer_ptr -> tx_timer_created_next; + } + break; + + default: + + /* Not a type the manager authenticates. */ + break; + } + + /* Restore interrupts. */ + TX_RESTORE + + return(status); +} + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _txm_module_manager_object_id_check PORTABLE C */ +/* 6.4.3 */ +/* AUTHOR */ +/* */ +/* Eclipse ThreadX contributors */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function determines whether the control block at an object */ +/* start carries the ID of a module object type. The kernel writes */ +/* that ID when it creates an object and clears it when it deletes */ +/* one, so at an address already established to be an object start the */ +/* ID reports both the type and whether the object is still created. */ +/* */ +/* This check must not be used on its own to decide that an address is */ +/* an object. A module can place the value of an ID inside an object */ +/* it legitimately owns, so an ID found at an address the manager has */ +/* not otherwise authenticated proves nothing. */ +/* */ +/* The check matters most where the error checking layer is absent: */ +/* with TX_DISABLE_ERROR_CHECKING the _txe_ services that would */ +/* otherwise test the ID are compiled away, and this is then the only */ +/* ID test between a module and a privileged dereference. */ +/* */ +/* INPUT */ +/* */ +/* object_ptr Address of an object start */ +/* object_type Module object type */ +/* */ +/* OUTPUT */ +/* */ +/* TX_TRUE A created object of that type */ +/* TX_FALSE Anything else */ +/* */ +/* CALLS */ +/* */ +/* None */ +/* */ +/* CALLED BY */ +/* */ +/* _txm_module_manager_param_check_typed_object_for_use */ +/* Module object authentication */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-2026 Eclipse ThreadX Initial Version 6.4.3 */ +/* contributors */ +/* */ +/**************************************************************************/ +UINT _txm_module_manager_object_id_check(ALIGN_TYPE object_ptr, UINT object_type) +{ + +TX_INTERRUPT_SAVE_AREA + +ULONG object_id; +ULONG expected_id; +UINT status; + + + /* Read the ID through a pointer to the type the caller named, so that the field + read is the one that type declares rather than an assumed offset. */ + TX_DISABLE + + switch (object_type) + { + + case TXM_BLOCK_POOL_OBJECT: + + object_id = ((TX_BLOCK_POOL *) object_ptr) -> tx_block_pool_id; + expected_id = TX_BLOCK_POOL_ID; + break; + + case TXM_BYTE_POOL_OBJECT: + + object_id = ((TX_BYTE_POOL *) object_ptr) -> tx_byte_pool_id; + expected_id = TX_BYTE_POOL_ID; + break; + + case TXM_EVENT_FLAGS_OBJECT: + + object_id = ((TX_EVENT_FLAGS_GROUP *) object_ptr) -> tx_event_flags_group_id; + expected_id = TX_EVENT_FLAGS_ID; + break; + + case TXM_MUTEX_OBJECT: + + object_id = ((TX_MUTEX *) object_ptr) -> tx_mutex_id; + expected_id = TX_MUTEX_ID; + break; + + case TXM_QUEUE_OBJECT: + + object_id = ((TX_QUEUE *) object_ptr) -> tx_queue_id; + expected_id = TX_QUEUE_ID; + break; + + case TXM_SEMAPHORE_OBJECT: + + object_id = ((TX_SEMAPHORE *) object_ptr) -> tx_semaphore_id; + expected_id = TX_SEMAPHORE_ID; + break; + + case TXM_THREAD_OBJECT: + + object_id = ((TX_THREAD *) object_ptr) -> tx_thread_id; + expected_id = TX_THREAD_ID; + break; + + case TXM_TIMER_OBJECT: + + object_id = ((TX_TIMER *) object_ptr) -> tx_timer_id; + expected_id = TX_TIMER_ID; + break; + + default: + + /* Not a type the manager authenticates. Choose values that cannot match. */ + object_id = TX_CLEAR_ID; + expected_id = ~((ULONG) TX_CLEAR_ID); + break; + } + + /* Restore interrupts. */ + TX_RESTORE + + if (object_id == expected_id) + { + + status = TX_TRUE; + } + else + { + + status = TX_FALSE; + } + + return(status); +} + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _txm_module_manager_live_object_check PORTABLE C */ +/* 6.4.3 */ +/* AUTHOR */ +/* */ +/* Eclipse ThreadX contributors */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function determines whether an address is the exact address */ +/* of a live kernel object of any type the Module Manager knows. */ +/* */ +/* It answers the question object deallocation has to ask before it */ +/* gives memory back: is the kernel still going to use these bytes as */ +/* a control block. Deallocation is told an address and nothing else, */ +/* so unlike the checks a typed service makes it cannot be given the */ +/* type to look for, and every type has to be looked for in turn. */ +/* */ +/* The eight created lists are searched whatever the size of the */ +/* allocation at the address. Skipping a type whose control block is */ +/* larger than the allocation would be sound only if every object had */ +/* been created through a size-checked path, and a module running */ +/* without memory protection creates objects without one. */ +/* */ +/* Each list is searched in its own interrupts-disabled window rather */ +/* than all of them in one, so the longest window is bounded by the */ +/* number of objects of a single type. The whole search costs one pass */ +/* over the objects the system has created, and is paid once per */ +/* object deallocation. */ +/* */ +/* INPUT */ +/* */ +/* object_ptr Address of object memory area */ +/* */ +/* OUTPUT */ +/* */ +/* TX_TRUE A live kernel object is there */ +/* TX_FALSE Anything else */ +/* */ +/* CALLS */ +/* */ +/* _txm_module_manager_created_object_type_check */ +/* Check one kernel created list */ +/* */ +/* CALLED BY */ +/* */ +/* _txm_module_manager_object_deallocate Deallocate object memory */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* xx-xx-2026 Eclipse ThreadX Initial Version 6.4.3 */ +/* contributors */ +/* */ +/**************************************************************************/ +UINT _txm_module_manager_live_object_check(ALIGN_TYPE object_ptr) +{ + +UINT object_type; +UINT status; + + + /* Assume no live object is there. */ + status = TX_FALSE; + + /* The eight module object types that have a kernel created list occupy a + contiguous range, so each is asked in turn by walking the range. A value in + the range that the per-type check does not recognise answers TX_FALSE, so a + type the manager stops knowing does not silently pass this search. */ + for (object_type = ((UINT) TXM_BLOCK_POOL_OBJECT); object_type <= ((UINT) TXM_TIMER_OBJECT); object_type++) + { + + if (_txm_module_manager_created_object_type_check(object_ptr, object_type) == TX_TRUE) + { + + /* An address is the start of at most one object, so there is nothing + further to look for. */ + status = TX_TRUE; + break; + } + } + + return(status); +} + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ /* _txm_module_manager_util_code_allocation_size_and_alignment_get */ /* PORTABLE C */ /* 6.1 */ |
