Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge branch 'linus' of git://git.kernel.org/pub/scm/linux/kernel/git/herbert/crypto-2.6

Pull crypto fixes from Herbert Xu:

- avoid potential bogus alignment for some AEAD operations

- fix crash in algif_aead

- avoid sleeping in softirq context with async af_alg

* 'linus' of git://git.kernel.org/pub/scm/linux/kernel/git/herbert/crypto-2.6:
crypto: skcipher - Fix skcipher_walk_aead_common
crypto: af_alg - remove locking in async callback
crypto: algif_aead - skip SGL entries with NULL page

+66 -38
+14 -7
crypto/af_alg.c
··· 1021 1021 EXPORT_SYMBOL_GPL(af_alg_sendpage); 1022 1022 1023 1023 /** 1024 + * af_alg_free_resources - release resources required for crypto request 1025 + */ 1026 + void af_alg_free_resources(struct af_alg_async_req *areq) 1027 + { 1028 + struct sock *sk = areq->sk; 1029 + 1030 + af_alg_free_areq_sgls(areq); 1031 + sock_kfree_s(sk, areq, areq->areqlen); 1032 + } 1033 + EXPORT_SYMBOL_GPL(af_alg_free_resources); 1034 + 1035 + /** 1024 1036 * af_alg_async_cb - AIO callback handler 1025 1037 * 1026 1038 * This handler cleans up the struct af_alg_async_req upon completion of the ··· 1048 1036 struct kiocb *iocb = areq->iocb; 1049 1037 unsigned int resultlen; 1050 1038 1051 - lock_sock(sk); 1052 - 1053 1039 /* Buffer size written by crypto operation. */ 1054 1040 resultlen = areq->outlen; 1055 1041 1056 - af_alg_free_areq_sgls(areq); 1057 - sock_kfree_s(sk, areq, areq->areqlen); 1058 - __sock_put(sk); 1042 + af_alg_free_resources(areq); 1043 + sock_put(sk); 1059 1044 1060 1045 iocb->ki_complete(iocb, err ? err : resultlen, 0); 1061 - 1062 - release_sock(sk); 1063 1046 } 1064 1047 EXPORT_SYMBOL_GPL(af_alg_async_cb); 1065 1048
+36 -20
crypto/algif_aead.c
··· 101 101 struct aead_tfm *aeadc = pask->private; 102 102 struct crypto_aead *tfm = aeadc->aead; 103 103 struct crypto_skcipher *null_tfm = aeadc->null_tfm; 104 - unsigned int as = crypto_aead_authsize(tfm); 104 + unsigned int i, as = crypto_aead_authsize(tfm); 105 105 struct af_alg_async_req *areq; 106 - struct af_alg_tsgl *tsgl; 107 - struct scatterlist *src; 106 + struct af_alg_tsgl *tsgl, *tmp; 107 + struct scatterlist *rsgl_src, *tsgl_src = NULL; 108 108 int err = 0; 109 109 size_t used = 0; /* [in] TX bufs to be en/decrypted */ 110 110 size_t outlen = 0; /* [out] RX bufs produced by kernel */ ··· 178 178 } 179 179 180 180 processed = used + ctx->aead_assoclen; 181 - tsgl = list_first_entry(&ctx->tsgl_list, struct af_alg_tsgl, list); 181 + list_for_each_entry_safe(tsgl, tmp, &ctx->tsgl_list, list) { 182 + for (i = 0; i < tsgl->cur; i++) { 183 + struct scatterlist *process_sg = tsgl->sg + i; 184 + 185 + if (!(process_sg->length) || !sg_page(process_sg)) 186 + continue; 187 + tsgl_src = process_sg; 188 + break; 189 + } 190 + if (tsgl_src) 191 + break; 192 + } 193 + if (processed && !tsgl_src) { 194 + err = -EFAULT; 195 + goto free; 196 + } 182 197 183 198 /* 184 199 * Copy of AAD from source to destination ··· 209 194 */ 210 195 211 196 /* Use the RX SGL as source (and destination) for crypto op. */ 212 - src = areq->first_rsgl.sgl.sg; 197 + rsgl_src = areq->first_rsgl.sgl.sg; 213 198 214 199 if (ctx->enc) { 215 200 /* ··· 222 207 * v v 223 208 * RX SGL: AAD || PT || Tag 224 209 */ 225 - err = crypto_aead_copy_sgl(null_tfm, tsgl->sg, 210 + err = crypto_aead_copy_sgl(null_tfm, tsgl_src, 226 211 areq->first_rsgl.sgl.sg, processed); 227 212 if (err) 228 213 goto free; ··· 240 225 */ 241 226 242 227 /* Copy AAD || CT to RX SGL buffer for in-place operation. */ 243 - err = crypto_aead_copy_sgl(null_tfm, tsgl->sg, 228 + err = crypto_aead_copy_sgl(null_tfm, tsgl_src, 244 229 areq->first_rsgl.sgl.sg, outlen); 245 230 if (err) 246 231 goto free; ··· 272 257 areq->tsgl); 273 258 } else 274 259 /* no RX SGL present (e.g. authentication only) */ 275 - src = areq->tsgl; 260 + rsgl_src = areq->tsgl; 276 261 } 277 262 278 263 /* Initialize the crypto operation */ 279 - aead_request_set_crypt(&areq->cra_u.aead_req, src, 264 + aead_request_set_crypt(&areq->cra_u.aead_req, rsgl_src, 280 265 areq->first_rsgl.sgl.sg, used, ctx->iv); 281 266 aead_request_set_ad(&areq->cra_u.aead_req, ctx->aead_assoclen); 282 267 aead_request_set_tfm(&areq->cra_u.aead_req, tfm); 283 268 284 269 if (msg->msg_iocb && !is_sync_kiocb(msg->msg_iocb)) { 285 270 /* AIO operation */ 271 + sock_hold(sk); 286 272 areq->iocb = msg->msg_iocb; 287 273 aead_request_set_callback(&areq->cra_u.aead_req, 288 274 CRYPTO_TFM_REQ_MAY_BACKLOG, 289 275 af_alg_async_cb, areq); 290 276 err = ctx->enc ? crypto_aead_encrypt(&areq->cra_u.aead_req) : 291 277 crypto_aead_decrypt(&areq->cra_u.aead_req); 278 + 279 + /* AIO operation in progress */ 280 + if (err == -EINPROGRESS || err == -EBUSY) { 281 + /* Remember output size that will be generated. */ 282 + areq->outlen = outlen; 283 + 284 + return -EIOCBQUEUED; 285 + } 286 + 287 + sock_put(sk); 292 288 } else { 293 289 /* Synchronous operation */ 294 290 aead_request_set_callback(&areq->cra_u.aead_req, ··· 311 285 &ctx->wait); 312 286 } 313 287 314 - /* AIO operation in progress */ 315 - if (err == -EINPROGRESS) { 316 - sock_hold(sk); 317 - 318 - /* Remember output size that will be generated. */ 319 - areq->outlen = outlen; 320 - 321 - return -EIOCBQUEUED; 322 - } 323 288 324 289 free: 325 - af_alg_free_areq_sgls(areq); 326 - sock_kfree_s(sk, areq, areq->areqlen); 290 + af_alg_free_resources(areq); 327 291 328 292 return err ? err : outlen; 329 293 }
+12 -11
crypto/algif_skcipher.c
··· 117 117 118 118 if (msg->msg_iocb && !is_sync_kiocb(msg->msg_iocb)) { 119 119 /* AIO operation */ 120 + sock_hold(sk); 120 121 areq->iocb = msg->msg_iocb; 121 122 skcipher_request_set_callback(&areq->cra_u.skcipher_req, 122 123 CRYPTO_TFM_REQ_MAY_SLEEP, ··· 125 124 err = ctx->enc ? 126 125 crypto_skcipher_encrypt(&areq->cra_u.skcipher_req) : 127 126 crypto_skcipher_decrypt(&areq->cra_u.skcipher_req); 127 + 128 + /* AIO operation in progress */ 129 + if (err == -EINPROGRESS || err == -EBUSY) { 130 + /* Remember output size that will be generated. */ 131 + areq->outlen = len; 132 + 133 + return -EIOCBQUEUED; 134 + } 135 + 136 + sock_put(sk); 128 137 } else { 129 138 /* Synchronous operation */ 130 139 skcipher_request_set_callback(&areq->cra_u.skcipher_req, ··· 147 136 &ctx->wait); 148 137 } 149 138 150 - /* AIO operation in progress */ 151 - if (err == -EINPROGRESS) { 152 - sock_hold(sk); 153 - 154 - /* Remember output size that will be generated. */ 155 - areq->outlen = len; 156 - 157 - return -EIOCBQUEUED; 158 - } 159 139 160 140 free: 161 - af_alg_free_areq_sgls(areq); 162 - sock_kfree_s(sk, areq, areq->areqlen); 141 + af_alg_free_resources(areq); 163 142 164 143 return err ? err : len; 165 144 }
+3
crypto/skcipher.c
··· 522 522 scatterwalk_copychunks(NULL, &walk->in, req->assoclen, 2); 523 523 scatterwalk_copychunks(NULL, &walk->out, req->assoclen, 2); 524 524 525 + scatterwalk_done(&walk->in, 0, walk->total); 526 + scatterwalk_done(&walk->out, 0, walk->total); 527 + 525 528 walk->iv = req->iv; 526 529 walk->oiv = req->iv; 527 530
+1
include/crypto/if_alg.h
··· 242 242 unsigned int ivsize); 243 243 ssize_t af_alg_sendpage(struct socket *sock, struct page *page, 244 244 int offset, size_t size, int flags); 245 + void af_alg_free_resources(struct af_alg_async_req *areq); 245 246 void af_alg_async_cb(struct crypto_async_request *_req, int err); 246 247 unsigned int af_alg_poll(struct file *file, struct socket *sock, 247 248 poll_table *wait);