Skip to content

Conversation

@rniwa
Copy link
Member

@rniwa rniwa commented Dec 16, 2024

0477b9f

Suppress more clang static analyzer warnings in WTF
https://bugs.webkit.org/show_bug.cgi?id=284783

Reviewed by Chris Dumez.

Suppressed more clang static analyzer warnings.

* Source/WTF/SaferCPPExpectations/MemoryUnsafeCastCheckerExpectations:
* Source/WTF/SaferCPPExpectations/UncountedCallArgsCheckerExpectations:
* Source/WTF/SaferCPPExpectations/UncountedLocalVarsCheckerExpectations:
* Source/WTF/wtf/text/AtomString.h:
(WTF::nullAtom):
(WTF::emptyAtom):
* Source/WTF/wtf/text/AtomStringImpl.h:
(WTF::AtomStringImpl::lookUp):
(WTF::AtomStringImpl::add):
(isType):
* Source/WTF/wtf/text/StringImpl.h:
(WTF::StringImpl::empty):
(WTF::StringImpl::createSubstringSharingImpl):
(WTF::StringImpl::tryCreateUninitialized):
(WTF::StringImpl::StaticStringImpl::operator StringImpl&):
* Source/WTF/wtf/text/StringView.h:
(WTF::String::hasInfixStartingAt const):
(WTF::String::hasInfixEndingAt const):
* Source/WTF/wtf/text/WTFString.h:
(WTF::nullString):
(WTF::emptyString):
(WTF::String::defaultWritingDirection const):
(WTF::String::substring const):
(WTF::String::operator NSString * const):
(WTF::String::removeCharacters const):
* Source/WebKit/UIProcess/API/Cocoa/WKWebExtensionCommand.mm:
(-[WKWebExtensionCommand activationKey]):

Canonical link: https://commits.webkit.org/288214@main

ce4ba45

Misc iOS, visionOS, tvOS & watchOS macOS Linux Windows
✅ 🧪 style ✅ 🛠 ios ✅ 🛠 mac ✅ 🛠 wpe ✅ 🛠 win
✅ 🛠 ios-sim ✅ 🛠 mac-AS-debug ✅ 🧪 wpe-wk2 ✅ 🧪 win-tests
✅ 🧪 webkitperl ✅ 🧪 ios-wk2 ✅ 🧪 api-mac ✅ 🧪 api-wpe
✅ 🧪 ios-wk2-wpt ✅ 🧪 mac-wk1 ✅ 🛠 wpe-cairo
❌ 🛠 🧪 jsc 🧪 api-ios ✅ 🧪 mac-wk2 ✅ 🛠 gtk
✅ 🛠 🧪 jsc-arm64 ✅ 🛠 vision ❌ 🧪 mac-AS-debug-wk2 ✅ 🧪 gtk-wk2
❌ 🛠 vision-sim ✅ 🧪 mac-wk2-stress ✅ 🧪 api-gtk
⏳ 🧪 vision-wk2 ✅ 🧪 mac-intel-wk2 🛠 playstation
✅ 🛠 🧪 unsafe-merge ✅ 🛠 tv ✅ 🛠 mac-safer-cpp ✅ 🛠 jsc-armv7
✅ 🛠 tv-sim ✅ 🧪 jsc-armv7-tests
✅ 🛠 watch
✅ 🛠 watch-sim

@rniwa rniwa self-assigned this Dec 16, 2024
@rniwa rniwa added the New Bugs Unclassified bugs are placed in this component until the correct component can be determined. label Dec 16, 2024
@rniwa rniwa force-pushed the fix284783-suppress-wtf-warnings branch from 9aae735 to d2004bc Compare December 17, 2024 00:08
Copy link
Contributor

Choose a reason for hiding this comment

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

Should this if check use a dynamicDowncast? once AtomStringImpl supports it?

Copy link
Member Author

Choose a reason for hiding this comment

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

I don't think there is a much value in using dynamicDowncast here since AtomStringImpl is a phantom type. We never directly create AtomStringImpl. We just cast StringImpl to AtomStringImpl when isAtom().

Copy link
Contributor

Choose a reason for hiding this comment

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

Let me put it some other way: Couldn't we get security bugs if someone did an incorrect cast from StringImpl to AtomStringImpl even though isAtom() returns false? If the answer is yes, I think this is a clear case for using downcast / dynamicDowncast (cc @geoffreygaren)

Copy link
Member Author

Choose a reason for hiding this comment

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

I don't think so. The memory layout of AtomStringImpl and StringImpl are identical. The only difference is whether the string belongs to the atom string table or not. Of course, if you treat a string not in the atom string table as it's in the table or vice versa, it would be problematic but that's independent of whether we cast StringImpl to AtomStringImpl or not.

Copy link
Contributor

Choose a reason for hiding this comment

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

There are already isAtom() checks, which seems to nicely map to the dynamicCast model, I don't understand why we wouldn't want to catch bad casts in release builds and make the code consistent with the rest of the code base. It doesn't seem like a lot of work and I don't see the downside.

Copy link
Member

Choose a reason for hiding this comment

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

I think @rniwa has it mostly right. I agree that this is a downcast situation but not one that involves the classic risks of type confusion. With other such situations the objects have different sizes so type confusion can be exploited to read or write past the end of an object. In this situation the implications are far less dire. Having an AtomStringImpl pointing to something not an atom might be exploitable in some way but it would have to be more of a logic mistake and I can't immediately think of anything.

On the other hand if we can afford it from a performance point of view it seems fine to use downcast and dynamicDowncast anyway. Doesn't seem to be harmful to recheck the isAtom bit except for the performance cost.

Copy link
Contributor

Choose a reason for hiding this comment

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

To be clear, there may be places where downcast<>() has extra cost but for this particular piece of code, using dynamicDowncast<>() would have no extra cost since this original code is already checking isAtom. We'd replace isAtom check + static_cast with dynamicDowncast which is identical perf-wise but is more concise and modern.

Copy link
Contributor

Choose a reason for hiding this comment

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

For analogy, there are plenty of cases where holding a smart pointer on the stack is not strictly needed for security because the developer can reason about the code and claim that it is safe without that smart pointer. Yet, we still expect people to follow the pattern to silence static analysis warnings and guarantee safety, unless there is a very good reason NOT to do so.

Seems similar here, there is no safety issue but the static analysis wants use to use downcast / dynamicDowncast. While there is no safety issue, I think downcast / dynamicDowncast can still help catch logic errors so I believe it does provide some value. It would also make things consistent with the rest of our code base. I personally don't see a downside to using downcast / dynamicDowncast. What is the good reason NOT to use downcast?

Darin mentioned perf. That could be a reason. I don't think it applies to this case here because it was already doing a runtime type check. The check would just move inside the dynamicDowncast. There could be other places where we use static_cast<>() without a type check and downcast would add a cost. In those cases, I still think we should use downcast as long as it doesn't regress perf. If it does regress perf, we can static_cast with a comment explaining why we're not using downcast.

Copy link
Contributor

Choose a reason for hiding this comment

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

I agree with the analysis here that explains why it's not a memory safety error to mis-cast StringImpl to AtomStringImpl.

But our goal with Safer C++ is not to require expert exegesis. We want our code to be self-evidently safe based on idiomatic and automatically verified language. So I favor doing the dynamicDowncast<> here.

Copy link
Member

Choose a reason for hiding this comment

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

My request at this point: Use dynamicDowncast as an elegant way to write exactly the same code in a way that is understood by our safety tools. I don't think we should overstate that benefit — our discussion here is simplifying some things in a possibly misleading way — but it is a real one.

Copy link
Contributor

Choose a reason for hiding this comment

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

ditto

Copy link
Contributor

Choose a reason for hiding this comment

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

ditto.

Copy link
Contributor

Choose a reason for hiding this comment

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

ditto.

@rniwa rniwa force-pushed the fix284783-suppress-wtf-warnings branch from d2004bc to d623d20 Compare December 17, 2024 09:06
@webkit-ews-buildbot
Copy link
Collaborator

Safer C++ Build #14069 (d2004bc)

❌ Found 1 new failure. Please address these issues before landing. See WebKit Guidelines for Safer C++ Programming.
(cc @rniwa)

⚠️ Found 4 fixed files! Please update expectations in Source/[Project]/SaferCPPExpectations by running the following command and update your pull request:

  • Tools/Scripts/update-safer-cpp-expectations -p WTF --MemoryUnsafeCastChecker WebKitBuild/Release/usr/local/include/wtf/text/StringImpl.h WebKitBuild/Release/usr/local/include/wtf/text/AtomStringImpl.h WebKitBuild/Release/usr/local/include/wtf/text/WTFString.h --UncountedCallArgsChecker WebKitBuild/Release/usr/local/include/wtf/text/StringView.h --UncountedLocalVarsChecker WebKitBuild/Release/usr/local/include/wtf/text/StringImpl.h

@webkit-ews-buildbot
Copy link
Collaborator

Safer C++ Build #14142 (d623d20)

❌ Found 1 new failure. Please address these issues before landing. See WebKit Guidelines for Safer C++ Programming.
(cc @rniwa)

⚠️ Found 4 fixed files! Please update expectations in Source/[Project]/SaferCPPExpectations by running the following command and update your pull request:

  • Tools/Scripts/update-safer-cpp-expectations -p WTF --MemoryUnsafeCastChecker WebKitBuild/Release/usr/local/include/wtf/text/AtomStringImpl.h WebKitBuild/Release/usr/local/include/wtf/text/StringImpl.h WebKitBuild/Release/usr/local/include/wtf/text/WTFString.h --UncountedCallArgsChecker WebKitBuild/Release/usr/local/include/wtf/text/StringView.h --UncountedLocalVarsChecker WebKitBuild/Release/usr/local/include/wtf/text/StringImpl.h

@rniwa rniwa force-pushed the fix284783-suppress-wtf-warnings branch from d623d20 to 899ec4c Compare December 20, 2024 20:54
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: star on wrong side.

Copy link
Member Author

Choose a reason for hiding this comment

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

Ugh... I keep mixing up the star position in WebKit & LLVM.

Copy link
Member

Choose a reason for hiding this comment

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

I would have used the name atom without the impl suffix here and elsewhere.

Copy link
Member Author

Choose a reason for hiding this comment

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

ok, changed to atom.

@rniwa rniwa force-pushed the fix284783-suppress-wtf-warnings branch 2 times, most recently from fdc65b5 to ce4ba45 Compare December 20, 2024 21:36
@webkit-ews-buildbot webkit-ews-buildbot added the merging-blocked Applied to prevent a change from being merged label Dec 21, 2024
@rniwa rniwa added unsafe-merge-queue Applied to send a pull request to merge-queue, but skip building and testing and removed merging-blocked Applied to prevent a change from being merged labels Dec 21, 2024
https://bugs.webkit.org/show_bug.cgi?id=284783

Reviewed by Chris Dumez.

Suppressed more clang static analyzer warnings.

* Source/WTF/SaferCPPExpectations/MemoryUnsafeCastCheckerExpectations:
* Source/WTF/SaferCPPExpectations/UncountedCallArgsCheckerExpectations:
* Source/WTF/SaferCPPExpectations/UncountedLocalVarsCheckerExpectations:
* Source/WTF/wtf/text/AtomString.h:
(WTF::nullAtom):
(WTF::emptyAtom):
* Source/WTF/wtf/text/AtomStringImpl.h:
(WTF::AtomStringImpl::lookUp):
(WTF::AtomStringImpl::add):
(isType):
* Source/WTF/wtf/text/StringImpl.h:
(WTF::StringImpl::empty):
(WTF::StringImpl::createSubstringSharingImpl):
(WTF::StringImpl::tryCreateUninitialized):
(WTF::StringImpl::StaticStringImpl::operator StringImpl&):
* Source/WTF/wtf/text/StringView.h:
(WTF::String::hasInfixStartingAt const):
(WTF::String::hasInfixEndingAt const):
* Source/WTF/wtf/text/WTFString.h:
(WTF::nullString):
(WTF::emptyString):
(WTF::String::defaultWritingDirection const):
(WTF::String::substring const):
(WTF::String::operator NSString * const):
(WTF::String::removeCharacters const):
* Source/WebKit/UIProcess/API/Cocoa/WKWebExtensionCommand.mm:
(-[WKWebExtensionCommand activationKey]):

Canonical link: https://commits.webkit.org/288214@main
@webkit-commit-queue webkit-commit-queue force-pushed the fix284783-suppress-wtf-warnings branch from ce4ba45 to 0477b9f Compare December 21, 2024 06:27
@webkit-commit-queue
Copy link
Collaborator

Committed 288214@main (0477b9f): https://commits.webkit.org/288214@main

Reviewed commits have been landed. Closing PR #38038 and removing active labels.

@webkit-commit-queue webkit-commit-queue merged commit 0477b9f into WebKit:main Dec 21, 2024
@webkit-commit-queue webkit-commit-queue removed the unsafe-merge-queue Applied to send a pull request to merge-queue, but skip building and testing label Dec 21, 2024
@rniwa rniwa deleted the fix284783-suppress-wtf-warnings branch December 21, 2024 07:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

New Bugs Unclassified bugs are placed in this component until the correct component can be determined.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants