Skip to content
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

fix uninitialized read in tests #889

Merged
merged 2 commits into from Apr 7, 2021
Merged

fix uninitialized read in tests #889

merged 2 commits into from Apr 7, 2021

Conversation

PiRK
Copy link
Contributor

@PiRK PiRK commented Jan 31, 2021

I tried compiling secp256k1 with clang and -Wconditional-uninitialized and got the following warning:

$ make check
  CC       src/tests-tests.o
src/tests.c:4336:15: warning: variable 'recid' may be uninitialized when used here [-Wconditional-uninitialized]
        CHECK(recid >= 0 && recid < 4);
              ^~~~~
./src/util.h:54:18: note: expanded from macro 'CHECK'
    if (EXPECT(!(cond), 0)) { \
                 ^~~~
./src/util.h:41:39: note: expanded from macro 'EXPECT'
#define EXPECT(x,c) __builtin_expect((x),(c))
                                      ^
src/tests.c:4327:14: note: initialize the variable 'recid' to silence this warning
    int recid;
             ^
              = 0
1 warning generated.
  CCLD     tests
make  check-TESTS

This initializes recid and adds the -Wconditional-uninitialized flag when building with clang.

@elichai
Copy link
Contributor

elichai commented Jan 31, 2021

I think this is a false positive, if getrec is 1 we pass a pointer to recid into random_sign and inside we write into it, and then we only call CHECK if getrec is 1, so it shouldn't call CHECK on an uninitialized recid

Copy link
Contributor

@real-or-random real-or-random left a comment

Choose a reason for hiding this comment

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

So yes, this is a false positive but it's still a good idea to "fix" it. Ideally. the test should also check that recid is indeed written to by secp256k1_ecdsa_sig_sign.

src/tests.c Outdated Show resolved Hide resolved
configure.ac Outdated Show resolved Hide resolved
@PiRK
Copy link
Contributor Author

PiRK commented Feb 1, 2021

Thanks for your reviews. I have updated the commits with your feedback.

@real-or-random
Copy link
Contributor

Thanks for the quick update. This looks good.

ACK 64ebb15 changes looks good but I haven't tested them

@gmaxwell
Copy link
Contributor

gmaxwell commented Feb 2, 2021

It would probably be a good idea to VG_UNDEF() that variable.

Unnecessarily initialization of variables is usually not the best practice. It causes actual harm because it undermines the sensitivity of undefined behaviour checking -- e.g. if there is some change to the code and the dummy initialization which isn't supposed to get used starts to get used, there isn't any way to detect it where otherwise with valgrind/ubsan it would get flagged.

Because this is in a test you have the option of VG_UNDEF(&recid,sizeof()) it to restore the lost sensitivity at least for valgrind builds running in valgrind... and since this seems to allow turning on an additional warning it might be worth it. OTOH, if the warning produces additional false positives in the future it'll probably have to get turned off.

It's probably worth testing this with multiple clang versions-- in the past compilers have sometimes introduced new warnings in forms that spewed false positives and then improved them. If the codebase (with all the modules enabled) gets a lot of falses with an older but popular clang then it'll probably need to get compiler version restricted.

I tested this PR with ARM8 ubuntu clang 10 and all modules enabled and got no warnings.

Copy link
Contributor

@real-or-random real-or-random left a comment

Choose a reason for hiding this comment

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

Fwiw, I had checked that the current PR doesn't give further warnings on

clang version 11.0.1
Target: x86_64-pc-linux-gnu

src/tests.c Outdated Show resolved Hide resolved
@real-or-random
Copy link
Contributor

I wanted to write "let's ask Cirrus" about clang 9 but this PR didn't get a build. I'll try closing and opening this but I don't think it'll help.

@real-or-random
Copy link
Contributor

Oh I see the issue now: This PR is not rebased on the most recent master, so it just not have the new .cirrus.yml.

@PiRK Can you rebase this on the current master? Sorry for all the fuss about this small change, we recently switched our CI from Travis to Cirrus and this hits us here.

@PiRK
Copy link
Contributor Author

PiRK commented Feb 2, 2021

Np, I will rebase it tomorrow. I'm on the road today.

This was detected while running the tests with the `-Wconditional-uninitialized` flag

```
./autogen.sh
CC=clang CFLAGS="-Wconditional-uninitialized" ./configure
make check
```

The resulting warning is a false positive, but setting the value to -1
ensures that the CHECK below will fail if recid is never written to.
This compiler flag is available for clang but not gcc.

Test plan:

```
autogen.sh
./configure
make check
CC=clang ./configure
make check
```

If a variable is used uninitialized, the warning should look something
like:
```
  CC       src/tests-tests.o
src/tests.c:4336:15: warning: variable 'recid' may be uninitialized when used here [-Wconditional-uninitialized]
        CHECK(recid >= 0 && recid < 4);
              ^~~~~
./src/util.h:54:18: note: expanded from macro 'CHECK'
    if (EXPECT(!(cond), 0)) { \
                 ^~~~
./src/util.h:41:39: note: expanded from macro 'EXPECT'
                                      ^
src/tests.c:4327:14: note: initialize the variable 'recid' to silence this warning
    int recid;
             ^
              = 0
1 warning generated.
```
@real-or-random
Copy link
Contributor

real-or-random commented Mar 18, 2021

Closing and reopening to trigger Cirrus CI, which now really uses clang (version 7).

edit: Oh, Cirrus simply looks up the old results in its cache... This shouldn't be the case since we changed some settings in between.

Copy link
Contributor

@real-or-random real-or-random left a comment

Choose a reason for hiding this comment

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

ACK 99a1cfe code inspection

We now know that there are no additional warnings on clang 7 (Cirrus), clang 10 (@gmaxwell) and clang 11 (me). This should be enough.

So even there are two CI hiccups that could be solved by rebasing (the issue here is that .cirrus.yml is wrongly merged), these failures should disappear on master after merging. So I think we shouldn't bother @PiRK with a further rebase and just merge this.

Copy link
Contributor

@jonasnick jonasnick left a comment

Choose a reason for hiding this comment

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

No further warnings with clang version 11.1.1

ACK 99a1cfe

@jonasnick jonasnick merged commit 1e5d50f into bitcoin-core:master Apr 7, 2021
deadalnix pushed a commit to Bitcoin-ABC/bitcoin-abc that referenced this pull request Apr 8, 2021
Summary:
> This was detected while running the tests with the `-Wconditional-uninitialized` flag
>
> ```
> ./autogen.sh
> CC=clang CFLAGS="-Wconditional-uninitialized" ./configure
> make check
> ```
>
> The resulting warning is a false positive, but setting the value to -1
> ensures that the CHECK below will fail if recid is never written to.

This is a backport of [[bitcoin-core/secp256k1#889 | secp256k1#889]]

It should allow us to finally land D9110

Test Plan:
To check that this diff does not break existing tests:
`ninja && ninja check-secp256k1`

To check that this removes the compilation warning: rebased D9110 on top of this

Reviewers: #bitcoin_abc, Fabien

Reviewed By: #bitcoin_abc, Fabien

Differential Revision: https://reviews.bitcoinabc.org/D9372
deadalnix pushed a commit to Bitcoin-ABC/secp256k1 that referenced this pull request Apr 9, 2021
Summary:
> This was detected while running the tests with the `-Wconditional-uninitialized` flag
>
> ```
> ./autogen.sh
> CC=clang CFLAGS="-Wconditional-uninitialized" ./configure
> make check
> ```
>
> The resulting warning is a false positive, but setting the value to -1
> ensures that the CHECK below will fail if recid is never written to.

This is a backport of [[bitcoin-core/secp256k1#889 | secp256k1#889]]

It should allow us to finally land D9110

Test Plan:
To check that this diff does not break existing tests:
`ninja && ninja check-secp256k1`

To check that this removes the compilation warning: rebased D9110 on top of this

Reviewers: #bitcoin_abc, Fabien

Reviewed By: #bitcoin_abc, Fabien

Differential Revision: https://reviews.bitcoinabc.org/D9372
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.

None yet

5 participants