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

fuzz: split FuzzedSock interface and implementation #21630

Merged
merged 5 commits into from
Apr 15, 2021

Conversation

vasild
Copy link
Contributor

@vasild vasild commented Apr 7, 2021

  • split FuzzedSock interface and implementation
  • make FuzzedSock::Wait() sometimes simulate an occurred event
  • set errno from FuzzedSock::Wait() if it simulates a failure

(this is a followup from #21617)

@practicalswift
Copy link
Contributor

practicalswift commented Apr 7, 2021

Concept ACK

Thanks for making src/test/fuzz/ an even better place!

@maflcko
Copy link
Member

maflcko commented Apr 7, 2021

Can the uninitialized read also happen in i2p? (The Wait return code is ignored here):

src/i2p.cpp=bool Session::Accept(Connection& conn)
src/i2p.cpp-{
src/i2p.cpp-    try {
src/i2p.cpp-        while (!*m_interrupt) {
src/i2p.cpp-            Sock::Event occurred;
src/i2p.cpp:            conn.sock->Wait(MAX_WAIT_FOR_IO, Sock::RECV, &occurred);
src/i2p.cpp-
src/i2p.cpp-            if ((occurred & Sock::RECV) == 0) {

@maflcko
Copy link
Member

maflcko commented Apr 7, 2021

review-only ACK d2e8d12 📧

Show signature and timestamp

Signature:

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA512

review-only ACK d2e8d121eff98f9bbc3f15977bfb1dda9a27245a 📧
-----BEGIN PGP SIGNATURE-----

iQGzBAEBCgAdFiEE+rVPoUahrI9sLGYTzit1aX5ppUgFAlwqrYAACgkQzit1aX5p
pUg1aQv/aeRus5hrRnP5M5V3tAv4J17uP4l0h7ApjymlEHRgJvNLlBTDAjOKdji/
u3CYy9mEuxrLn1tv5TGqBMXy1YQLrj2x1R0ExBp96LRalfRPVyTpocx/yOhokfj0
sgy5MyPOpNg4WbcxMU6z0Mli2mg0TBg9pii/b5+KTQg7SdnSsjMXkWYoBYIBvcLk
g/Ra92zzNjYcUGYLM5zDbTu3oU/wbhV7M1H5xapm29heIhtJ3FfSGo5zlA5BynVO
nMNjq9+I04e3qpPopH0wnsSaApnqlFqzRdUNADTMdkyB+tqolDxet3G4GRR0SPGL
8TR7BXBUqAKNfx37x2+4hM5cUnTh+eByyemrRXlyMwAGWzo6QBmINbmD6dbPLT/t
KZUAiKPN7ppA0nsSBdmejAX37ZyVKLFjtC0Nd2XT6XNKXCaYA27lL7VNbQJ2wpOq
fayqkcxeAre8F+5rFq7/oIWSU8ArIXM9ruWhXO6OOFB0MHgcN23CgQ58jfvGLIoM
6nO8IrZq
=aNPu
-----END PGP SIGNATURE-----

Timestamp of file with hash fbf1a942dcb87778554e8487c05545ff298d95af1816d6f90d53986f457f41d2 -

src/test/fuzz/util.cpp Outdated Show resolved Hide resolved
@vasild
Copy link
Contributor Author

vasild commented Apr 7, 2021

Can the uninitialized read also happen in i2p? (The Wait return code is ignored here):

Right! Addressed in #21631.

@practicalswift
Copy link
Contributor

practicalswift commented Apr 7, 2021

Consider adding [[nodiscard]] to Wait: such an annotation would likely have saved us from the uninitialized read reported in #21617.

[[nodiscard]] is great for functions where an ignored return value is likely to be unintentional (like in this case!). I think we underuse [[nodiscard]] :)

@maflcko
Copy link
Member

maflcko commented Apr 8, 2021

review ACK 841905b 🍰

Show signature and timestamp

Signature:

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA512

review ACK 841905bb61e34faa97b34f4f0c97f7581092a988 🍰
-----BEGIN PGP SIGNATURE-----

iQGzBAEBCgAdFiEE+rVPoUahrI9sLGYTzit1aX5ppUgFAlwqrYAACgkQzit1aX5p
pUhL0Av/boScIgVINXDYMJ262ndgfw3HxUyP9JYZLZ/LFDjDhnuLCoBYqfnGvs63
u8DZKbJoFtxjyHkasgOMgWindvj9ae/qzTNkLSBoT8Z6oWoooRhmjawvWXCj2OhO
TxfqVpY9FtcpnXMHZUWN3nx8qbGeAkhdoQ8dB3V0tCa1N+74taaLB1GmgcaJzy/8
Mftf7AymvV/lgWSvZjcIOv1JoXKqw2vEYEkDUoXJuVyiVeqZXzYPeT/ZAgFrlQed
ui3KjNa8RT/VGa4+rQee6rl76oSUcjBBRiAw+nRGpi4J3cxu15yHoD/ETR0OVow3
z0d//mhKHbn6Pyn4tqJ23ple4/JlFRgAuZBEBPYcfxVUYBfPNHgOiomoIKA5fLnK
ByJcIa0hHsPVMy54bzXHMrPyDaFeXw/563/lPsJt9IgJ3o73B3hQ0PGbtvmZe3FH
K4lSSuxOWBNdowECW0qMweSH36kzrB9KQPvF2ov+KGNbd5j8ErB8M5GtpLcMy4mq
RBX26q3v
=eXO6
-----END PGP SIGNATURE-----

Timestamp of file with hash 3f87a5b288e93fbd4eb780ede4aca90eea4b994dd7a1d9c2be7101c3fbf5173f -

@bitcoin bitcoin deleted a comment from xzavjierr Apr 8, 2021
@bitcoin bitcoin deleted a comment from Nadtasticle Apr 8, 2021
@vasild
Copy link
Contributor Author

vasild commented Apr 9, 2021

@practicalswift, I will do [[nodiscard]] in a separate PR, once #21631 is merged.

{
if (!m_fuzzed_data_provider.ConsumeBool()) {
m_socket = fuzzed_data_provider.ConsumeIntegral<SOCKET>();
Copy link
Contributor

Choose a reason for hiding this comment

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

Not changed in this PR, but is there any scenario where we want m_socket != INVALID_SOCKET here?

Otherwise I'd prefer going with INVALID_SOCKET. Perhaps Sock::m_socket could be default initialized to INVALID_SOCKET. That should be a safe default.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Normally we want the fuzzed socket's m_socket to be != INVALID_SOCKET, otherwise a code that does if (sock.Get() == INVALID_SOCKET) will "misbehave" when mocked.

Copy link
Contributor

@practicalswift practicalswift Apr 9, 2021

Choose a reason for hiding this comment

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

@vasild Oh, I didn't think about the possibility to peek at m_socket via Get(). But then I guess we want two cases: 1.) m_socket == INVALID_SOCKET, and 2.) m_socket != INVALID_SOCKET where m_socket is a very high number which is unlikely to coincide with a real opened file descriptor?

The current code allows m_socket to be set to low numbers such as 0, 1, 2, 3, etc which may be problematic :)

Copy link
Contributor

Choose a reason for hiding this comment

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

Perhaps m_socket = fuzzed_data_provider.ConsumeIntegralInRange<SOCKET>(INVALID_SOCKET - 1, INVALID_SOCKET)?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Right! And we can do even better:

  • add a method to check if the Sock object "owns" a socket, similar to std::unique_ptr::operator bool() so that callers don't do Get() == INVALID_SOCKET.
  • Add wrapper methods for getsockname(), setsockopt(), bind() and listen(). That way more code will be mockable, but more importantly - then nobody would need to call Sock::Get() anymore so the value of m_socket will remain "hidden" within the Sock class.

Copy link
Contributor

@practicalswift practicalswift Apr 12, 2021

Choose a reason for hiding this comment

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

@vasild Sounds good! Until we have that in place I think it makes sense to set m_socket to very high numbers here to avoid nasty surprises :) The thought of random reads/writes to existing open file descriptors is a bit scary even if only from fuzzing code.

Copy link
Contributor Author

@vasild vasild Apr 15, 2021

Choose a reason for hiding this comment

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

Low fd values avoided in #21677.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Add wrapper methods for ...

Done in #21700

@vasild
Copy link
Contributor Author

vasild commented Apr 12, 2021

Sock methods flagged with [[nodiscard]] in #21659.

maflcko pushed a commit to bitcoin-core/gui that referenced this pull request Apr 13, 2021
1c1467f i2p: cancel the Accept() method if waiting on the socket errors (Vasil Dimov)

Pull request description:

  If `Sock::Wait()` fails, then cancel the `Accept()` method.

  Not checking the return value may cause an uninitialized read a few lines below when we read the `occurred` variable.

  [Spotted](bitcoin/bitcoin#21630 (comment)) by MarcoFalke, thanks!

ACKs for top commit:
  laanwj:
    Code review ACK 1c1467f
  practicalswift:
    cr ACK 1c1467f: patch looks correct and agree with laanwj that `[[nodiscard]]` can be taken in a follow-up PR :)

Tree-SHA512: 57fa8a03a4e055999e23121cd9ed1566a585ece0cf68b74223d8c902804cb6890218c9356d60e0560ccacc6c8542a526356c226ebd48e7b299b4572be312d49b
sidhujag pushed a commit to syscoin/syscoin that referenced this pull request Apr 13, 2021
1c1467f i2p: cancel the Accept() method if waiting on the socket errors (Vasil Dimov)

Pull request description:

  If `Sock::Wait()` fails, then cancel the `Accept()` method.

  Not checking the return value may cause an uninitialized read a few lines below when we read the `occurred` variable.

  [Spotted](bitcoin#21630 (comment)) by MarcoFalke, thanks!

ACKs for top commit:
  laanwj:
    Code review ACK 1c1467f
  practicalswift:
    cr ACK 1c1467f: patch looks correct and agree with laanwj that `[[nodiscard]]` can be taken in a follow-up PR :)

Tree-SHA512: 57fa8a03a4e055999e23121cd9ed1566a585ece0cf68b74223d8c902804cb6890218c9356d60e0560ccacc6c8542a526356c226ebd48e7b299b4572be312d49b
@DrahtBot
Copy link
Contributor

DrahtBot commented Apr 14, 2021

The following sections might be updated with supplementary metadata relevant to reviewers and maintainers.

Conflicts

No conflicts as of last run.

Move the `FuzzedSock`'s implementation from `src/test/fuzz/util.h` to
`src/test/fuzz/util.cpp`.

A separate interface and implementation make the code more readable for
consumers who don't need to (better not) know the implementation
details.
The former is shorter and ends up with a "random" bool anyway.
@vasild
Copy link
Contributor Author

vasild commented Apr 15, 2021

841905bb6...549c82ad3: rebase due to conflicts

@practicalswift
Copy link
Contributor

cr ACK 549c82a: patch looks correct and touches only src/test/fuzz/

@maflcko
Copy link
Member

maflcko commented Apr 15, 2021

re-ACK 549c82a only change is rebase 🎬

Show signature and timestamp

Signature:

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA512

re-ACK 549c82ad3a34a885ecca37a5f04c36dfbaa95d17 only change is rebase 🎬
-----BEGIN PGP SIGNATURE-----

iQGzBAEBCgAdFiEE+rVPoUahrI9sLGYTzit1aX5ppUgFAlwqrYAACgkQzit1aX5p
pUjNUwv5AZxj+qkRP+IARG87hMf1liImC+MpuCNqfr2qE2faCtn9+lGilUiSYIMo
Tmf4R06QIevh+jlAAbXazLwB7eLrSrFX25dIgQ7f6ijCMXEl8ezcic58WY1K7gF4
OhWm6bjDHYOH6b70fIpAHIXxsZViIJD1N1COqoD999rvFkTkCkREQXIsk1LkHxAJ
Cr45GFJ7zSo55WIxV8NSfvUFDftENjlgu0/YB4n6wraIaQ3sNiRe7n45eqVt5Zc2
Z0lnE3+9JwbCZKpsNcJ9C5G24KcIxyc/hbB5qwP+uF58b2ANGry5KJjMEyGJ5TWp
hWWxcjZQq1ZhaEoCOpapKKyTDPckTLfE4TfpJz5h3YbVzEXezT+nUskZoCHTc9b7
Oldfw9BF7foMyhS83QOfjDd4POw7rtPaWT7PR0lRAKbXGHjy9PYHpocXoLlvXJPz
asKm+tfedIyfIVO24aRPMnrW22KUFX9Hrd56lqeo21SVHXT22zyz+bcDyNSV8541
zTOdMYVQ
=0nmO
-----END PGP SIGNATURE-----

Timestamp of file with hash fefa9f6ff7ab6d5c5d493fb447f3ba78a5d161e01bf1afb703b033184420ad98 -

@maflcko maflcko merged commit c6b30cc into bitcoin:master Apr 15, 2021
@vasild vasild deleted the FuzzedSock_move branch April 15, 2021 08:51
sidhujag pushed a commit to syscoin/syscoin that referenced this pull request Apr 15, 2021
@bitcoin bitcoin locked as resolved and limited conversation to collaborators Aug 16, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants