summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKlement Sekera <ksekera@cisco.com>2020-06-23 13:12:33 +0000
committerAndrew Yourtchenko <ayourtch@gmail.com>2020-08-18 19:47:21 +0000
commitbef1019aa30a93c4eb4ca7da48651c920609b23c (patch)
treee12c582a216c3298f0252626e6e9195ecef5bc19
parentccaef621a8f11ac84b29d2b86c931facb4aa22b0 (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 (cherry picked from commit f3d7bd9d4d652b1c4b687267acdb9fdb908a74bd)
-rw-r--r--src/plugins/nat/nat44_cli.c9
-rw-r--r--src/plugins/nat/nat_det.c16
2 files changed, 20 insertions, 5 deletions
diff --git a/src/plugins/nat/nat44_cli.c b/src/plugins/nat/nat44_cli.c
index e9d3ff5426f..8910f1c6c0a 100644
--- a/src/plugins/nat/nat44_cli.c
+++ b/src/plugins/nat/nat44_cli.c
@@ -1528,8 +1528,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
{