summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHerbert Xu <herbert@gondor.apana.org.au>2008-04-29 21:53:52 +0800
committerHerbert Xu <herbert@gondor.apana.org.au>2008-05-01 18:22:28 +0800
commit8ec970d8561abb5645d4602433b772e268c96d05 (patch)
treed48569fb99e2fefad3e9b89f867bc8fd194f5950
parent161613293fd4b7d5ceb1faab788f47e688e07a67 (diff)
[CRYPTO] api: Fix scatterwalk_sg_chain
When I backed out of using the generic sg chaining (as it isn't currently portable) and introduced scatterwalk_sg_chain/scatterwalk_sg_next I left out the sg_is_last check in the latter. This causes it to potentially dereference beyond the end of the sg array. As most uses of scatterwalk_sg_next are bound by an overall length, this only affected the chaining code in authenc and eseqiv. Thanks to Patrick McHardy for identifying this problem. This patch also clears the "last" bit on the head of the chained list as it's no longer last. This also went missing in scatterwalk_sg_chain and is present in sg_chain. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
-rw-r--r--include/crypto/scatterwalk.h4
1 files changed, 4 insertions, 0 deletions
diff --git a/include/crypto/scatterwalk.h b/include/crypto/scatterwalk.h
index 224658b8d80..833d208c25d 100644
--- a/include/crypto/scatterwalk.h
+++ b/include/crypto/scatterwalk.h
@@ -57,10 +57,14 @@ static inline void scatterwalk_sg_chain(struct scatterlist *sg1, int num,
struct scatterlist *sg2)
{
sg_set_page(&sg1[num - 1], (void *)sg2, 0, 0);
+ sg1[num - 1].page_link &= ~0x02;
}
static inline struct scatterlist *scatterwalk_sg_next(struct scatterlist *sg)
{
+ if (sg_is_last(sg))
+ return NULL;
+
return (++sg)->length ? sg : (void *)sg_page(sg);
}