GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — gh-102509: Start initializing `ob_digit` of `_PyLongValue` by illia-v · Pull Request #102510 · python/cpython

Conversation

@illia-v

@illia-v illia-v commented Mar 7, 2023 •
edited by bedevere-bot
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown
Contributor

https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=51574 detected an uninitialized value.

I can reproduce the error by running CC=clang ./configure --with-memory-sanitizer && make -j12 locally. When I initialize result->long_value.ob_digit[0] explicitly, the error looks to be fixed (actually a new error similar to one described in #91043 (comment) appears.)

  • Issue: cpython3:fuzz_builtin_unicode: Use-of-uninitialized-value in maybe_small_long #102509

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
@illia-v
pythongh-102509: Start initializing ob_digit of _PyLongValue
e13f099
@bedevere-bot bedevere-bot mentioned this pull request Mar 7, 2023
cpython3:fuzz_builtin_unicode: Use-of-uninitialized-value in maybe_small_long #102509
Closed
@bedevere-bot bedevere-bot added the awaiting review label Mar 7, 2023
@illia-v illia-v mentioned this pull request Mar 7, 2023
./Programs/_freeze_module fails with MSAN: Uninitialized value was created by an allocation of 'stat.i' #91043
Closed
@terryjreedy
terryjreedy requested review from ammaraskar and ezio-melotti March 7, 2023 20:55
@mdickinson
mdickinson self-requested a review March 8, 2023 13:35
@illia-v
Merge branch 'main' into pythongh-102509
3d240a8
@mdickinson

mdickinson commented Mar 18, 2023 •
edited
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown
Member

@illia-v Can you provide Python code that reproduces the access of the uninitialized value? The theory is that it shouldn't matter that this digit is uninitialized when ob_size = 0, since it should never be accessed. I think the right fix is to find out where we're breaking that assumption.

I'm not convinced that _PyLong_New is the right place to fix this.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@mdickinson

mdickinson commented Mar 18, 2023

Copy link
Copy Markdown
Member

I think I see. In the case ob_size=0, we are reading a potentially uninitialised value ob_digit[0], in medium_value, but we then always multiply it by zero. I admit this does make me a bit twitchy, but I think it's fine in practice. Reading uninitialised memory is not undefined behaviour: we'll just get a random integer. (In theory we could get a trap representation, but I don't think trap representations have met real machines running CPython in some number of decades, and we already assume elsewhere that we're working with integer types with no trap representations.) We then multiply that random integer by zero, which will always give zero.

So I think this counts as a false positive, and no fix is necessary.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@mdickinson

mdickinson commented Mar 18, 2023

Copy link
Copy Markdown
Member

Pinging @markshannon, who introduced this logic: Mark, I don't see any issue here, and think this should be closed. Agreed?

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@mdickinson

mdickinson commented Mar 18, 2023

Copy link
Copy Markdown
Member

It may still be worth adding a comment in medium_value to the effect that yes, we know this is accessing allocated but potentially uninitialized memory, and that's okay.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@mdickinson

mdickinson commented Mar 18, 2023

Copy link
Copy Markdown
Member

I admit this does make me a bit twitchy [...]

To be clear, if this weren't a hot path then I'd probably add the extra initialization just for peace of mind, but _PyLong_New is a hot path, where we don't want to be doing any more work than strictly necessary.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@markshannon

markshannon commented Mar 18, 2023

Copy link
Copy Markdown
Member

This does seem to be a real bug.
When working on #102464, I added an assert that zero sized ints had ob_digit[0] == 0. The assertion failed and we never set ob_digit[0] to non-zero if ob_size == 0.

Reading uninitialised memory is not undefined behaviour

Are you sure about this?
The real issue is whether C guarantees that 0 * unitialized_value == 0 and I'm not sure that is does.
It probably should, but you know much C likes undefined behavior 🙁

I expect this code to go when #101291 is implemented, so we might as well fix it for now.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@mdickinson

mdickinson commented Mar 18, 2023

Copy link
Copy Markdown
Member

Are you sure about this?

Fairly sure, yes. :-) We either get an uninitialised value (which is fine), or a trap representation (which is not), but trap representations in integers are not a practical problem these days.

Here's a good Stack Overflow answer by Eric Postpischil that quotes chapter and verse: https://stackoverflow.com/a/66840190/270986

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@mdickinson

mdickinson commented Mar 18, 2023

Copy link
Copy Markdown
Member

The real issue is whether C guarantees that 0 * unitialized_value == 0 and I'm not sure that is does.

It should be fine - at that point, the uninitialised value is some value of type digit. And every single legal value of type digit, when multiplied by zero, gives zero.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@illia-v

illia-v commented Mar 18, 2023

Copy link
Copy Markdown
Contributor Author

I think I see. In the case ob_size=0, we are reading a potentially uninitialised value ob_digit[0], in medium_value, but we then always multiply it by zero.

I am not very familiar with this part of CPython source, but comments and code itself mention not only ob_size=0 but also -1 and 1, are not they?

cpython/Objects/longobject.c

Lines 25 to 34 in 3adb23a

/* Is this PyLong of size 1, 0 or -1? */
#define IS_MEDIUM_VALUE(x) (((size_t)Py_SIZE(x)) + 1U < 3U)
/* convert a PyLong of size 1, 0 or -1 to a C integer */
static inline stwodigits
medium_value(PyLongObject *x)
{
assert(IS_MEDIUM_VALUE(x));
return ((stwodigits)Py_SIZE(x)) * x->long_value.ob_digit[0];
}

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@mdickinson

mdickinson commented Mar 19, 2023

Copy link
Copy Markdown
Member

I am not very familiar with this part of CPython source, but comments and code itself mention not only ob_size=0 but also -1 and 1, are not they?

Yes, but if ob_size == 1 or ob_size == -1 then we're guaranteed that ob_digit[0] has been initialized. It's only in the case ob_size == 0 when we can end up with an uninitialized digit.

If this goes in, we should have a comment explaining why the extra initialization is necessary (possibly with a pointer to this PR or the associated issue), and this comment in longintrepr.h needs updating, too. (I added that comment previously, having already noticed the uninitialised access and figured out that it was safe; I'd assumed that @markshannon had done this intentionally.)

My preferred solution here would be to go back to a more obviously correct spelling for medium_value that only accesses ob_digit[0] when ob_size is nonzero.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@erlend-aasland erlend-aasland mentioned this pull request Mar 22, 2023
gh-102509: Ignore acceptable access of an uninitialized value #102838
Closed
@mdickinson
mdickinson removed their request for review May 22, 2023 15:01
@illia-v
Merge branch 'main' into pythongh-102509
d1016a6
@AlexWaygood
AlexWaygood requested review from gpshead and markshannon July 28, 2023 12:55
@markshannon

markshannon commented Jul 28, 2023

Copy link
Copy Markdown
Member

The performance impact of this change is in the noise.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

markshannon
markshannon approved these changes Jul 28, 2023
View reviewed changes
@bedevere-bot bedevere-bot added awaiting merge and removed awaiting review labels Jul 28, 2023
@markshannon

markshannon commented Jul 28, 2023

Copy link
Copy Markdown
Member

We expect the internals of PyLongObject to change again, which may make this change obsolete for 3.13 (but worth doing anyway).
The question is "should we backport this to 3.12?"
@Yhg1s

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@markshannon
markshannon merged commit fc130c4 into python:main Jul 28, 2023
@bedevere-bot bedevere-bot removed the awaiting merge label Jul 28, 2023
@gpshead gpshead added the needs backport to 3.12 only security fixes label Jul 30, 2023
@miss-islington

miss-islington commented Jul 30, 2023

Copy link
Copy Markdown
Contributor

Thanks @illia-v for the PR, and @markshannon for merging it 🌮🎉.. I'm working now to backport this PR to: 3.12.
🐍🍒⛏🤖

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@bedevere-bot

bedevere-bot commented Jul 30, 2023

Copy link
Copy Markdown

GH-107464 is a backport of this pull request to the 3.12 branch.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@bedevere-bot bedevere-bot removed the needs backport to 3.12 only security fixes label Jul 30, 2023
miss-islington pushed a commit to miss-islington/cpython that referenced this pull request Jul 30, 2023
@illia-v @miss-islington
pythongh-102509: Start initializing ob_digit of _PyLongValue (pyt…
47b91f5
…honGH-102510)

(cherry picked from commit fc130c4)

Co-authored-by: Illia Volochii <[email protected]>
Yhg1s pushed a commit that referenced this pull request Jul 31, 2023
@miss-islington @illia-v
[3.12] gh-102509: Start initializing ob_digit of _PyLongValue (GH…
8f080a2
…-102510) (#107464)

gh-102509: Start initializing `ob_digit` of `_PyLongValue` (GH-102510)
(cherry picked from commit fc130c4)

Co-authored-by: Illia Volochii <[email protected]>
@sobolevn sobolevn mentioned this pull request May 14, 2024
Valgrind: Conditional jump or move depends on uninitialised value in ob_digit[0] of PyLongObject #119022
Closed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Reviewers

@markshannon markshannon markshannon approved these changes
@ezio-melotti ezio-melotti Awaiting requested review from ezio-melotti
@ammaraskar ammaraskar Awaiting requested review from ammaraskar
@gpshead gpshead Awaiting requested review from gpshead

Uh oh!

There was an error while loading. Please reload this page.

Assignees

No one assigned

Labels

None yet

Projects

None yet

Milestone

No milestone

Development

Successfully merging this pull request may close these issues.

Uh oh!

There was an error while loading. Please reload this page.

6 participants

@illia-v @mdickinson @markshannon @miss-islington @bedevere-bot @gpshead
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
You are visitor 01402503 — GeezerVison does not store the pages you look up.
Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.