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

Eliminate built-in SNTP support (fixes #4207): #4628

Merged
merged 1 commit into from
Sep 27, 2023
Merged

Eliminate built-in SNTP support (fixes #4207): #4628

merged 1 commit into from
Sep 27, 2023

Conversation

nbougalis
Copy link
Contributor

@nbougalis nbougalis commented Jul 18, 2023

The code contained a simple SNTP client that could be used to synchronize the clock that the code uses even when the system clock was unsynchronized.

Not only was the SNTP code "crufty" but during a recent audit of the codebase by Bishop-Fox, a potential attack vector that could allow an attacker with the ability to shape or redirect traffic to skew the server's clock was discovered.

This commit removes the SNTP client code, removes a mutex and generally simplifies the TimeKeeper.

Note to server operators:
It is highly recommended to use time synchronization software to ensure that system clocks are accurate.

Type of Change

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • Refactor (non-breaking change that only restructures code)
  • Tests (You added tests for code that already exists, or your new feature included in this PR)
  • Documentation Updates
  • Release

@nbougalis nbougalis requested a review from HowardHinnant July 18, 2023 22:13
@intelliot
Copy link
Collaborator

How does this compare with HowardHinnant@6c239bd ?

@nbougalis
Copy link
Contributor Author

How does this compare with HowardHinnant@6c239bd ?

I feel that it is more thorough, restructuring and simplifying the code, instead of simply eliminating the SNTP code.

Copy link
Contributor

@HowardHinnant HowardHinnant left a comment

Choose a reason for hiding this comment

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

Looks good to me.

@intelliot intelliot linked an issue Aug 29, 2023 that may be closed by this pull request
@intelliot intelliot added this to the 1.13 or 2.0 milestone Sep 7, 2023
Copy link
Collaborator

@seelabs seelabs left a comment

Choose a reason for hiding this comment

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

👍 LGTM, but see the comment about the assert.


return (offset * 3) / 4;
}());
assert(success);
Copy link
Collaborator

Choose a reason for hiding this comment

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

I don't really object, but doesn't asserting here mean you can unconditionally assign? If the assert fails, that means another thread changed the value between the time we read it and changed it. If we're asserting that never fails do we need the compare and exchange strong? Do we need the atomic?

Honestly, I think I'd keep the atomics - it makes the code thread safe, but I might remove the assert. What breaks if that assert fires?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

You're right; we could just unconditionally assign and nothing really goes wrong. My intention here was to implement a "weak" form of the precondition that calling this function is supposed to be externally serialized, but it's extremely weak and subject to timing, instead of being a robust check.

I can just change this to be:

        closeOffset_ = [by, offset]() {
                // Ignore small offsets and push the close time
                // towards our wall time.
                if (by > 1s)
                    return offset + ((by + 3s) / 4);

                if (by < -1s)
                    return offset + ((by - 3s) / 4);

                return (offset * 3) / 4;
            }();

@nbougalis
Copy link
Contributor Author

@intelliot, I've addressed @seelabs's comment and rebased the code against the latest develop branch. I will let Scott do a final pass and give a thumbs up, but I think this is ready to go.

@intelliot
Copy link
Collaborator

I will let Scott do a final pass and give a thumbs up

Awaiting final pass by @seelabs . Also, there are (new) conflicts that must be resolved.

@intelliot intelliot added Bug Tech Debt Non-urgent improvements labels Sep 19, 2023
@intelliot intelliot requested a review from seelabs September 22, 2023 23:13
Copy link
Collaborator

@seelabs seelabs left a comment

Choose a reason for hiding this comment

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

👍 Looks good. Thanks Nik!

adjust(std::chrono::system_clock::time_point when)
{
return time_point(std::chrono::duration_cast<duration>(
when.time_since_epoch() - days(10957)));
Copy link
Collaborator

Choose a reason for hiding this comment

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

Just a nit: we usually like to separate the implementation from the interface so it's easier to see interfaces. I'm OK merging this as-is though. It's only a nit and we can clean it up latter (although I did want to flag it; for future changes we should try to stick with separate interfaces/implementations).

@nbougalis
Copy link
Contributor Author

nbougalis commented Sep 26, 2023

Rebased to address merge conflicts. No changes to the code after @seelabs' last review. The conflict was caused by ce570c1, which was modifying a #include in a file deleted in this patch, so the resolution was trivial: keep the deleted file.

@nbougalis nbougalis added the Passed Passed code review & PR owner thinks it's ready to merge. Perf sign-off may still be required. label Sep 26, 2023
The codebase includes a simple SNTP client that is enabled by
default and used to adjust an application-level clock in case
the operating system's clock is not already synchronized.

A recent audit of the code conducted by Bishop-Fox identified
a potential attack vector, which could allow an attacker with
the capability to manipulate the UDP traffic flow of a server
by redirecting queries or by injecting crafted SNTP responses
to manipulate the correction factor, skewing the clock.

Although the impact of such an attack, if mounted, is minimal
and can be completely eliminated by editing the configuration
file to disable the built-in SNTP client, this commit instead
entirely eliminates the "crufty" 10+ year-old code, removes a
mutex and greatly simplifies the `TimeKeeper`.

**Note to server operators:**

It is highly recommended to use time synchronization software
to ensure that the system clock is accurate. For more details
see https://en.wikipedia.org/wiki/Ntpd#Implementations.
@intelliot intelliot merged commit 548c91e into XRPLF:develop Sep 27, 2023
15 checks passed
@intelliot
Copy link
Collaborator

Eliminate the built-in SNTP support (fixes #4207):
The codebase includes a simple SNTP client that is enabled by
default and used to adjust an application-level clock in case
the operating system's clock is not already synchronized.

A recent audit of the code conducted by Bishop-Fox identified
a potential attack vector, which could allow an attacker with
the capability to manipulate the UDP traffic flow of a server
by redirecting queries or by injecting crafted SNTP responses
to manipulate the correction factor, skewing the clock.

Although the impact of such an attack, if mounted, is minimal
and can be completely eliminated by editing the configuration
file to disable the built-in SNTP client, this commit instead
entirely eliminates the "crufty" 10+ year-old code, removes a
mutex and greatly simplifies the `TimeKeeper`.

**Note to server operators:**

It is highly recommended to use time synchronization software
to ensure that the system clock is accurate. For more details
see https://en.wikipedia.org/wiki/Ntpd#Implementations.

@nbougalis nbougalis deleted the sntp branch October 16, 2023 05:59
@intelliot intelliot mentioned this pull request Oct 17, 2023
1 task
sophiax851 pushed a commit to sophiax851/rippled that referenced this pull request Jun 12, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug Passed Passed code review & PR owner thinks it's ready to merge. Perf sign-off may still be required. Tech Debt Non-urgent improvements
Projects
Archived in project
Development

Successfully merging this pull request may close these issues.

SNTP Clock issues
4 participants