VOLTUR // ONE

Broadcasts | Bedtime Stories from NCB | Mastodon
Hacker and storyteller from somewhere in the Virgo Supercluster.

C++: argv[0] isn't guaranteed to exist

Voltur | 2022-01-11

Basically from the very beginning, C/C++ is an oddity of insecure things held together by the duct tape of developer intention and knowledge. And by beginning, I mean literally. The C++ main function signature.

Take for example this common code snippet:

program.cpp

#include <iostream>

int main(int argc, char** argv) {
  if (argc == 0) {
    std::cout << "Usage: " << argv[0] << std::endl;
    exit(EXIT_FAILURE);
  }
  else {
    std::cout << argv[1];
  }
  exit(EXIT_SUCCESS);
}

This is a null pointer issue. We almost never see it, but argv[0] isn't guaranteed to exist. In fact, argv[0] is basically just a courtesy of your shell as it passes the exec request to the kernel. The kernel calls an internal execve function that loads argument information for the new process. That service can be used without passing argv data, though.

Example code:

do_exec.cpp

#include <iostream>

int main( int argc, char** argv) {
  if (argc >= 1) {
    execve(argv[1], NULL, NULL);
  }
  exit(EXIT_FAILURE);
}

This code will exec another program without passing any argument information, and instead will pass it null. The previous program, for example, won't check argv[0] and it will segfault. Depending on the type of system and design you're working with, this can be a vector for some form of abuse.

Update:

This was fixed on March 1st of 2022. A friend pointed out that this wasn't working as intended, and sure enough, someone else fixed it! Yay!

The kernel patch is here in response to CVE-2021-4034



Mirror-Wave Shift Technology