Skip to content

buffer: add optional -fbounds-safety annotations for struct buffer - #1105

Open
LaptopsPlural wants to merge 4 commits into
OpenVPN:masterfrom
LaptopsPlural:local/buffer-fbounds-safety
Open

LaptopsPlural wants to merge 4 commits into
OpenVPN:masterfrom
LaptopsPlural:local/buffer-fbounds-safety

Conversation

@LaptopsPlural

@LaptopsPlural LaptopsPlural commented Sep 11, 2026

Copy link
Copy Markdown

Summary

Secure-by-design memory-safety hardening. Annotates struct buffer.data with optional Clang -fbounds-safety / sized-by macros tied to capacity. Default builds unchanged (ENABLE_FBOUNDS_SAFETY OFF).

Per CONTRIBUTING: GitHub PRs are for discussion; will also send git format-patch to openvpn-devel / Gerrit for merge.

Contributor: Jeff Bindel via LaptopsPlural. Not a vulnerability PoC.

Test plan

  • Default configure/make
  • Optional bounds-safety ON with supporting Clang

Introduce inert OVPN_SIZED_BY*_ macros (OFF by default) and annotate the
struct buffer data/capacity pair used on packet paths. Capacity-first
assign already present in alloc paths (documented). Default builds
unchanged; ENABLE_FBOUNDS_SAFETY / --enable-fbounds-safety opt-in for
experimental Clang toolchains.

Signed-off-by: Jeff <jeff@incrediblybased.co>
Align trailing comments and preprocessor macros with project
.clang-format so the style CI check passes.

Signed-off-by: Jeff <jeff@incrediblybased.co>

@flichtenheld flichtenheld left a comment

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.

Definitely looks interesting. The changes are overly verbose, see my comments. My understanding is that this is currently only available in Apple's clang fork?

Comment thread src/openvpn/buffer_bounds_safety.h Outdated

#else /* !OVPN_SUPPORT_FBOUNDS_SAFETY */

#define OVPN_SIZED_BY(n)

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.

Why use the additional indirection? Can't we just do

#define __sized_by(n)

Comment thread CMakeLists.txt Outdated
# macros in src/openvpn/buffer_bounds_safety.h are inert and the ABI/build is unchanged.
# When ON, requires a Clang that provides -fbounds-safety / <ptrcheck.h>.
option(ENABLE_FBOUNDS_SAFETY "Enable experimental Clang -fbounds-safety annotations (OFF by default)" OFF)
if(ENABLE_FBOUNDS_SAFETY)

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.

We have no status message for other options, so this is not required

Comment thread src/openvpn/buffer.h Outdated
* within the allocated memory. */
int len; /**< Length in bytes of the actual content
* within the allocated memory. */
/* Field order already has capacity before data; alloc / set

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.

Comment is mostly redundant

Comment thread src/openvpn/buffer.h Outdated
uint8_t *data; /**< Pointer to the allocated memory. */
int capacity; /**< Size in bytes of memory allocated by
* \c malloc(). Capacity companion for
* \c data under optional -fbounds-safety. */

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.

comment change is redundant and not required

Comment thread src/openvpn/buffer.c Outdated
{
buf_size_error(size);
}
/* Capacity before pointer so sized_by invariants hold under -fbounds-safety. */

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.

All these additional comments are not required

Comment thread src/openvpn/buffer_bounds_safety.h Outdated

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.

Not sure this warrants its own file. Might be small enough to put into compat.h or syshead.h

Move inert __sized_by* stubs into compat.h, drop OVPN_* wrappers
and buffer_bounds_safety.h, restore compact buffer comments, and
remove ENABLE_FBOUNDS_SAFETY status chatter from CMake/configure.

Signed-off-by: Jeff <jeff@incrediblybased.co>
@LaptopsPlural

Copy link
Copy Markdown
Author

Thanks @flichtenheld — good catches. Slimmed this per your review:

  • Moved the inert __sized_by / __sized_by_or_null / __counted_by / __counted_by_or_null stubs into compat.h and dropped buffer_bounds_safety.h plus the OVPN_* wrappers; struct buffer now annotates data with __sized_by_or_null(capacity) directly.
  • Restored the compact original doxygen on capacity/offset/len/data and removed the narrating comments in buffer.c.
  • Trimmed the ENABLE_FBOUNDS_SAFETY status MESSAGE/AC_MSG_NOTICE noise (option/flag still opt-in, OFF by default).

On Apple Clang: yes — -fbounds-safety originated in Apple’s Clang fork and is still experimental / not available in all mainline toolchains. That’s why the stubs stay inert by default so normal builds are unchanged.

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