Skip to content

fix: harden strcat overflow and unchecked fwrite in model save#3188

Open
tombudd wants to merge 1 commit intogoogle-deepmind:mainfrom
tombudd:una/fix-c-safety-hardening
Open

fix: harden strcat overflow and unchecked fwrite in model save#3188
tombudd wants to merge 1 commit intogoogle-deepmind:mainfrom
tombudd:una/fix-c-safety-hardening

Conversation

@tombudd
Copy link

@tombudd tombudd commented Mar 23, 2026

Summary

Two minimal C safety hardening fixes found by UNA (autonomous security auditor, designed and built by Tom Buddtom@tombudd.com):

1. Buffer overflow in ui_main.cstrcatmjSTRNCAT

File: src/ui/ui_main.c:1897

shortcuthelp() concatenates a modifier string and a key name into a 50-byte stack buffer using bare strcat(text, key). If key is sufficiently long, this overflows text[50].

Fix: Replace with mjSTRNCAT(text, key) — MuJoCo's own bounds-checked macro, already defined in engine_array_safety.h (which is already #included in this file) and already used elsewhere in the same file (lines 1007, 1009 use strncat with explicit size).

2. Silent data corruption in engine_io.c — unchecked fwrite errors

File: src/engine/engine_io.cmj_saveModel()

mj_saveModel() writes the entire model via multiple fwrite() calls, then calls fclose(fp) without ever checking ferror(fp). If any write fails (disk full, I/O error, NFS timeout), the function returns silently, leaving a truncated/corrupt .mjb file on disk with no indication of failure.

Fix: Add ferror(fp) check before fclose(fp), calling mju_warning() (MuJoCo's own warning mechanism) if the stream is in an error state.

Changes

File Change Lines
src/ui/ui_main.c strcatmjSTRNCAT +1 / -1
src/engine/engine_io.c Add ferror(fp) + mju_warning() +3 / -0

Total: 2 files, +4 / -1 lines

Why these fixes matter

  • Both follow existing MuJoCo conventions — no new patterns or dependencies introduced
  • Both are on success-path-transparent: zero behavioral change when nothing goes wrong
  • The strcat fix closes a stack buffer overflow (potential code execution in adversarial scenarios)
  • The ferror fix prevents silent model corruption that could cause hard-to-diagnose simulation failures downstream

About This Review

This security audit was performed by UNA (Unified Nexus Agent), an autonomous AI security auditor — a Governed Digital Organism (GDO) designed and built by Tom Budd (tom@tombudd.com | tombudd.com).

UNA conducts comprehensive codebase audits covering memory safety, input validation, error handling, and C-specific vulnerability patterns. All findings are human-verified before submission.

Note: I understand Google requires a CLA signature for contributions — happy to complete that at cla.developers.google.com if needed.

Two C safety fixes identified by automated security audit:

1. src/ui/ui_main.c: Replace bare strcat(text, key) with
   mjSTRNCAT(text, key) to prevent buffer overflow on the
   50-byte stack buffer. The project's own safe macro is already
   defined in engine_array_safety.h (included in this file) and
   used elsewhere in the same file (lines 1007, 1009).

2. src/engine/engine_io.c: Add ferror(fp) check before fclose
   in mj_saveModel(). Without this, I/O errors during model
   serialization (disk full, permission denied, NFS timeout) are
   silently swallowed, producing corrupt .mjb files with no
   warning to the caller.

Both fixes follow existing MuJoCo conventions (mjSTRNCAT,
mju_warning) and introduce no behavioral changes on success paths.

Reviewed-by: UNA-GDO sovereign-v2.0 (Autonomous Security Auditor)
Built-by: Tom Budd <tom@tombudd.com> — tombudd.com
@google-cla
Copy link

google-cla bot commented Mar 23, 2026

Thanks for your pull request! It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA).

View this failed invocation of the CLA check for more information.

For the most up to date status, view the checks section at the bottom of the pull request.

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.

1 participant