diff options
author | Jing Peng <pj.hades@gmail.com> | 2022-05-31 11:20:31 -0400 |
---|---|---|
committer | Matthew Smith <mgsmith@netgate.com> | 2022-08-16 19:32:14 +0000 |
commit | 5c9f9968de63fa627b4a72b344df36cdc686d18a (patch) | |
tree | 3e191980cbe4e3d4f7da3f01709947b81bf5171d /src/plugins/nat/nat44-ed | |
parent | b5339c64d1100463058d1719ea23e0af353ce697 (diff) |
nat: fix potential out-of-bound worker array index
In several NAT submodules, the number of available ports (0xffff - 1024)
may not be divisible by the number of workers, so port_per_thread is
determined by integer division, which is the floor of the quotient.
Later when a worker index is needed, dividing the port with port_per_thread
may yield an out-of-bound array index into the workers array.
As an example, assume 2 workers are configured, then port_per_thread
will be (0xffff - 1024) / 2, which is 32255. When we compute a worker
index with port 0xffff, we get (0xffff - 1024) / 32255, which is 2,
but since we only have 2 workers, only 0 and 1 are valid indices.
This patch fixes the problem by adding a modulo at the end of the division.
Type: fix
Signed-off-by: Jing Peng <pj.hades@gmail.com>
Change-Id: Ieae3d5faf716410422610484a68222f1c957f3f8
Diffstat (limited to 'src/plugins/nat/nat44-ed')
-rw-r--r-- | src/plugins/nat/nat44-ed/nat44_ed.c | 10 |
1 files changed, 4 insertions, 6 deletions
diff --git a/src/plugins/nat/nat44-ed/nat44_ed.c b/src/plugins/nat/nat44-ed/nat44_ed.c index 9c797536fb6..27c1870ccef 100644 --- a/src/plugins/nat/nat44-ed/nat44_ed.c +++ b/src/plugins/nat/nat44-ed/nat44_ed.c @@ -761,9 +761,9 @@ get_thread_idx_by_port (u16 e_port) u32 thread_idx = sm->num_workers; if (sm->num_workers > 1) { - thread_idx = - sm->first_worker_index + - sm->workers[(e_port - 1024) / sm->port_per_thread]; + thread_idx = sm->first_worker_index + + sm->workers[(e_port - 1024) / sm->port_per_thread % + _vec_len (sm->workers)]; } return thread_idx; } @@ -3166,9 +3166,7 @@ nat44_ed_get_out2in_worker_index (vlib_buffer_t *b, ip4_header_t *ip, } /* worker by outside port */ - next_worker_index = sm->first_worker_index; - next_worker_index += - sm->workers[(clib_net_to_host_u16 (port) - 1024) / sm->port_per_thread]; + next_worker_index = get_thread_idx_by_port (clib_net_to_host_u16 (port)); done: nat_elog_debug_handoff (sm, "HANDOFF OUT2IN", next_worker_index, |