diff options
author | Marco Varlese <marco.varlese@suse.com> | 2018-02-23 17:43:06 +0100 |
---|---|---|
committer | Florin Coras <florin.coras@gmail.com> | 2018-02-25 19:33:48 +0000 |
commit | 04e5d64c454ec53103fa1f4b7f3634bb61a65d0f (patch) | |
tree | eb934071bb2254bea39bca2a9804caa07393b4d9 /src/vnet/sctp/sctp.h | |
parent | 3473e4938718a820b63edaeab5ae7738c31379d5 (diff) |
SCTP: fix connection memory corruption
A bug was found when multiple SCTP connections were being opened to the
same SCTP server. This patch addresses that problem, removing the use of
the 'parent' pointer approach for sub-connection and saving instead
within the sub-connection itself the ID representing its position. That
facilitates pointer-arithmetic to be computed in the
get_connection_from_transport().
Change-Id: Iaa1f4efc501590be1c93e42fd6fe3d6e02f635eb
Signed-off-by: Marco Varlese <marco.varlese@suse.com>
Diffstat (limited to 'src/vnet/sctp/sctp.h')
-rw-r--r-- | src/vnet/sctp/sctp.h | 10 |
1 files changed, 7 insertions, 3 deletions
diff --git a/src/vnet/sctp/sctp.h b/src/vnet/sctp/sctp.h index fd9d8da5741..048d153ac55 100644 --- a/src/vnet/sctp/sctp.h +++ b/src/vnet/sctp/sctp.h @@ -100,8 +100,8 @@ enum _sctp_subconn_state typedef struct _sctp_sub_connection { transport_connection_t connection; /**< Common transport data. First! */ - void *parent; /**< Link to the parent-super connection */ + u8 subconn_idx; /**< This indicates the position of this sub-connection in the super-set container of connections pool */ u32 error_count; /**< The current error count for this destination. */ u32 error_threshold; /**< Current error threshold for this destination, i.e. what value marks the destination down if error count reaches this value. */ @@ -512,7 +512,7 @@ sctp_half_open_connection_get (u32 conn_index) clib_spinlock_lock_if_init (&sctp_main.half_open_lock); if (!pool_is_free_index (sctp_main.half_open_connections, conn_index)) tc = pool_elt_at_index (sctp_main.half_open_connections, conn_index); - tc->sub_conn[MAIN_SCTP_SUB_CONN_IDX].parent = tc; + tc->sub_conn[MAIN_SCTP_SUB_CONN_IDX].subconn_idx = MAIN_SCTP_SUB_CONN_IDX; clib_spinlock_unlock_if_init (&sctp_main.half_open_lock); return tc; } @@ -609,7 +609,11 @@ sctp_get_connection_from_transport (transport_connection_t * tconn) if (sub->parent == NULL) SCTP_ADV_DBG ("sub->parent == NULL"); #endif - return (sctp_connection_t *) sub->parent; + if (sub->subconn_idx > 0) + return (sctp_connection_t *) sub - + (sizeof (sctp_sub_connection_t) * (sub->subconn_idx - 1)); + + return (sctp_connection_t *) sub; } always_inline u32 |