Skip to content

Fix invalid memory access in TRandom3#14135

Merged
lmoneta merged 2 commits intoroot-project:masterfrom
sawenzel:swenzel/TRandom3
Nov 30, 2023
Merged

Fix invalid memory access in TRandom3#14135
lmoneta merged 2 commits intoroot-project:masterfrom
sawenzel:swenzel/TRandom3

Conversation

@sawenzel
Copy link
Copy Markdown
Contributor

The TRandom3 generator was observed to fail
a very simple test on the SetSeed/GetSeed interface:

gRandom->SetSeed(11);
auto a = gRandom->GetSeed();
gRandom->SetSeed(12);
auto b = gRandom->GetSeed();
assert(a != b);

Indeed a GetSeed() following any SetSeed(seed) call always returns the magic number 624. This is because in the current implementation

GetSeed() { return fMT[fCount624]; }

we access memory location fMT[624] which does not exist in fMT ... and so the value of fCount624 is returned, which happens to be 624.

This commit fixes this bug by imposing an index range between 0 and 623.

The TRandom3 generator was observed to fail
a very simple test on the SetSeed/GetSeed interface:

```
gRandom->SetSeed(11);
auto a = gRandom->GetSeed();
gRandom->SetSeed(12);
auto b = gRandom->GetSeed();
assert(a != b);
```

Indeed a `GetSeed()` following any `SetSeed(seed)` call
always returns the magic number 624. This is because
in the current implementation

`GetSeed() { return fMT[fCount624]; }`

we access memory location `fMT[624]` which does not
exist in fMT ... and so the value of fCount624 is returned,
which happens to be `624`.

This commit fixes this bug by imposing an index range
between 0 and 623.
@sawenzel sawenzel requested a review from lmoneta as a code owner November 28, 2023 14:25
@phsft-bot
Copy link
Copy Markdown

Can one of the admins verify this patch?

Copy link
Copy Markdown
Member

@lmoneta lmoneta left a comment

Choose a reason for hiding this comment

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

Thank you for fixing this memory access problem.
However, for TRandom3, with a state of 624 words, it does not make any sense to return a single seed since there is no guarantee that the other 623 values will be the same.
Maybe is better to return a zero value.

@sawenzel
Copy link
Copy Markdown
Contributor Author

Thank you for fixing this memory access problem. However, for TRandom3, with a state of 624 words, it does not make any sense to return a single seed since there is no guarantee that the other 623 values will be the same. Maybe is better to return a zero value.

Hi Lorenzo. No, I believe we should leave the current contract intact, which I am fixing. I am relying in my code on the fact that GetSeed() returns some representation of the generator state, even though it is not the same number as SetSeed(seed).

@lmoneta
Copy link
Copy Markdown
Member

lmoneta commented Nov 28, 2023

I see, but this can be dangerous if misused. What is the usage you are doing with the return value of GetSeed?

sawenzel added a commit to sawenzel/AliceO2 that referenced this pull request Nov 28, 2023
ROOTs TRandom3::GetSeed() may return non-sensical
values when we call GetSeed() directly after a GetSeed().

An intermediate call to TRandam3::Rndm() avoids this misbehaviour.

See also root-project/root#14135, where
this is fixed directly in ROOT.
@sawenzel
Copy link
Copy Markdown
Contributor Author

I agree that the interface is somewhat dangerous but the docs clearly mention its limitations. However, dangerous or not, this is currently broken and should be fixed.

sawenzel added a commit to sawenzel/AliceO2 that referenced this pull request Nov 28, 2023
ROOTs TRandom3::GetSeed() may return non-sensical
values when we call GetSeed() directly after a GetSeed().

An intermediate call to TRandam3::Rndm() avoids this misbehaviour.

See also root-project/root#14135, where
this is fixed directly in ROOT.
sawenzel added a commit to sawenzel/AliceO2 that referenced this pull request Nov 28, 2023
ROOTs TRandom3::GetSeed() may return non-sensical
values when we call GetSeed() directly after a SetSeed(...).

An intermediate call to TRandam3::Rndm() avoids this misbehaviour.

See also root-project/root#14135, where
this is fixed directly in ROOT.
sawenzel added a commit to sawenzel/AliceO2 that referenced this pull request Nov 28, 2023
ROOTs TRandom3::GetSeed() may return non-sensical
values when we call GetSeed() directly after a SetSeed(...).

An intermediate call to TRandam3::Rndm() avoids this misbehaviour.

See also root-project/root#14135, where
this is fixed directly in ROOT.
@@ -35,7 +35,7 @@ class TRandom3 : public TRandom {
~TRandom3() override;
/// return current element of the state used for generate the random number
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.

I think we should specify clearly here what is return
Maybe something like:

Return one element of the generator state used to generate the random numbers.
Note that it is not the seed of the generator that was used in the SetSeed function and the full state (624 numbers)
is required to define the generator and have a reproducible output.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Yes that's ok with me. You may just modify my PR accordingly.

sawenzel added a commit to AliceO2Group/AliceO2 that referenced this pull request Nov 29, 2023
ROOTs TRandom3::GetSeed() may return non-sensical
values when we call GetSeed() directly after a SetSeed(...).

An intermediate call to TRandam3::Rndm() avoids this misbehaviour.

See also root-project/root#14135, where
this is fixed directly in ROOT.
Document better what GetSeed returns for TRandom3
@lmoneta
Copy link
Copy Markdown
Member

lmoneta commented Nov 30, 2023

The PR looks good now. Thank you @sawenzel for this fix

@lmoneta lmoneta merged commit b68a32f into root-project:master Nov 30, 2023
github-actions bot pushed a commit to AliceO2Group/AliceO2 that referenced this pull request Dec 20, 2023
ROOTs TRandom3::GetSeed() may return non-sensical
values when we call GetSeed() directly after a SetSeed(...).

An intermediate call to TRandam3::Rndm() avoids this misbehaviour.

See also root-project/root#14135, where
this is fixed directly in ROOT.
andreasmolander pushed a commit to andreasmolander/AliceO2 that referenced this pull request Apr 12, 2024
ROOTs TRandom3::GetSeed() may return non-sensical
values when we call GetSeed() directly after a SetSeed(...).

An intermediate call to TRandam3::Rndm() avoids this misbehaviour.

See also root-project/root#14135, where
this is fixed directly in ROOT.
mwinn2 pushed a commit to mwinn2/AliceO2 that referenced this pull request Apr 25, 2024
ROOTs TRandom3::GetSeed() may return non-sensical
values when we call GetSeed() directly after a SetSeed(...).

An intermediate call to TRandam3::Rndm() avoids this misbehaviour.

See also root-project/root#14135, where
this is fixed directly in ROOT.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants