Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix #855, check against FD_SETSIZE in bsd-select #897

Merged
merged 1 commit into from
Mar 19, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 35 additions & 21 deletions src/os/portable/os-impl-bsd-select.c
Original file line number Diff line number Diff line change
Expand Up @@ -72,16 +72,16 @@
*
* returns: Highest numbered file descriptor in the output fd_set
*-----------------------------------------------------------------*/
static int OS_FdSet_ConvertIn_Impl(fd_set *os_set, OS_FdSet *OSAL_set)
static int32 OS_FdSet_ConvertIn_Impl(int *os_maxfd, fd_set *os_set, OS_FdSet *OSAL_set)
{
size_t offset;
size_t bit;
osal_index_t id;
uint8 objids;
int osfd;
int maxfd;
int32 status;

maxfd = -1;
status = OS_SUCCESS;
for (offset = 0; offset < sizeof(OSAL_set->object_ids); ++offset)
{
objids = OSAL_set->object_ids[offset];
Expand All @@ -94,10 +94,18 @@ static int OS_FdSet_ConvertIn_Impl(fd_set *os_set, OS_FdSet *OSAL_set)
osfd = OS_impl_filehandle_table[id].fd;
if (osfd >= 0 && OS_impl_filehandle_table[id].selectable)
{
FD_SET(osfd, os_set);
if (osfd > maxfd)
if (osfd >= FD_SETSIZE)
{
/* out of range of select() implementation */
status = OS_ERR_OPERATION_NOT_SUPPORTED;
}
else
{
maxfd = osfd;
FD_SET(osfd, os_set);
if (osfd > *os_maxfd)
{
*os_maxfd = osfd;
}
}
}
}
Expand All @@ -106,7 +114,7 @@ static int OS_FdSet_ConvertIn_Impl(fd_set *os_set, OS_FdSet *OSAL_set)
}
}

return maxfd;
return status;
} /* end OS_FdSet_ConvertIn_Impl */

/*----------------------------------------------------------------
Expand Down Expand Up @@ -267,6 +275,12 @@ int32 OS_SelectSingle_Impl(const OS_object_token_t *token, uint32 *SelectFlags,
return OS_ERR_OPERATION_NOT_SUPPORTED;
}

if (impl->fd >= FD_SETSIZE)
{
/* out of range of select() implementation */
return OS_ERR_OPERATION_NOT_SUPPORTED;
}

if (*SelectFlags != 0)
{
FD_ZERO(&wr_set);
Expand Down Expand Up @@ -319,41 +333,41 @@ int32 OS_SelectMultiple_Impl(OS_FdSet *ReadSet, OS_FdSet *WriteSet, int32 msecs)
{
fd_set wr_set;
fd_set rd_set;
int osfd;
int maxfd;
int32 return_code;

/*
* This return code will be used if the set(s) do not
* contain any file handles capable of select(). It
* will be overwritten with the real result of the
* select call, if selectable file handles were specified.
*/
return_code = OS_ERR_OPERATION_NOT_SUPPORTED;
FD_ZERO(&rd_set);
FD_ZERO(&wr_set);
maxfd = -1;
if (ReadSet != NULL)
{
osfd = OS_FdSet_ConvertIn_Impl(&rd_set, ReadSet);
if (osfd > maxfd)
return_code = OS_FdSet_ConvertIn_Impl(&maxfd, &rd_set, ReadSet);
if (return_code != OS_SUCCESS)
{
maxfd = osfd;
return return_code;
}
}
if (WriteSet != NULL)
{
osfd = OS_FdSet_ConvertIn_Impl(&wr_set, WriteSet);
if (osfd > maxfd)
return_code = OS_FdSet_ConvertIn_Impl(&maxfd, &wr_set, WriteSet);
if (return_code != OS_SUCCESS)
{
maxfd = osfd;
return return_code;
}
}

if (maxfd >= 0)
{
return_code = OS_DoSelect(maxfd, &rd_set, &wr_set, msecs);
}
else
{
/*
* This return code will be used if the set(s) were
* both empty/NULL or otherwise did not contain valid filehandles.
*/
return_code = OS_ERR_INVALID_ID;
}

if (return_code == OS_SUCCESS)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,5 +39,6 @@
*
*****************************************************/
void UT_PortablePosixIOTest_Set_Selectable(osal_index_t local_id, bool is_selectable);
void UT_PortablePosixIOTest_Set_FD(osal_index_t local_id, int fd);

#endif /* UT_ADAPTOR_PORTABLE_POSIX_IO_H */
Original file line number Diff line number Diff line change
Expand Up @@ -35,3 +35,8 @@ void UT_PortablePosixIOTest_Set_Selectable(osal_index_t local_id, bool is_select
{
OS_impl_filehandle_table[local_id].selectable = is_selectable;
}

void UT_PortablePosixIOTest_Set_FD(osal_index_t local_id, int fd)
{
OS_impl_filehandle_table[local_id].fd = fd;
}
28 changes: 28 additions & 0 deletions src/unit-test-coverage/portable/src/coveragetest-bsd-select.c
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,13 @@ void Test_OS_SelectSingle_Impl(void)
UT_SetDataBuffer(UT_KEY(OCS_clock_gettime), &nowtime, sizeof(nowtime), false);
UT_SetDataBuffer(UT_KEY(OCS_clock_gettime), &latertime, sizeof(latertime), false);
OSAPI_TEST_FUNCTION_RC(OS_SelectSingle_Impl, (&token, &SelectFlags, 2100), OS_ERROR);

/* Test cases where the FD exceeds FD_SETSIZE */
SelectFlags = OS_STREAM_STATE_READABLE | OS_STREAM_STATE_WRITABLE;
UT_PortablePosixIOTest_Set_FD(UT_INDEX_0, OCS_FD_SETSIZE);
UT_PortablePosixIOTest_Set_Selectable(UT_INDEX_0, true);
OSAPI_TEST_FUNCTION_RC(OS_SelectSingle_Impl, (&token, &SelectFlags, 0), OS_ERR_OPERATION_NOT_SUPPORTED);

} /* end OS_SelectSingle_Impl */

void Test_OS_SelectMultiple_Impl(void)
Expand All @@ -81,13 +88,34 @@ void Test_OS_SelectMultiple_Impl(void)
OS_FdSet ReadSet;
OS_FdSet WriteSet;

UT_PortablePosixIOTest_Set_FD(UT_INDEX_0, 0);
UT_PortablePosixIOTest_Set_Selectable(UT_INDEX_0, true);

memset(&ReadSet, 0, sizeof(ReadSet));
memset(&WriteSet, 0xff, sizeof(WriteSet));
OSAPI_TEST_FUNCTION_RC(OS_SelectMultiple_Impl, (&ReadSet, &WriteSet, 0), OS_SUCCESS);
memset(&ReadSet, 0xff, sizeof(ReadSet));
memset(&WriteSet, 0, sizeof(WriteSet));
UT_SetDefaultReturnValue(UT_KEY(OCS_select), 0);
OSAPI_TEST_FUNCTION_RC(OS_SelectMultiple_Impl, (&ReadSet, &WriteSet, 1), OS_ERROR_TIMEOUT);

/* Test where the FD set is empty */
memset(&ReadSet, 0, sizeof(ReadSet));
memset(&WriteSet, 0, sizeof(WriteSet));
OSAPI_TEST_FUNCTION_RC(OS_SelectMultiple_Impl, (NULL, NULL, 0), OS_ERR_INVALID_ID);

/* Test cases where the FD exceeds FD_SETSIZE in the read set */
UT_PortablePosixIOTest_Set_FD(UT_INDEX_0, OCS_FD_SETSIZE);
UT_PortablePosixIOTest_Set_Selectable(UT_INDEX_0, true);
memset(&ReadSet, 0xff, sizeof(ReadSet));
memset(&WriteSet, 0, sizeof(WriteSet));
OSAPI_TEST_FUNCTION_RC(OS_SelectMultiple_Impl, (&ReadSet, &WriteSet, 0), OS_ERR_OPERATION_NOT_SUPPORTED);

/* Test cases where the FD exceeds FD_SETSIZE in the write set */
memset(&ReadSet, 0, sizeof(ReadSet));
memset(&WriteSet, 0xff, sizeof(WriteSet));
OSAPI_TEST_FUNCTION_RC(OS_SelectMultiple_Impl, (&ReadSet, &WriteSet, 0), OS_ERR_OPERATION_NOT_SUPPORTED);

} /* end OS_SelectMultiple_Impl */

/* ------------------- End of test cases --------------------------------------*/
Expand Down
2 changes: 2 additions & 0 deletions src/unit-test-coverage/ut-stubs/inc/OCS_sys_select.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@
/* constants normally defined in sys/select.h */
/* ----------------------------------------- */

#define OCS_FD_SETSIZE 10

/* ----------------------------------------- */
/* types normally defined in sys/select.h */
/* ----------------------------------------- */
Expand Down
2 changes: 2 additions & 0 deletions src/unit-test-coverage/ut-stubs/override_inc/sys/select.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,4 +50,6 @@
#define FD_CLR OCS_FD_CLR
#define FD_ZERO OCS_FD_ZERO

#define FD_SETSIZE OCS_FD_SETSIZE

#endif /* SELECT_H */