C ++: safety for beginners

Hello, Khabrovites. For future students of the course “C ++ Developer. Professional” Alexander Kolesnikov prepared an article.

We also invite you to watch an open webinar on the topic “Scopes of Visibility and Invisibility”… In 1.5 hours, the participants, together with an expert, will have time to implement a general-purpose class and run several unit tests using googletest. Join us.


The article will use examples to consider why applications in the C ++ programming language should be developed with special attention.

Today the C ++ programming language exists in several parallel realities: C ++ 98, C ++ 11, C ++ 14, C ++ 17, C ++ 20. There is at least one a sourcewhere you can get a little bit of this whole set of multiverse. However, when it comes to writing code using stackOverflow, the question “is this line exactly written safely” will torment the developer from release to release. By the way, at the time of this writing, a new C ++ standard 23 = is being prepared).

Where are the problems

C ++ is a very powerful programming language that allows you to develop applications for any level of the operating system. It has not existed for a decade and a programmer should understand what he is doing, since any line in the code can carry a fairly large number of pitfalls that in the future may lead to problems with the safety of the code. Each new update increases the likelihood of encountering such things.

The most common problems a beginner may encounter are:

  • incorrect declaration of data types;

  • incorrect use of expressions;

  • incorrect processing of integer data;

  • improper work with containers;

  • incorrect work with strings;

  • incorrect work with memory;

  • invalid exception handling;

  • disregard for OOP restrictions;

  • race conditions when processing resources in a multithreaded application;

  • other problems, about which there is little, where it is said.

It seems that if you read into the list of restrictions, you might think that C ++ is not a solid thing, and seems to go through, will start and run. Of course, you can concentrate on the algorithm and not pay attention to all the problems described above, but, unfortunately, a large number of CVEs, which lead specifically to applications written in C ++, are off the charts.

Let’s look at a few examples.

String Format

void check_password(const char *user) {
  int ret;
  //
  static const char format[] = "%s wrong pass.n";
  size_t messageLength = strlen(user) + sizeof(msg_format);
  char *data = (char *)malloc(messageLength); // <- так же не очень безопасный вариант
  if (data == NULL) {
    //Код для ошибки
  }
  ret = snprintf(data, messageLength, format, user);
  if (ret < 0) { 
    //Код для ошибки
  } else if (ret >= messageLength) { 
    //Последний шанс обработать некорректные данные
  }
  syslog(LOG_INFO, msg);
  free(msg);
}

What is the problem? The data used to create the row is controlled by the user. Passing other special characters (% n,% x) and using large strings can crash the application.

Integer overflow

This problem is a headache for any software that works with accumulated data. What size of variables should you use to optimally store data and at the same time make a reserve for the application if it will be used for months without restarting? In some cases, it is impossible to answer this question unambiguously, therefore the programmer, focusing on his own experience, writes by a strong-willed decision uint16_t… But the data turns out to be more than 65.535 and then a miracle happens – the value of the variable becomes zero and the countdown starts again. Sample code:

...
user->nameLength = getUserNameLength(&user->name) ;
user->newDbCellLen = malloc(user->nameLength * sizeof(uint8_t))
...

One line and one shot … to the head for the entire application. Now the user can safely allocate as much memory as he needs. In this case, the application will continue to work for some time. You can fix it with a simple function:

...
int16_t checkLen(uint16_t firstNumber, uint16_t secondNumber)
{
    uint16_t resultLength;
    if (UINT_MAX - firstNumber < secondNumber) 
    {
        //ошибка
        return -1;
    }
    else
    {
        resultLength = firstNumber + secondNumber;
    }
    return resultLength;
}

Type conversion

If you are not afraid of difficulties and you still want to develop as a C ++ programmer, then most likely you will get your hands on the code that was developed “When dinosaurs walked under the table” and it will contain a lot of code similar to the one below:

...
unsigned int number = (unsigned int)ptr;
number = (number & 0x7fffff) | (flag << 23);
ptr = (char *)number;
...

What’s wrong with this kind of code? It is not clear what the programmer wanted to describe in terms of the algorithm. Yes, it’s using bitmasks, but what exactly are they collecting?
In addition to this problem, the following may arise: the data type that the programmer intended may not coincide with what will be obtained after all the operations have been carried out.

findings

As you can see from the examples in the article, C ++ is a language in which you need to be careful about seeming little things, from data formats to variable types. Where to get examples? What to do with vulnerabilities? Unfortunately, there is no universal answer, but you can constantly work and accumulate knowledge about the language and its features. You can start here or here… You also need to use plugins and applications that allow you to analyze the code at the build stage. In this case, you can focus on products like of this or of this


Learn more about the course “C ++ Developer. Professional”

Watch an open webinar on the topic “Scopes of Visibility and Invisibility”

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *