Skip to content

posix: mqueue: pop mode as int with va_arg() #67071

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

Conversation

cfriedt
Copy link
Member

@cfriedt cfriedt commented Dec 29, 2023

There was some discussion about whether it was suitable to have an architecture-specific workaround in mqueue.c after that workaround was copied to a different source file in #67007.

The original issue was that newlib and picolibc declare mode_t to be unsigned short (16-bits) instead of unsigned long when __svr4__ is not defined along with __sparc__. This is specifically impactful, because va_arg() deals (mainly) with 32-bit and 64-bit values that are all naturally aligned to 4 bytes (or 8 bytes)

#if defined(__sparc__) && !defined(__sparc_v9__)
#ifdef __svr4__
typedef unsigned long __mode_t;
#else
typedef unsigned short __mode_t;
#endif

A uint16_t is naturally aligned to 2 bytes, so not only would a 16-bit mode_t be corrupted, it would also generate a warning with recent gcc versions which is promoted to error (rightfully so) when run through CI.

mqueue.c:61:35: error: 'mode_t' {aka 'short unsigned int'} is
  promoted to 'int' when passed through '...' [-Werror]
   61 |                 mode = va_arg(va, mode_t);

Instead of using an architecture-specific workaround, simply add a build assert that the size of mode_t is less than or equal to the size of an int, and use an int to retrieve it via va_arg().

Also ensure that we allow testing via qemu_leon3 which was not part of the fix in 6d126e7.

keith-packard
keith-packard previously approved these changes Dec 29, 2023
Copy link
Collaborator

@keith-packard keith-packard left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd be slightly tempted to use 'unsigned int' instead of 'int', just to make the two types have the same 'signedness'.

@cfriedt
Copy link
Member Author

cfriedt commented Dec 30, 2023

I'd be slightly tempted to use 'unsigned int' instead of 'int', just to make the two types have the same 'signedness'.

That's a good point - better to be safe than sorry!

@cfriedt cfriedt force-pushed the posix-mqueue-always-use-int-for-mode-t-va-arg branch from bc20f53 to 100e765 Compare December 30, 2023 21:08
@cfriedt
Copy link
Member Author

cfriedt commented Dec 30, 2023

@keith-packard - fixed!

There was some discussion about whether it was suitable to have
an architecture-specific workaround in mqueue.c after that
workaround was copied to a different source file in a PR.

The original issue was that newlib and picolibc declare mode_t
to be unsigned short instead of unsigned long when __svr4__
is not defined along with __sparc__. This is specifically
impactful, because va_arg() deals (mainly) with 32-bit and
64-bit values that are all naturally aligned to 4 bytes.

#if defined(__sparc__) && !defined(__sparc_v9__)
#ifdef __svr4__
typedef unsigned long __mode_t;
#else
typedef unsigned short __mode_t;
#endif

A uint16_t is naturally aligned to 2 bytes, so not only would
a 16-bit mode_t be corrupted, it would also generate a warning
with recent gcc versions which is promoted to error (rightfully
so) when run through CI.

mqueue.c:61:35: error: 'mode_t' {aka 'short unsigned int'} is
  promoted to 'int' when passed through '...' [-Werror]
   61 |                 mode = va_arg(va, mode_t);

Instead of using an architecture-specific workaround, simply
add a build assert that the size of mode_t is less than or
equal to the size of an int, and use an int to retrieve it
via va_arg().

Signed-off-by: Christopher Friedt <[email protected]>

# Please enter the commit message for your changes. Lines starting
# with '#' will be kept; you may remove them yourself if you want to.
# An empty message aborts the commit.
#
# Date:      Fri Dec 29 10:06:44 2023 -0500
#
# On branch posix-mqueue-always-use-int-for-mode-t-va-arg
# Changes to be committed:
#	modified:   lib/posix/mqueue.c
#	modified:   tests/posix/common/testcase.yaml
#
@cfriedt cfriedt force-pushed the posix-mqueue-always-use-int-for-mode-t-va-arg branch from 100e765 to aa88d9d Compare December 30, 2023 21:11
@cfriedt cfriedt merged commit 10156f5 into zephyrproject-rtos:main Jan 1, 2024
@cfriedt cfriedt deleted the posix-mqueue-always-use-int-for-mode-t-va-arg branch January 26, 2024 15:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area: POSIX POSIX API Library
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants