Skip to content

posix: make posix access modes enum fields#753

Draft
oI0ck wants to merge 1 commit intomasterfrom
michal.lach/accmode_enum
Draft

posix: make posix access modes enum fields#753
oI0ck wants to merge 1 commit intomasterfrom
michal.lach/accmode_enum

Conversation

@oI0ck
Copy link
Copy Markdown
Member

@oI0ck oI0ck commented Mar 26, 2026

Most POSIX conformant/compilant systems treat O_ACCMODE fields as enum fields, not bitfields, which carries on to their usage semantics, making it impossible to repesent states when modes are not mutually exclusive.

JIRA: RTOS-1088

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Chore (refactoring, style fixes, git/CI config, submodule management, no code logic changes)

How Has This Been Tested?

  • Already covered by automatic testing.
  • New test added: (add PR link here).
  • Tested by hand on: ia32-generic-qemu, armv7a9-zynq7000-qemu.

Checklist:

  • My change requires a change to the documentation.
  • I have updated the documentation accordingly.
  • I have added tests to cover my changes.
  • All new and existing linter checks and tests passed.
  • My changes generate no new compilation warnings for any of the targets.

Special treatment

  • This PR needs additional PRs to work (list the PRs, preferably in merge-order).
  • I will merge this PR by myself when appropriate.

@oI0ck oI0ck force-pushed the michal.lach/accmode_enum branch from 2d22040 to 8b84664 Compare March 26, 2026 15:13
Copy link
Copy Markdown

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request updates the POSIX file access mode constants (O_RDONLY, O_WRONLY, O_RDWR) from bitfield flags to enum-style values and introduces a new O_ACCMODE mask. While this aligns with POSIX standards, the change is critical as it breaks existing bitwise logic throughout the codebase. Specifically, since O_RDONLY is now 0, existing checks for read-only status will fail, potentially allowing unauthorized writes or truncations. A full audit and update of all access mode checks using O_ACCMODE is required to prevent these regressions.

Comment on lines +28 to +30
#define O_RDONLY 0x00000U
#define O_WRONLY 0x00001U
#define O_RDWR 0x00002U
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

critical

Changing these access modes from bitfields to enum-style values has consequences in other parts of the code that are not updated in this PR. This can lead to critical bugs.

  • Writing to read-only files: Checks like (f->status & O_RDONLY) != 0U in posix_write() (posix/posix.c:786) will always be false because O_RDONLY is now 0. This allows writing to files opened as read-only. This is a critical issue.

  • Truncating read-only files: Similarly, (f->status & O_RDONLY) == 0U in posix_ftruncate() (posix/posix.c:1278) will always be true, allowing truncation of read-only files.

  • Incorrect pipe creation: Expressions like O_RDONLY | O_WRONLY now evaluate to O_WRONLY. This is used in posix_pipe() (posix/posix.c:981) and likely breaks pipe creation, which should be read/write. It should probably be O_RDWR.

All checks on access modes should be updated to use O_ACCMODE. For example:

  • To check for read-only: (flags & O_ACCMODE) == O_RDONLY
  • To check for not read-only: (flags & O_ACCMODE) != O_RDONLY
  • To check for write-only: (flags & O_ACCMODE) == O_WRONLY

Please audit all usages of O_RDONLY, O_WRONLY, and O_RDWR in the codebase and update them accordingly.

@oI0ck oI0ck marked this pull request as draft March 26, 2026 15:32
@oI0ck oI0ck force-pushed the michal.lach/accmode_enum branch 2 times, most recently from 5f8b0bb to 602aae3 Compare March 26, 2026 15:49
Most POSIX conformant/compilant systems treat O_ACCMODE fields as enum
fields, not bitfields, which carries on to their usage semantics,
making it impossible to repesent states when modes are not mutually
exclusive.

JIRA: RTOS-1088
@oI0ck oI0ck force-pushed the michal.lach/accmode_enum branch from 602aae3 to a41e233 Compare March 26, 2026 15:53
@github-actions
Copy link
Copy Markdown

Unit Test Results

9 508 tests   - 45   8 770 ✅  - 191   58m 1s ⏱️ + 4m 52s
  591 suites ± 0     592 💤 ±  0 
    1 files   ± 0     146 ❌ +146 

For more details on these failures, see this check.

Results for commit a41e233. ± Comparison against base commit 09ea2db.

This pull request removes 54 and adds 9 tests. Note that renamed tests count towards both.
phoenix-rtos-tests/libc/stdio ‑ aarch64a53-zynqmp-qemu:phoenix-rtos-tests/libc/stdio.stdio_fflush.stdio_fflush_eagain
phoenix-rtos-tests/libc/stdio ‑ aarch64a53-zynqmp-qemu:phoenix-rtos-tests/libc/stdio.stdio_fflush.stdio_fflush_socket
phoenix-rtos-tests/libc/stdio ‑ aarch64a53-zynqmp-qemu:phoenix-rtos-tests/libc/stdio.stdio_fread.stdio_fread_buffered_refill
phoenix-rtos-tests/libc/stdio ‑ aarch64a53-zynqmp-qemu:phoenix-rtos-tests/libc/stdio.stdio_fwrite.stdio_fwrite_buffered_error
phoenix-rtos-tests/libc/stdio ‑ aarch64a53-zynqmp-qemu:phoenix-rtos-tests/libc/stdio.stdio_fwrite.stdio_fwrite_espipe
phoenix-rtos-tests/libc/stdio ‑ aarch64a53-zynqmp-qemu:phoenix-rtos-tests/libc/stdio.stdio_fwrite.stdio_fwrite_unbuffered_error
phoenix-rtos-tests/libc/stdio ‑ armv7a7-imx6ull-evk:phoenix-rtos-tests/libc/stdio.stdio_fflush.stdio_fflush_eagain
phoenix-rtos-tests/libc/stdio ‑ armv7a7-imx6ull-evk:phoenix-rtos-tests/libc/stdio.stdio_fflush.stdio_fflush_socket
phoenix-rtos-tests/libc/stdio ‑ armv7a7-imx6ull-evk:phoenix-rtos-tests/libc/stdio.stdio_fread.stdio_fread_buffered_refill
phoenix-rtos-tests/libc/stdio ‑ armv7a7-imx6ull-evk:phoenix-rtos-tests/libc/stdio.stdio_fwrite.stdio_fwrite_buffered_error
…
phoenix-rtos-tests/libc/stdio ‑ aarch64a53-zynqmp-qemu:phoenix-rtos-tests/libc/stdio
phoenix-rtos-tests/libc/stdio ‑ armv7a7-imx6ull-evk:phoenix-rtos-tests/libc/stdio
phoenix-rtos-tests/libc/stdio ‑ armv7a9-zynq7000-qemu:phoenix-rtos-tests/libc/stdio
phoenix-rtos-tests/libc/stdio ‑ armv7a9-zynq7000-zedboard:phoenix-rtos-tests/libc/stdio
phoenix-rtos-tests/libc/stdio ‑ armv7m4-stm32l4x6-nucleo:phoenix-rtos-tests/libc/stdio
phoenix-rtos-tests/libc/stdio ‑ armv7m7-imxrt106x-evk:phoenix-rtos-tests/libc/stdio
phoenix-rtos-tests/libc/stdio ‑ armv7m7-imxrt117x-evk:phoenix-rtos-tests/libc/stdio
phoenix-rtos-tests/libc/stdio ‑ ia32-generic-qemu:phoenix-rtos-tests/libc/stdio
phoenix-rtos-tests/libc/stdio ‑ riscv64-generic-qemu:phoenix-rtos-tests/libc/stdio

#define O_RDONLY 0x00001U
#define O_WRONLY 0x00002U
#define O_RDWR 0x00004U
/*
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

technically we could decide to not change the numeric values of these defines - that way we will keep binary compatibility (so the change would not be breaking)?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Technically, yes, though, having none of these bits set is an invalid state, which is why I marginally prefer starting with 0, although even with constants starting from 0, one could have a 11 state, which is also incorrect, so that might not matter as much as I'd like it to.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

@Darchiv What do you think?

@oI0ck oI0ck requested a review from Darchiv March 30, 2026 14:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants