summary |
shortlog |
log |
commit | commitdiff |
review |
tree
raw |
patch |
inline | side by side (from parent 1:
595d6f8)
IPsec writes trailing data at the end of the buffer without checking
if there is enough space. If the packet length equals buffer size this
leads to rewiting of the next buffer header in the pool.
Type: fix
Change-Id: Iceb27bb724c7243863a4b532aad0808051b7d74c
Signed-off-by: Filip Tehlar <ftehlar@cisco.com>
/* pad packet in input buffer */
static_always_inline u8 *
/* pad packet in input buffer */
static_always_inline u8 *
-esp_add_footer_and_icv (vlib_buffer_t * b, u8 block_size, u8 icv_sz)
+esp_add_footer_and_icv (vlib_buffer_t * b, u8 block_size, u8 icv_sz,
+ u16 * next, vlib_node_runtime_t * node,
+ u16 buffer_data_size)
{
static const u8 pad_data[ESP_MAX_BLOCK_SIZE] = {
0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
{
static const u8 pad_data[ESP_MAX_BLOCK_SIZE] = {
0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
esp_footer_t *f = (esp_footer_t *) (vlib_buffer_get_current (b) +
new_length - sizeof (esp_footer_t));
esp_footer_t *f = (esp_footer_t *) (vlib_buffer_get_current (b) +
new_length - sizeof (esp_footer_t));
+ if (b->current_data + new_length + icv_sz > buffer_data_size)
+ {
+ b->error = node->errors[ESP_ENCRYPT_ERROR_NO_TRAILER_SPACE];
+ next[0] = ESP_ENCRYPT_NEXT_DROP;
+ return 0;
+ }
+
- clib_memcpy_fast ((u8 *) f - pad_bytes, pad_data, ESP_MAX_BLOCK_SIZE);
+ clib_memcpy_fast ((u8 *) f - pad_bytes, pad_data, pad_bytes);
f->pad_length = pad_bytes;
b->current_length = new_length + icv_sz;
f->pad_length = pad_bytes;
b->current_length = new_length + icv_sz;
-static_always_inline int
-esp_trailer_icv_overflow (vlib_node_runtime_t * node, vlib_buffer_t * b,
- u16 * next, u16 buffer_data_size)
-{
- if (b->current_data + b->current_length <= buffer_data_size)
- return 0;
-
- b->current_length -= buffer_data_size - b->current_data;
- b->error = node->errors[ESP_ENCRYPT_ERROR_NO_TRAILER_SPACE];
- next[0] = ESP_ENCRYPT_NEXT_DROP;
- return 1;
-}
-
static_always_inline void
esp_process_ops (vlib_main_t * vm, vlib_node_runtime_t * node,
vnet_crypto_op_t * ops, vlib_buffer_t * b[], u16 * nexts)
static_always_inline void
esp_process_ops (vlib_main_t * vm, vlib_node_runtime_t * node,
vnet_crypto_op_t * ops, vlib_buffer_t * b[], u16 * nexts)
if (ipsec_sa_is_set_IS_TUNNEL (sa0))
{
payload = vlib_buffer_get_current (b[0]);
if (ipsec_sa_is_set_IS_TUNNEL (sa0))
{
payload = vlib_buffer_get_current (b[0]);
- next_hdr_ptr = esp_add_footer_and_icv (b[0], block_sz, icv_sz);
- payload_len = b[0]->current_length;
-
- if (esp_trailer_icv_overflow (node, b[0], next, buffer_data_size))
+ next_hdr_ptr = esp_add_footer_and_icv (b[0], block_sz, icv_sz,
+ next, node,
+ buffer_data_size);
+ if (!next_hdr_ptr)
+ payload_len = b[0]->current_length;
/* ESP header */
hdr_len += sizeof (*esp);
/* ESP header */
hdr_len += sizeof (*esp);
vlib_buffer_advance (b[0], ip_len);
payload = vlib_buffer_get_current (b[0]);
vlib_buffer_advance (b[0], ip_len);
payload = vlib_buffer_get_current (b[0]);
- next_hdr_ptr = esp_add_footer_and_icv (b[0], block_sz, icv_sz);
- payload_len = b[0]->current_length;
-
- if (esp_trailer_icv_overflow (node, b[0], next, buffer_data_size))
+ next_hdr_ptr = esp_add_footer_and_icv (b[0], block_sz, icv_sz,
+ next, node,
+ buffer_data_size);
+ if (!next_hdr_ptr)
+ payload_len = b[0]->current_length;
/* ESP header */
hdr_len += sizeof (*esp);
/* ESP header */
hdr_len += sizeof (*esp);