Skip to content

emitbc: Avoid undefined behavior calling memset() #3799

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

Closed

Conversation

jepler
Copy link
Contributor

@jepler jepler commented May 19, 2018

When micropython is built with 'clang -fsanitize=undefined', a diagnostic like the following will occur:

$ UBSAN_OPTIONS=abort_on_error=1 ./micropython_fuzzing  -c 'print(1)'
../../py/emitbc.c:319:16: runtime error: null pointer passed as argument 1, which is declared to never be null
/usr/include/string.h:62:62: note: nonnull attribute specified here
Aborted

Traditionally, memset(NULL, value, 0) has been accepted without causing problems. However, it is not standards-compliant behavior; and for instance Ted Unangst of the OpenBSD project notes that "A smart C compiler may observe a call to memcpy, flag both pointers as valid, and then delete any null checks. Forwards and backwards."
https://www.tedunangst.com/flak/post/zero-size-objects

Since micropython is using -fdelete-null-pointer-checks ("enabled by default on most targets") and it is probably giving good code size improvements, we have to pay a modest price and add a few checks.

When micropython is built with 'clang -fsanitize=undefined', a diagnostic
like the following will occur:

$ UBSAN_OPTIONS=abort_on_error=1 ./micropython_fuzzing  -c 'print(1)'
../../py/emitbc.c:319:16: runtime error: null pointer passed as argument 1, which is declared to never be null
/usr/include/string.h:62:62: note: nonnull attribute specified here
Aborted

Traditionally, memset(NULL, value, 0) has been accepted without causing
problems.  However, it is not standards-compliant behavior; and for
instance Ted Unangst of the OpenBSD project notes that "A smart C compiler
may observe a call to memcpy, flag both pointers as valid, and then
delete any null checks. Forwards and backwards."
    https://www.tedunangst.com/flak/post/zero-size-objects

Since micropython is using -fdelete-null-pointer-checks ("enabled by
default on most targets") and it is probably giving good code size
improvements, we have to pay a modest price and add a few checks.
@dpgeorge
Copy link
Member

Thanks! I agree with the analysis here, than memset should not be passed NULL and so the right thing to do is check the pointer first (because it is NULL on the first pass of the compiler). Merged in bc6c0b2

@dpgeorge dpgeorge closed this May 21, 2018
tannewt added a commit to tannewt/circuitpython that referenced this pull request Dec 8, 2020
@jepler jepler deleted the emitb-memset-undefined-behavior branch March 27, 2025 02:05
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