1010
1111#include " boost/endian/conversion.hpp"
1212
13- #include " crab/array_domain.hpp"
14- #include " crab/ebpf_domain.hpp"
15-
1613#include " asm_ostream.hpp"
1714#include " asm_unmarshal.hpp"
1815#include " config.hpp"
16+ #include " crab/array_domain.hpp"
17+ #include " crab/ebpf_domain.hpp"
18+ #include " crab_utils/num_safety.hpp"
1919#include " dsl_syntax.hpp"
2020#include " platform.hpp"
2121#include " string_constraints.hpp"
2222
2323using crab::domains::NumAbsDomain;
2424namespace crab {
2525
26- static auto to_signed (std::unsigned_integral auto x) -> std::make_signed_t<decltype(x)> {
27- return static_cast <std::make_signed_t <decltype (x)>>(x);
28- }
29-
30- static auto to_unsigned (std::signed_integral auto x) -> std::make_unsigned_t<decltype(x)> {
31- return static_cast <std::make_unsigned_t <decltype (x)>>(x);
32- }
33-
3426constexpr int MAX_PACKET_SIZE = 0xffff ;
3527
3628// Pointers in the BPF VM are defined to be 64 bits. Some contexts, like
@@ -80,7 +72,7 @@ static std::vector<linear_constraint_t> assume_bit_cst_interval(const NumAbsDoma
8072 }
8173 uint64_t src_int_value = src_n.value ().cast_to <uint64_t >();
8274 if (!is64) {
83- src_int_value = static_cast <uint32_t >(src_int_value);
75+ src_int_value = gsl::narrow_cast <uint32_t >(src_int_value);
8476 }
8577
8678 bool result;
@@ -1655,7 +1647,7 @@ static std::tuple<linear_expression_t, linear_expression_t> lb_ub_access_pair(co
16551647void ebpf_domain_t::operator ()(const ValidAccess& s) {
16561648 using namespace crab ::dsl_syntax;
16571649
1658- const bool is_comparison_check = s.width == static_cast < Value>( Imm{0 }) ;
1650+ const bool is_comparison_check = s.width == Value{ Imm{0 }} ;
16591651
16601652 const auto reg = reg_pack (s.reg );
16611653 // join_over_types instead of simple iteration is only needed for assume-assert
@@ -1679,7 +1671,7 @@ void ebpf_domain_t::operator()(const ValidAccess& s) {
16791671 if (s.offset < 0 ) {
16801672 require (inv, linear_constraint_t::false_const (), " Stack content is not numeric" );
16811673 } else if (const auto pimm = std::get_if<Imm>(&s.width )) {
1682- if (!inv.entail (static_cast <int >(pimm->v ) <= reg.stack_numeric_size - s.offset )) {
1674+ if (!inv.entail (gsl::narrow <int >(pimm->v ) <= reg.stack_numeric_size - s.offset )) {
16831675 require (inv, linear_constraint_t::false_const (), " Stack content is not numeric" );
16841676 }
16851677 } else {
@@ -2023,8 +2015,8 @@ void ebpf_domain_t::operator()(const Mem& b) {
20232015 do_mem_store (b, *preg, data_reg.svalue , data_reg.uvalue , data_reg);
20242016 }
20252017 } else {
2026- do_mem_store (b, number_t { T_NUM }, number_t { static_cast < int64_t >( std::get<Imm>(b.value ).v )},
2027- number_t {static_cast < uint64_t >(std::get<Imm>(b. value ). v ) }, {});
2018+ const uint64_t imm = std::get<Imm>(b.value ).v ;
2019+ do_mem_store (b, number_t { T_NUM }, number_t {to_signed (imm)}, number_t {imm }, {});
20282020 }
20292021}
20302022
@@ -2187,7 +2179,7 @@ void ebpf_domain_t::operator()(const Call& call) {
21872179 if (const auto map_type = get_map_type (*maybe_fd_reg)) {
21882180 if (global_program_info->platform ->get_map_type (*map_type).value_type == EbpfMapValueType::MAP ) {
21892181 if (const auto inner_map_fd = get_map_inner_map_fd (*maybe_fd_reg)) {
2190- do_load_mapfd (r0_reg, static_cast < int > (*inner_map_fd), true );
2182+ do_load_mapfd (r0_reg, to_signed (*inner_map_fd), true );
21912183 goto out;
21922184 }
21932185 } else {
@@ -2327,8 +2319,8 @@ void ebpf_domain_t::shl(const Reg& dst_reg, int imm, const int finite_width) {
23272319 const number_t ub = interval.ub ().number ().value ();
23282320 uint64_t lb_n = lb.cast_to <uint64_t >();
23292321 uint64_t ub_n = ub.cast_to <uint64_t >();
2330- const uint64_t uint_max = finite_width == 64 ? std::numeric_limits<uint64_t >::max ()
2331- : static_cast < uint64_t >( std::numeric_limits<uint32_t >::max ()) ;
2322+ const uint64_t uint_max = finite_width == 64 ? uint64_t { std::numeric_limits<uint64_t >::max ()}
2323+ : uint64_t { std::numeric_limits<uint32_t >::max ()} ;
23322324 if (lb_n >> (finite_width - imm) != ub_n >> (finite_width - imm)) {
23332325 // The bits that will be shifted out to the left are different,
23342326 // which means all combinations of remaining bits are possible.
@@ -2342,7 +2334,7 @@ void ebpf_domain_t::shl(const Reg& dst_reg, int imm, const int finite_width) {
23422334 ub_n = ub_n << imm & uint_max;
23432335 }
23442336 m_inv.set (dst.uvalue , interval_t {lb_n, ub_n});
2345- if (static_cast < int64_t > (ub_n) >= static_cast < int64_t > (lb_n)) {
2337+ if (to_signed (ub_n) >= to_signed (lb_n)) {
23462338 m_inv.assign (dst.svalue , dst.uvalue );
23472339 } else {
23482340 havoc (dst.svalue );
@@ -2472,7 +2464,7 @@ void ebpf_domain_t::ashr(const Reg& dst_reg, const linear_expression_t& right_sv
24722464 }
24732465 }
24742466 m_inv.set (dst.svalue , interval_t {lb_n, ub_n});
2475- if (static_cast < uint64_t > (ub_n) >= static_cast < uint64_t > (lb_n)) {
2467+ if (to_unsigned (ub_n) >= to_unsigned (lb_n)) {
24762468 m_inv.assign (dst.uvalue , dst.svalue );
24772469 } else {
24782470 havoc (dst.uvalue );
@@ -2500,10 +2492,10 @@ void ebpf_domain_t::operator()(const Bin& bin) {
25002492 int64_t imm;
25012493 if (bin.is64 ) {
25022494 // Use the full signed value.
2503- imm = static_cast < int64_t > (pimm->v );
2495+ imm = to_signed (pimm->v );
25042496 } else {
25052497 // Use only the low 32 bits of the value.
2506- imm = static_cast <int32_t >(pimm->v );
2498+ imm = gsl::narrow_cast <int32_t >(pimm->v );
25072499 bitwise_and (dst.svalue , dst.uvalue , std::numeric_limits<uint32_t >::max ());
25082500 }
25092501 switch (bin.op ) {
@@ -2521,13 +2513,13 @@ void ebpf_domain_t::operator()(const Bin& bin) {
25212513 if (imm == 0 ) {
25222514 return ;
25232515 }
2524- add (bin.dst , static_cast <int >(imm), finite_width);
2516+ add (bin.dst , gsl::narrow <int >(imm), finite_width);
25252517 break ;
25262518 case Bin::Op::SUB :
25272519 if (imm == 0 ) {
25282520 return ;
25292521 }
2530- add (bin.dst , static_cast <int >(-imm), finite_width);
2522+ add (bin.dst , gsl::narrow <int >(-imm), finite_width);
25312523 break ;
25322524 case Bin::Op::MUL :
25332525 mul (dst.svalue , dst.uvalue , imm, finite_width);
@@ -2556,7 +2548,7 @@ void ebpf_domain_t::operator()(const Bin& bin) {
25562548 case Bin::Op::AND :
25572549 // FIX: what to do with ptr&-8 as in counter/simple_loop_unrolled?
25582550 bitwise_and (dst.svalue , dst.uvalue , imm);
2559- if (static_cast <int32_t >(imm) > 0 ) {
2551+ if (gsl::narrow <int32_t >(imm) > 0 ) {
25602552 // AND with immediate is only a 32-bit operation so svalue and uvalue are the same.
25612553 assume (dst.svalue <= imm);
25622554 assume (dst.uvalue <= imm);
@@ -2565,9 +2557,9 @@ void ebpf_domain_t::operator()(const Bin& bin) {
25652557 }
25662558 havoc_offsets (bin.dst );
25672559 break ;
2568- case Bin::Op::LSH : shl (bin.dst , static_cast <int32_t >(imm), finite_width); break ;
2569- case Bin::Op::RSH : lshr (bin.dst , static_cast <int32_t >(imm), finite_width); break ;
2570- case Bin::Op::ARSH : ashr (bin.dst , static_cast <int32_t >(imm), finite_width); break ;
2560+ case Bin::Op::LSH : shl (bin.dst , gsl::narrow <int32_t >(imm), finite_width); break ;
2561+ case Bin::Op::RSH : lshr (bin.dst , gsl::narrow <int32_t >(imm), finite_width); break ;
2562+ case Bin::Op::ARSH : ashr (bin.dst , gsl::narrow <int32_t >(imm), finite_width); break ;
25712563 case Bin::Op::XOR :
25722564 bitwise_xor (dst.svalue , dst.uvalue , imm);
25732565 havoc_offsets (bin.dst );
@@ -2728,7 +2720,7 @@ void ebpf_domain_t::operator()(const Bin& bin) {
27282720 // Use only the low 32 bits of the value.
27292721 bitwise_and (dst.svalue , dst.uvalue , std::numeric_limits<uint32_t >::max ());
27302722 }
2731- shl (bin.dst , static_cast <int32_t >(imm), finite_width);
2723+ shl (bin.dst , gsl::narrow_cast <int32_t >(imm), finite_width);
27322724 break ;
27332725 }
27342726 }
@@ -2746,7 +2738,7 @@ void ebpf_domain_t::operator()(const Bin& bin) {
27462738 // Use only the low 32 bits of the value.
27472739 bitwise_and (dst.svalue , dst.uvalue , std::numeric_limits<uint32_t >::max ());
27482740 }
2749- lshr (bin.dst , static_cast <int32_t >(imm), finite_width);
2741+ lshr (bin.dst , gsl::narrow_cast <int32_t >(imm), finite_width);
27502742 break ;
27512743 }
27522744 }
0 commit comments