diff options
author | Klement Sekera <ksekera@cisco.com> | 2020-06-23 13:12:33 +0000 |
---|---|---|
committer | Ole Trøan <otroan@employees.org> | 2020-06-24 07:20:50 +0000 |
commit | f3d7bd9d4d652b1c4b687267acdb9fdb908a74bd (patch) | |
tree | 3063cd4589b6671499840d3d1f1b6c4ad7adfd43 /src | |
parent | 9c8142a43c503276f97666cb8d34b39e382f82d6 (diff) |
nat: deterministic: disallow invalid config
Prevent overflow if input network prefix is too small and crash on
packet #1 due to vector not being allocated/initialized.
Type: fix
Signed-off-by: Klement Sekera <ksekera@cisco.com>
Change-Id: I3494cc62ce889df48cc59cc9340b5dd70338c3a8
Diffstat (limited to 'src')
-rw-r--r-- | src/plugins/nat/nat44_cli.c | 9 | ||||
-rw-r--r-- | src/plugins/nat/nat_det.c | 16 |
2 files changed, 20 insertions, 5 deletions
diff --git a/src/plugins/nat/nat44_cli.c b/src/plugins/nat/nat44_cli.c index c73cffa85b2..7d74f36c754 100644 --- a/src/plugins/nat/nat44_cli.c +++ b/src/plugins/nat/nat44_cli.c @@ -1858,8 +1858,13 @@ snat_det_map_command_fn (vlib_main_t * vm, } } - rv = snat_det_add_map (sm, &in_addr, (u8) in_plen, &out_addr, (u8) out_plen, - is_add); + if (in_plen > 32 || out_plen > 32) + { + error = clib_error_return (0, "network prefix length must be <= 32"); + goto done; + } + + rv = snat_det_add_map (sm, &in_addr, in_plen, &out_addr, out_plen, is_add); if (rv) { diff --git a/src/plugins/nat/nat_det.c b/src/plugins/nat/nat_det.c index 0ab96dc1026..cad0d2ae5af 100644 --- a/src/plugins/nat/nat_det.c +++ b/src/plugins/nat/nat_det.c @@ -71,6 +71,17 @@ snat_det_add_map (snat_main_t * sm, ip4_address_t * in_addr, u8 in_plen, if (is_add) { + u32 num_sessions = (1 << (32 - in_plen)); + if (num_sessions > UINT32_MAX / 1000) + { + // don't let it overflow + return VNET_API_ERROR_INVALID_VALUE; + } + else + { + num_sessions = num_sessions * 1000 - 1; + } + pool_get (sm->det_maps, det_map); clib_memset (det_map, 0, sizeof (*det_map)); det_map->in_addr.as_u32 = in_cmp.as_u32; @@ -80,9 +91,8 @@ snat_det_add_map (snat_main_t * sm, ip4_address_t * in_addr, u8 in_plen, det_map->sharing_ratio = (1 << (32 - in_plen)) / (1 << (32 - out_plen)); det_map->ports_per_host = (65535 - 1023) / det_map->sharing_ratio; - vec_validate_init_empty (det_map->sessions, - SNAT_DET_SES_PER_USER * (1 << (32 - in_plen)) - - 1, empty_snat_det_session); + vec_validate_init_empty (det_map->sessions, num_sessions, + empty_snat_det_session); } else { |