diff options
Diffstat (limited to 'net/tls/tls_sw.c')
-rw-r--r-- | net/tls/tls_sw.c | 30 |
1 files changed, 22 insertions, 8 deletions
diff --git a/net/tls/tls_sw.c b/net/tls/tls_sw.c index c02293fb10e6..d93f83f77864 100644 --- a/net/tls/tls_sw.c +++ b/net/tls/tls_sw.c | |||
@@ -119,23 +119,25 @@ static int skb_nsg(struct sk_buff *skb, int offset, int len) | |||
119 | } | 119 | } |
120 | 120 | ||
121 | static int padding_length(struct tls_sw_context_rx *ctx, | 121 | static int padding_length(struct tls_sw_context_rx *ctx, |
122 | struct tls_context *tls_ctx, struct sk_buff *skb) | 122 | struct tls_prot_info *prot, struct sk_buff *skb) |
123 | { | 123 | { |
124 | struct strp_msg *rxm = strp_msg(skb); | 124 | struct strp_msg *rxm = strp_msg(skb); |
125 | int sub = 0; | 125 | int sub = 0; |
126 | 126 | ||
127 | /* Determine zero-padding length */ | 127 | /* Determine zero-padding length */ |
128 | if (tls_ctx->prot_info.version == TLS_1_3_VERSION) { | 128 | if (prot->version == TLS_1_3_VERSION) { |
129 | char content_type = 0; | 129 | char content_type = 0; |
130 | int err; | 130 | int err; |
131 | int back = 17; | 131 | int back = 17; |
132 | 132 | ||
133 | while (content_type == 0) { | 133 | while (content_type == 0) { |
134 | if (back > rxm->full_len) | 134 | if (back > rxm->full_len - prot->prepend_size) |
135 | return -EBADMSG; | 135 | return -EBADMSG; |
136 | err = skb_copy_bits(skb, | 136 | err = skb_copy_bits(skb, |
137 | rxm->offset + rxm->full_len - back, | 137 | rxm->offset + rxm->full_len - back, |
138 | &content_type, 1); | 138 | &content_type, 1); |
139 | if (err) | ||
140 | return err; | ||
139 | if (content_type) | 141 | if (content_type) |
140 | break; | 142 | break; |
141 | sub++; | 143 | sub++; |
@@ -170,9 +172,17 @@ static void tls_decrypt_done(struct crypto_async_request *req, int err) | |||
170 | tls_err_abort(skb->sk, err); | 172 | tls_err_abort(skb->sk, err); |
171 | } else { | 173 | } else { |
172 | struct strp_msg *rxm = strp_msg(skb); | 174 | struct strp_msg *rxm = strp_msg(skb); |
173 | rxm->full_len -= padding_length(ctx, tls_ctx, skb); | 175 | int pad; |
174 | rxm->offset += prot->prepend_size; | 176 | |
175 | rxm->full_len -= prot->overhead_size; | 177 | pad = padding_length(ctx, prot, skb); |
178 | if (pad < 0) { | ||
179 | ctx->async_wait.err = pad; | ||
180 | tls_err_abort(skb->sk, pad); | ||
181 | } else { | ||
182 | rxm->full_len -= pad; | ||
183 | rxm->offset += prot->prepend_size; | ||
184 | rxm->full_len -= prot->overhead_size; | ||
185 | } | ||
176 | } | 186 | } |
177 | 187 | ||
178 | /* After using skb->sk to propagate sk through crypto async callback | 188 | /* After using skb->sk to propagate sk through crypto async callback |
@@ -1478,7 +1488,7 @@ static int decrypt_skb_update(struct sock *sk, struct sk_buff *skb, | |||
1478 | struct tls_prot_info *prot = &tls_ctx->prot_info; | 1488 | struct tls_prot_info *prot = &tls_ctx->prot_info; |
1479 | int version = prot->version; | 1489 | int version = prot->version; |
1480 | struct strp_msg *rxm = strp_msg(skb); | 1490 | struct strp_msg *rxm = strp_msg(skb); |
1481 | int err = 0; | 1491 | int pad, err = 0; |
1482 | 1492 | ||
1483 | if (!ctx->decrypted) { | 1493 | if (!ctx->decrypted) { |
1484 | #ifdef CONFIG_TLS_DEVICE | 1494 | #ifdef CONFIG_TLS_DEVICE |
@@ -1501,7 +1511,11 @@ static int decrypt_skb_update(struct sock *sk, struct sk_buff *skb, | |||
1501 | *zc = false; | 1511 | *zc = false; |
1502 | } | 1512 | } |
1503 | 1513 | ||
1504 | rxm->full_len -= padding_length(ctx, tls_ctx, skb); | 1514 | pad = padding_length(ctx, prot, skb); |
1515 | if (pad < 0) | ||
1516 | return pad; | ||
1517 | |||
1518 | rxm->full_len -= pad; | ||
1505 | rxm->offset += prot->prepend_size; | 1519 | rxm->offset += prot->prepend_size; |
1506 | rxm->full_len -= prot->overhead_size; | 1520 | rxm->full_len -= prot->overhead_size; |
1507 | tls_advance_record_sn(sk, &tls_ctx->rx, version); | 1521 | tls_advance_record_sn(sk, &tls_ctx->rx, version); |