Modern C ++ won't save us

I often criticize memory-insecure languages, mainly C and C ++, and how they provoke an extraordinary number of security vulnerabilities. My summary, based on examining evidence from numerous large C and C ++ programming projects, is that we need to migrate our industry to the default memory-safe languages ​​(such as Rust and Swift). One of the answers that I often get is that the problem is not in C and C ++ themselves, the developers simply "prepare" them incorrectly. In particular, I often get an answer in defense of C ++ like: "C ++ is safe if you do not use functionality inherited from C" [1] or similar to it, that if you use the types and idioms of modern C ++, then you will be insured against vulnerabilities such as damage memories that other projects suffer from.





I would like to give credit to C ++ smart pointers because they help a lot. Unfortunately, my experience of working on large C ++ projects using modern idioms is that it is not even close enough to stop the influx of vulnerabilities. My goal for the remainder of this post is to highlight a number of completely modern C ++ idioms that introduce vulnerabilities.






Hidden link and use-after-free

#include <iostream>
#include <string>
#include <string_view>

int main() {
  std::string s = "Hellooooooooooooooo ";
  std::string_view sv = s + "World\n";
  std::cout << sv;
}
      
      



, s + "World\n"



std::string



, std::string_view



. std::string , sv



, . sv



use-after-free . ! ++ , , sv



-, , . std::span



, ++.





++ :





#include <memory>
#include <iostream>
#include <functional>


std::function<int(void)> f(std::shared_ptr<int> x) {
    return [&]() { return *x; };
}

int main() {
    std::function<int(void)> y(nullptr);
    {
        std::shared_ptr<int> x(std::make_shared<int>(4));
        y = f(x);
    }
    std::cout << y() << std::endl;
}
      
      



[&]



f



. main



, x



, . y



. , . , , std::shared_ptr&



, .





std::optional

std::optional



, , , (, -1



nullptr



). , value()



, T



, , , optional



. , operator*



operator->



. T



, , optional



.





, , :





#include <optional>

int f() {
    std::optional<int> x(std::nullopt);
    return *x;
}
      
      



std::optional



nullptr



, ! nullptr



segfault ( , ). , nullopt



, . T*



, , , nullptr



.





, . / :





#include <optional>
#include <memory>

std::unique_ptr<int> f() {
    std::optional<std::unique_ptr<int>> x(std::nullopt);
    return std::move(*x);
}
      
      



std::span

std::span



. , ; std::span



, std::vector, std::array<uint8_t, N>



. - , span



, , .





STL, span::operator[]



. , operator[]



. std::vector



std::array



, , , at()



, ( , , , std::vector::operator[]



). span at()



, , .





, Firefox, Chromium std::span



operator[]



, , , std::span



.





C++ , : , std::span



, , std::variant



union



. C++ :



use-after-free, optional



span



.





++ Rust- ( Rust-, unsafe



) , ++ , , Rust Swift ( Python Javascript, , - Python, C++).





C C++ - . , , , , . ++, , ++.





[1] , , --, malloc/free . , , , , , ++ , ++- "".








All Articles