Skip to content

Fix buffer overflow and nul-byte replacement in error handling#243

Open
urschrei wants to merge 1 commit intomainfrom
fix_buffer_overflow
Open

Fix buffer overflow and nul-byte replacement in error handling#243
urschrei wants to merge 1 commit intomainfrom
fix_buffer_overflow

Conversation

@urschrei
Copy link
Member

  • Add bounds checking using error_string_max_size before writing error strings
  • Fix incorrect character replacement: use '\0' (nul byte) instead of '0' (digit)

NB: this PR is tool-assisted (Claude Opus 4.5)

  • I agree to follow the project's code of conduct.
  • I added an entry to the project's change log file if knowledge of this change could be valuable to users.
    • Usually called CHANGES.md or CHANGELOG.md
    • Prefix changelog entries for breaking changes with "BREAKING: "

@urschrei urschrei force-pushed the fix_buffer_overflow branch from 42f9e11 to 08332dc Compare February 4, 2026 19:26
let err_string = e.to_string();
out_error_string.copy_from_nonoverlapping(err_string.as_ptr().cast(), err_string.len());
out_error_string.add(err_string.len()).write(0);
let len = err_string
Copy link
Member

Choose a reason for hiding this comment

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

Before talking about the new code - I'm a bit confused by the previous code.

Isn't this redundant with what already happens inside _network_open? Why are we "re-copying" the error text?

Copy link
Member Author

Choose a reason for hiding this comment

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

I don't think so? The error originates in Rust code (in _network_open()), and we check for an error, returning early to the facade if it does. I don't think we're re-copying anything: we're copying the stringified Rust error message into the libproj buffer.

Copy link
Member

Choose a reason for hiding this comment

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

Sorry, you're right!

- Add bounds checking using error_string_max_size before writing error strings
- Fix incorrect character replacement: use '\0' (nul byte) instead of '0' (digit)


Signed-off-by: Stephan Hügel <shugel@tcd.ie>
@urschrei urschrei force-pushed the fix_buffer_overflow branch 2 times, most recently from a081b87 to e7b9040 Compare February 5, 2026 12:25
Copy link
Member

@michaelkirk michaelkirk left a comment

Choose a reason for hiding this comment

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

This seems like an improvement, good finds!

let err_string = e.to_string().replace('0', "nought");
out_error_string.copy_from_nonoverlapping(err_string.as_ptr().cast(), err_string.len());
out_error_string.add(err_string.len()).write(0);
let err_string = e.to_string().replace('\0', "");
Copy link
Member

@michaelkirk michaelkirk Feb 5, 2026

Choose a reason for hiding this comment

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

I agree, the previous code was wrong (the character '0' is not the null terminator).

// since this isn't a conversion using CString, nul chars must be manually stripped

This error message is coming from rust code, so the purpose of this code is to detect the situation where some rust developer includes a NULL in their string output, right?

Rust strings can contain NULL (as many times as they want) but it seems absolutely unhinged to do so. If we do want to be protective in this way, I guess we should check on line 164 too?

Also (take it or leave it), could we use the CString handling? I think it'd look something like:

Err(e) => {
  let err_string = CString::new(e.to_string()).unwrap_or(c"Error while buildling error message: Unable to report error specifics".into());
  let bytes = &err_string.as_bytes_with_nul();
  let len = bytes.len().min(error_string_max_size);
  out_error_string.copy_from_nonoverlapping(bytes.as_ptr().cast(), len);
  0
}

Is it "better"? IDK. Interacting with C is such a bummer.

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