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 . , , , , , ++ , ++- "".