fix: -Wunsafe-buffer-usage warnings in IsUrlArg() (#43542)

* fix: -Wunsafe-buffer-usage warnings in IsUrlArg()

Co-authored-by: Charles Kerr <charles@charleskerr.com>

* chore: improve code comments for CheckCommandLineArguments()

Co-authored-by: Charles Kerr <charles@charleskerr.com>

* chore: reduce diffs from main

Co-authored-by: Charles Kerr <charles@charleskerr.com>

* refactor: CheckCommandLineArguments takes a StringVector arg

Fixes another buffer warning!

Co-authored-by: Charles Kerr <charles@charleskerr.com>

* chore: use base::CommandLine::StringPieceType

base:CommandLine::StringViewType has not been invented yet

---------

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Charles Kerr <charles@charleskerr.com>
This commit is contained in:
trop[bot] 2024-09-04 21:27:00 -05:00 committed by GitHub
parent cb7eb6747d
commit 73f43ae46b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 30 additions and 31 deletions

View file

@ -4,6 +4,7 @@
#include "shell/app/command_line_args.h" #include "shell/app/command_line_args.h"
#include <algorithm>
#include <locale> #include <locale>
#include "sandbox/policy/switches.h" #include "sandbox/policy/switches.h"
@ -11,46 +12,44 @@
namespace { namespace {
bool IsUrlArg(const base::CommandLine::CharType* arg) { #if BUILDFLAG(IS_WIN)
// the first character must be a letter for this to be a URL constexpr auto DashDash = base::CommandLine::StringPieceType{L"--"};
auto c = *arg; #else
if (std::isalpha(c, std::locale::classic())) { constexpr auto DashDash = base::CommandLine::StringPieceType{"--"};
for (auto* p = arg + 1; *p; ++p) { #endif
c = *p;
// colon indicates that the argument starts with a URI scheme // we say it's a URL arg if it starts with a URI scheme that:
if (c == ':') { // 1. starts with an alpha, and
// it could also be a Windows filesystem path // 2. contains no spaces, and
if (p == arg + 1) // 3. is longer than one char (to ensure it's not a Windows drive path)
break; bool IsUrlArg(const base::CommandLine::StringPieceType arg) {
const auto scheme_end = arg.find(':');
if (scheme_end == base::CommandLine::StringPieceType::npos)
return false;
return true; const auto& c_locale = std::locale::classic();
} const auto isspace = [&](auto ch) { return std::isspace(ch, c_locale); };
const auto scheme = arg.substr(0U, scheme_end);
// white-space before a colon means it's not a URL return std::size(scheme) > 1U && std::isalpha(scheme.front(), c_locale) &&
if (std::isspace(c, std::locale::classic())) std::ranges::none_of(scheme, isspace);
break;
}
}
return false;
} }
} // namespace } // namespace
namespace electron { namespace electron {
bool CheckCommandLineArguments(int argc, base::CommandLine::CharType** argv) { // Check for CVE-2018-1000006 issues. Return true iff argv looks safe.
const base::CommandLine::StringType dashdash(2, '-'); // Sample exploit: 'exodus://aaaaaaaaa" --gpu-launcher="cmd" --aaaaa='
// Prevent it by returning false if any arg except '--' follows a URL arg.
// More info at https://www.electronjs.org/blog/protocol-handler-fix
bool CheckCommandLineArguments(const base::CommandLine::StringVector& argv) {
bool block_args = false; bool block_args = false;
for (int i = 0; i < argc; ++i) { for (const auto& arg : argv) {
if (argv[i] == dashdash) if (arg == DashDash)
break; break;
if (block_args) { if (block_args)
return false; return false;
} else if (IsUrlArg(argv[i])) { if (IsUrlArg(arg))
block_args = true; block_args = true;
}
} }
return true; return true;
} }

View file

@ -9,7 +9,7 @@
namespace electron { namespace electron {
bool CheckCommandLineArguments(int argc, base::CommandLine::CharType** argv); bool CheckCommandLineArguments(const base::CommandLine::StringVector& argv);
bool IsSandboxEnabled(base::CommandLine* command_line); bool IsSandboxEnabled(base::CommandLine* command_line);
} // namespace electron } // namespace electron

View file

@ -225,7 +225,7 @@ int APIENTRY wWinMain(HINSTANCE instance, HINSTANCE, wchar_t* cmd, int) {
CHECK_EQ(fiber_status, FiberStatus::kSuccess); CHECK_EQ(fiber_status, FiberStatus::kSuccess);
#endif // defined(ARCH_CPU_32_BITS) #endif // defined(ARCH_CPU_32_BITS)
if (!electron::CheckCommandLineArguments(arguments.argc, arguments.argv)) if (!electron::CheckCommandLineArguments(command_line->argv()))
return -1; return -1;
sandbox::SandboxInterfaceInfo sandbox_info = {nullptr}; sandbox::SandboxInterfaceInfo sandbox_info = {nullptr};