C ++ moderno não vai nos salvar

Eu muitas vezes criticam memória com insegurança idiomas, principalmente C e C ++, e como eles provocam um número extraordinário de vulnerabilidades de segurança. Meu resumo, com base no exame de evidências de vários grandes projetos de programação C e C ++, é que precisamos migrar nosso setor para as linguagens padrão de memória segura (como Rust e Swift). Uma das respostas que frequentemente recebo é que o problema não está em C e C ++, os desenvolvedores simplesmente os "preparam" incorretamente. Em particular, muitas vezes recebo uma resposta em defesa do C ++ como: "C ++ é seguro se você não usar a funcionalidade herdada de C" [1] ou semelhante a ela, que se você usar os tipos e expressões do moderno C ++, então você terá seguro contra vulnerabilidades, como memórias danificadas que outros projetos sofrem.





Eu gostaria de dar crédito aos ponteiros inteligentes C ++, porque eles ajudam muito. Infelizmente, minha experiência de trabalho em grandes projetos C ++ usando expressões modernas é que não chega nem perto de impedir o influxo de vulnerabilidades. Meu objetivo no restante deste post é destacar uma série de expressões idiomáticas C ++ completamente modernas que apresentam vulnerabilidades.






Link oculto e uso após livre

#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