File tree Expand file tree Collapse file tree 3 files changed +62
-1
lines changed Expand file tree Collapse file tree 3 files changed +62
-1
lines changed Original file line number Diff line number Diff line change @@ -50,6 +50,13 @@ void _twin_run_timeout(void)
5050 twin_timeout_t * first = (twin_timeout_t * ) _twin_queue_set_order (& head );
5151 for (timeout = first ; timeout && twin_time_compare (now , >=, timeout -> time );
5252 timeout = (twin_timeout_t * ) timeout -> queue .order ) {
53+ /* Validate closure pointer before executing timeout callback */
54+ if (!twin_pointer_valid (timeout -> closure )) {
55+ /* Invalid closure pointer, remove this timeout */
56+ _twin_queue_delete (& head , & timeout -> queue );
57+ continue ;
58+ }
59+
5360 delay = (* timeout -> proc )(now , timeout -> closure );
5461 if (delay >= 0 ) {
5562 timeout -> time = twin_now () + delay ;
@@ -68,6 +75,12 @@ twin_timeout_t *twin_set_timeout(twin_timeout_proc_t timeout_proc,
6875 if (!timeout )
6976 return NULL ;
7077
78+ /* Basic validation of closure pointer at scheduling time */
79+ if (closure && !twin_pointer_valid (closure )) {
80+ free (timeout );
81+ return NULL ;
82+ }
83+
7184 if (!start )
7285 start = twin_now ();
7386 timeout -> delay = delay ;
Original file line number Diff line number Diff line change @@ -810,4 +810,38 @@ void twin_custom_widget_destroy(twin_custom_widget_t *custom);
810810/* Path convex hull computation */
811811twin_path_t * twin_path_convex_hull (twin_path_t * path );
812812
813+ /*
814+ * Memory pointer validation
815+ *
816+ * This defines the minimum valid pointer address for closure validation.
817+ * Different environments have different memory layouts:
818+ *
819+ * - Unix-like systems (Linux/BSD/macOS/Solaris): First 4KB (0x1000) typically
820+ * unmapped
821+ * - Windows: First 64KB (0x10000) reserved
822+ * - Bare-metal: May have valid memory starting at 0x0
823+ */
824+ #ifndef TWIN_POINTER_MIN_VALID
825+ #if defined(_WIN32 ) || defined(_WIN64 )
826+ #define TWIN_POINTER_MIN_VALID 0x10000 /* Windows: 64KB */
827+ #elif defined(__unix__ ) || defined(__unix ) || defined(unix ) || \
828+ (defined(__APPLE__ ) && defined(__MACH__ )) || defined(__linux__ ) || \
829+ defined(__FreeBSD__ ) || defined(__NetBSD__ ) || defined(__OpenBSD__ ) || \
830+ defined(__DragonFly__ ) || defined(__sun ) || defined(__HAIKU__ ) || \
831+ defined(__ANDROID__ )
832+ #define TWIN_POINTER_MIN_VALID 0x1000 /* Unix-like: 4KB */
833+ #else
834+ #define TWIN_POINTER_MIN_VALID 0x100 /* Bare-metal/embedded: 256 bytes */
835+ #endif
836+ #endif
837+
838+ /*
839+ * Validate a pointer for basic sanity
840+ * Returns true if the pointer appears to be valid
841+ */
842+ static inline bool twin_pointer_valid (const void * ptr )
843+ {
844+ return ptr && (uintptr_t ) ptr >= TWIN_POINTER_MIN_VALID ;
845+ }
846+
813847#endif /* _TWIN_PRIVATE_H_ */
Original file line number Diff line number Diff line change @@ -32,9 +32,17 @@ void _twin_run_work(void)
3232 twin_work_t * first ;
3333
3434 first = (twin_work_t * ) _twin_queue_set_order (& head );
35- for (work = first ; work ; work = (twin_work_t * ) work -> queue .order )
35+ for (work = first ; work ; work = (twin_work_t * ) work -> queue .order ) {
36+ /* Validate closure pointer before executing callback */
37+ if (!twin_pointer_valid (work -> closure )) {
38+ /* Invalid closure pointer, remove this work item */
39+ _twin_queue_delete (& head , & work -> queue );
40+ continue ;
41+ }
42+
3643 if (!(* work -> proc )(work -> closure ))
3744 _twin_queue_delete (& head , & work -> queue );
45+ }
3846 _twin_queue_review_order (& first -> queue );
3947}
4048
@@ -46,6 +54,12 @@ twin_work_t *twin_set_work(twin_work_proc_t work_proc,
4654 if (!work )
4755 return NULL ;
4856
57+ /* Basic validation of closure pointer at scheduling time */
58+ if (closure && !twin_pointer_valid (closure )) {
59+ free (work );
60+ return NULL ;
61+ }
62+
4963 work -> proc = work_proc ;
5064 work -> priority = priority ;
5165 work -> closure = closure ;
You can’t perform that action at this time.
0 commit comments