libphoenix: make pthread attrs (more) POSIX-compliant#484
Conversation
TASK: RTOS-1353
There was a problem hiding this comment.
Code Review
This pull request adds NULL pointer checks to pthread_attr_init and pthread_attr_destroy to prevent potential dereferences, and fixes a logical bug in pthread_attr_setdetachstate by changing the logical OR (||) to a logical AND (&&) when validating the detachstate parameter. No review comments were provided, so there is no additional feedback.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
|
/gemini review |
There was a problem hiding this comment.
Code Review
This pull request refactors the pthread_attr_t structure, introduces new fields such as guardsize and inheritsched, and implements several missing pthread_attr_* getter and setter functions. However, two critical issues were identified in pthread_create: first, the thread's detached state is incorrectly initialized using the default attributes instead of the user-provided attributes; second, adding the stack size and guard size can result in an integer overflow, potentially leading to an undersized stack allocation and memory corruption.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
35b09b7 to
4dea89e
Compare
b20dbf9 to
68a70c5
Compare
The ceiling should be done only when the stack is mmaped. Ceiling in setstacksize violates POSIX and doesn't make sense if the stack is provided by the caller. Fixes: phoenix-rtos/phoenix-rtos-project#1641 TASK: RTOS-1353
TASK: RTOS-1353
TASK: RTOS-1353
TASK: RTOS-1353
TASK: RTOS-1353
TASK: RTOS-1353
PS-C-REC-016 TASK: RTOS-1353
68a70c5 to
e2a03e2
Compare
|
/gemini review |
There was a problem hiding this comment.
Code Review
This pull request refactors the pthread attributes implementation, updating the pthread_attr_t structure to support guardsize and inheritsched, renaming fields for clarity, and introducing macro-generated getters. Feedback points out POSIX compliance issues: sched_get_priority_max and sched_get_priority_min should set errno and return -1 on failure rather than returning the error code directly, and pthread_create should ignore guardsize when a custom stackaddr is provided.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
| int sched_get_priority_max(int policy) | ||
| { | ||
| if (policy == SCHED_RR) | ||
| return 7; | ||
| return PH_MAX_PRIO; | ||
|
|
||
| return EINVAL; | ||
| } |
There was a problem hiding this comment.
According to POSIX, sched_get_priority_max should return -1 and set errno to EINVAL if the policy is invalid or unsupported, rather than returning EINVAL directly as a positive integer.
int sched_get_priority_max(int policy)
{
if (policy == SCHED_RR) {
return PH_MAX_PRIO;
}
errno = EINVAL;
return -1;
}| int sched_get_priority_min(int policy) | ||
| { | ||
| if (policy == SCHED_RR) | ||
| return 0; | ||
| return PH_MIN_PRIO; | ||
|
|
||
| return EINVAL; | ||
| } |
There was a problem hiding this comment.
According to POSIX, sched_get_priority_min should return -1 and set errno to EINVAL if the policy is invalid or unsupported, rather than returning EINVAL directly as a positive integer.
int sched_get_priority_min(int policy)
{
if (policy == SCHED_RR) {
return PH_MIN_PRIO;
}
errno = EINVAL;
return -1;
}| if (attrs->stacksize > SIZE_MAX - attrs->guardsize || attrs->stacksize + attrs->guardsize > SIZE_MAX - PAGE_SIZE) { | ||
| return EINVAL; | ||
| } | ||
|
|
||
| size_t stacksize = ALIGN(attrs->stacksize + attrs->guardsize, PAGE_SIZE); | ||
| /* FIXME: don't mmap when attrs->stackaddr is not null and just use that address as a stack */ | ||
| void *stack = mmap(attrs->stackaddr, stacksize, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); |
There was a problem hiding this comment.
According to POSIX, if the stackaddr attribute has been set (i.e., the caller is allocating and managing their own thread stacks), the guardsize attribute must be ignored and no guard area should be created. Currently, guardsize is added to stacksize regardless of whether stackaddr is NULL or not.
size_t guardsize = (attrs->stackaddr != NULL) ? 0 : attrs->guardsize;
if (attrs->stacksize > SIZE_MAX - guardsize || attrs->stacksize + guardsize > SIZE_MAX - PAGE_SIZE) {
return EINVAL;
}
size_t stacksize = ALIGN(attrs->stacksize + guardsize, PAGE_SIZE);
/* FIXME: don't mmap when attrs->stackaddr is not null and just use that address as a stack */
void *stack = mmap(attrs->stackaddr, stacksize, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);There was a problem hiding this comment.
Code Review
This pull request refactors the pthread attribute implementation, introducing support for guard size and inherit scheduling attributes, updating the pthread_attr_t structure, and cleaning up function declarations. The feedback highlights POSIX compliance issues: sched_get_priority_max and sched_get_priority_min should return -1 and set errno on failure instead of returning the error code directly, and pthread_attr_setschedparam should return EINVAL rather than ENOTSUP for invalid scheduling priorities.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
| int sched_get_priority_max(int policy) | ||
| { | ||
| if (policy == SCHED_RR) | ||
| return 7; | ||
| return PH_MAX_PRIO; | ||
|
|
||
| return EINVAL; | ||
| } |
There was a problem hiding this comment.
| int sched_get_priority_min(int policy) | ||
| { | ||
| if (policy == SCHED_RR) | ||
| return 0; | ||
| return PH_MIN_PRIO; | ||
|
|
||
| return EINVAL; | ||
| } |
There was a problem hiding this comment.
| if (param->sched_priority > sched_get_priority_max(attr->schedpolicy) || | ||
| param->sched_priority < sched_get_priority_min(attr->schedpolicy)) { | ||
| return ENOTSUP; | ||
| } |
There was a problem hiding this comment.
According to POSIX, pthread_attr_setschedparam should return EINVAL (not ENOTSUP) if the scheduling priority specified in param is invalid for the scheduling policy of attr.
if (param->sched_priority > sched_get_priority_max(attr->schedpolicy) ||
param->sched_priority < sched_get_priority_min(attr->schedpolicy)) {
return EINVAL;
}There was a problem hiding this comment.
Code Review
This pull request refactors the pthread implementation by updating the pthread_attr_t structure, introducing support for guard size and scheduling inheritance, and adding corresponding getter and setter functions. The feedback highlights a critical issue where the guard area is not properly protected with PROT_NONE via mprotect, rendering it ineffective against stack overflows. Additionally, the reviewer points out that sched_get_priority_max and sched_get_priority_min should return -1 and set errno to EINVAL on failure to comply with POSIX standards.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
| if (attrs->stacksize > SIZE_MAX - attrs->guardsize || attrs->stacksize + attrs->guardsize > SIZE_MAX - PAGE_SIZE) { | ||
| return EINVAL; | ||
| } | ||
|
|
||
| size_t stacksize = ALIGN(attrs->stacksize + attrs->guardsize, PAGE_SIZE); | ||
| /* FIXME: don't mmap when attrs->stackaddr is not null and just use that address as a stack */ | ||
| void *stack = mmap(attrs->stackaddr, stacksize, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); | ||
|
|
||
| if ((stack == MAP_FAILED) || (stack == NULL)) { | ||
| return EAGAIN; |
There was a problem hiding this comment.
The guard area is currently allocated as part of the stack with PROT_READ | PROT_WRITE permissions, which means it does not actually protect against stack overflow (it just acts as extra stack space). To comply with POSIX and provide actual stack overflow protection, the guard area should be protected with PROT_NONE using mprotect.
if (attrs->guardsize > SIZE_MAX - PAGE_SIZE || attrs->stacksize > SIZE_MAX - attrs->guardsize) {
return EINVAL;
}
size_t guardsize = ALIGN(attrs->guardsize, PAGE_SIZE);
if (attrs->stacksize > SIZE_MAX - guardsize || attrs->stacksize + guardsize > SIZE_MAX - PAGE_SIZE) {
return EINVAL;
}
size_t stacksize = ALIGN(attrs->stacksize + guardsize, PAGE_SIZE);
/* FIXME: don't mmap when attrs->stackaddr is not null and just use that address as a stack */
void *stack = mmap(attrs->stackaddr, stacksize, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
if ((stack == MAP_FAILED) || (stack == NULL)) {
return EAGAIN;
}
if (attrs->guardsize > 0) {
if (mprotect(stack, guardsize, PROT_NONE) != 0) {
munmap(stack, stacksize);
return EAGAIN;
}
}| int sched_get_priority_max(int policy) | ||
| { | ||
| if (policy == SCHED_RR) | ||
| return 7; | ||
| return PH_MAX_PRIO; | ||
|
|
||
| return EINVAL; | ||
| } |
There was a problem hiding this comment.
| int sched_get_priority_min(int policy) | ||
| { | ||
| if (policy == SCHED_RR) | ||
| return 0; | ||
| return PH_MIN_PRIO; | ||
|
|
||
| return EINVAL; | ||
| } |
There was a problem hiding this comment.
TASK: RTOS-1353
Description
Motivation and Context
Types of changes
How Has This Been Tested?
Checklist:
Special treatment
include/threads: expose min,max prio values to userspace phoenix-rtos-kernel#791