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:
		
					parent
					
						
							
								cb7eb6747d
							
						
					
				
			
			
				commit
				
					
						73f43ae46b
					
				
			
		
					 3 changed files with 30 additions and 31 deletions
				
			
		| 
						 | 
					@ -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,47 +12,45 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
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
 | 
					 | 
				
			||||||
      if (c == ':') {
 | 
					 | 
				
			||||||
        // it could also be a Windows filesystem path
 | 
					 | 
				
			||||||
        if (p == arg + 1)
 | 
					 | 
				
			||||||
          break;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        return true;
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      // white-space before a colon means it's not a URL
 | 
					 | 
				
			||||||
      if (std::isspace(c, std::locale::classic()))
 | 
					 | 
				
			||||||
        break;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// we say it's a URL arg if it starts with a URI scheme that:
 | 
				
			||||||
 | 
					// 1. starts with an alpha, and
 | 
				
			||||||
 | 
					// 2. contains no spaces, and
 | 
				
			||||||
 | 
					// 3. is longer than one char (to ensure it's not a Windows drive path)
 | 
				
			||||||
 | 
					bool IsUrlArg(const base::CommandLine::StringPieceType arg) {
 | 
				
			||||||
 | 
					  const auto scheme_end = arg.find(':');
 | 
				
			||||||
 | 
					  if (scheme_end == base::CommandLine::StringPieceType::npos)
 | 
				
			||||||
    return false;
 | 
					    return false;
 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  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);
 | 
				
			||||||
 | 
					  return std::size(scheme) > 1U && std::isalpha(scheme.front(), c_locale) &&
 | 
				
			||||||
 | 
					         std::ranges::none_of(scheme, isspace);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
}  // 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;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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};
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue