提交 136f702f 编写于 作者: P Patrick McHardy 提交者: Herbert Xu

[HIFN]: Properly handle requests for less than the full scatterlist

    
The scatterlist may contain more data than the crypto request, causing
an underflow of the remaining byte count while walking the list.
    
Use the minimum of the scatterlist element size and the remaining byte
count specified in the crypto request to avoid this.
Signed-off-by: NPatrick McHardy <kaber@trash.net>
Acked-by: NEvgeniy Polyakov <johnpol@2ka.mipt.ru>
Signed-off-by: NHerbert Xu <herbert@gondor.apana.org.au>
上级 d069033b
...@@ -1433,7 +1433,7 @@ static int ablkcipher_add(void *daddr, unsigned int *drestp, struct scatterlist ...@@ -1433,7 +1433,7 @@ static int ablkcipher_add(void *daddr, unsigned int *drestp, struct scatterlist
return -EINVAL; return -EINVAL;
while (size) { while (size) {
copy = min(drest, src->length); copy = min(drest, min(size, src->length));
saddr = kmap_atomic(sg_page(src), KM_SOFTIRQ1); saddr = kmap_atomic(sg_page(src), KM_SOFTIRQ1);
memcpy(daddr, saddr + src->offset, copy); memcpy(daddr, saddr + src->offset, copy);
...@@ -1482,7 +1482,7 @@ static int ablkcipher_walk(struct ablkcipher_request *req, ...@@ -1482,7 +1482,7 @@ static int ablkcipher_walk(struct ablkcipher_request *req,
if (!IS_ALIGNED(dst->offset, HIFN_D_DST_DALIGN) || if (!IS_ALIGNED(dst->offset, HIFN_D_DST_DALIGN) ||
!IS_ALIGNED(dst->length, HIFN_D_DST_DALIGN) || !IS_ALIGNED(dst->length, HIFN_D_DST_DALIGN) ||
offset) { offset) {
unsigned slen = src->length - offset; unsigned slen = min(src->length - offset, nbytes);
unsigned dlen = PAGE_SIZE; unsigned dlen = PAGE_SIZE;
t = &w->cache[idx]; t = &w->cache[idx];
...@@ -1540,7 +1540,7 @@ static int ablkcipher_walk(struct ablkcipher_request *req, ...@@ -1540,7 +1540,7 @@ static int ablkcipher_walk(struct ablkcipher_request *req,
kunmap_atomic(daddr, KM_SOFTIRQ0); kunmap_atomic(daddr, KM_SOFTIRQ0);
} else { } else {
nbytes -= src->length; nbytes -= min(src->length, nbytes);
idx++; idx++;
} }
...@@ -1559,7 +1559,7 @@ static int hifn_setup_session(struct ablkcipher_request *req) ...@@ -1559,7 +1559,7 @@ static int hifn_setup_session(struct ablkcipher_request *req)
struct hifn_context *ctx = crypto_tfm_ctx(req->base.tfm); struct hifn_context *ctx = crypto_tfm_ctx(req->base.tfm);
struct hifn_device *dev = ctx->dev; struct hifn_device *dev = ctx->dev;
struct page *spage, *dpage; struct page *spage, *dpage;
unsigned long soff, doff, flags; unsigned long soff, doff, dlen, flags;
unsigned int nbytes = req->nbytes, idx = 0, len; unsigned int nbytes = req->nbytes, idx = 0, len;
int err = -EINVAL, sg_num; int err = -EINVAL, sg_num;
struct scatterlist *src, *dst, *t; struct scatterlist *src, *dst, *t;
...@@ -1571,12 +1571,13 @@ static int hifn_setup_session(struct ablkcipher_request *req) ...@@ -1571,12 +1571,13 @@ static int hifn_setup_session(struct ablkcipher_request *req)
while (nbytes) { while (nbytes) {
dst = &req->dst[idx]; dst = &req->dst[idx];
dlen = min(dst->length, nbytes);
if (!IS_ALIGNED(dst->offset, HIFN_D_DST_DALIGN) || if (!IS_ALIGNED(dst->offset, HIFN_D_DST_DALIGN) ||
!IS_ALIGNED(dst->length, HIFN_D_DST_DALIGN)) !IS_ALIGNED(dlen, HIFN_D_DST_DALIGN))
ctx->walk.flags |= ASYNC_FLAGS_MISALIGNED; ctx->walk.flags |= ASYNC_FLAGS_MISALIGNED;
nbytes -= dst->length; nbytes -= dlen;
idx++; idx++;
} }
...@@ -1631,7 +1632,7 @@ static int hifn_setup_session(struct ablkcipher_request *req) ...@@ -1631,7 +1632,7 @@ static int hifn_setup_session(struct ablkcipher_request *req)
if (err) if (err)
goto err_out; goto err_out;
nbytes -= len; nbytes -= min(len, nbytes);
} }
dev->active = HIFN_DEFAULT_ACTIVE_NUM; dev->active = HIFN_DEFAULT_ACTIVE_NUM;
...@@ -1736,8 +1737,7 @@ static int ablkcipher_get(void *saddr, unsigned int *srestp, unsigned int offset ...@@ -1736,8 +1737,7 @@ static int ablkcipher_get(void *saddr, unsigned int *srestp, unsigned int offset
return -EINVAL; return -EINVAL;
while (size) { while (size) {
copy = min(srest, min(dst->length, size));
copy = min(dst->length, srest);
daddr = kmap_atomic(sg_page(dst), KM_IRQ0); daddr = kmap_atomic(sg_page(dst), KM_IRQ0);
memcpy(daddr + dst->offset + offset, saddr, copy); memcpy(daddr + dst->offset + offset, saddr, copy);
...@@ -1794,7 +1794,7 @@ static void hifn_process_ready(struct ablkcipher_request *req, int error) ...@@ -1794,7 +1794,7 @@ static void hifn_process_ready(struct ablkcipher_request *req, int error)
sg_page(dst), dst->length, nbytes); sg_page(dst), dst->length, nbytes);
if (!t->length) { if (!t->length) {
nbytes -= dst->length; nbytes -= min(dst->length, nbytes);
idx++; idx++;
continue; continue;
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册