Skip to content

Commit

Permalink
crypto: skcipher - Fix skcipher_dequeue_givcrypt NULL test
Browse files Browse the repository at this point in the history
As struct skcipher_givcrypt_request includes struct crypto_request
at a non-zero offset, testing for NULL after converting the pointer
returned by crypto_dequeue_request does not work.  This can result
in IPsec crashes when the queue is depleted.

This patch fixes it by doing the pointer conversion only when the
return value is non-NULL.  In particular, we create a new function
__crypto_dequeue_request that does the pointer conversion.

Reported-by: Brad Bosch <bradbosch@comcast.net>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
  • Loading branch information
herbertx committed Aug 29, 2009
1 parent b6f34d4 commit 0c7d400
Show file tree
Hide file tree
Showing 3 changed files with 12 additions and 4 deletions.
11 changes: 9 additions & 2 deletions crypto/algapi.c
Expand Up @@ -692,7 +692,7 @@ int crypto_enqueue_request(struct crypto_queue *queue,
}
EXPORT_SYMBOL_GPL(crypto_enqueue_request);

struct crypto_async_request *crypto_dequeue_request(struct crypto_queue *queue)
void *__crypto_dequeue_request(struct crypto_queue *queue, unsigned int offset)
{
struct list_head *request;

Expand All @@ -707,7 +707,14 @@ struct crypto_async_request *crypto_dequeue_request(struct crypto_queue *queue)
request = queue->list.next;
list_del(request);

return list_entry(request, struct crypto_async_request, list);
return (char *)list_entry(request, struct crypto_async_request, list) -
offset;
}
EXPORT_SYMBOL_GPL(__crypto_dequeue_request);

struct crypto_async_request *crypto_dequeue_request(struct crypto_queue *queue)
{
return __crypto_dequeue_request(queue, 0);
}
EXPORT_SYMBOL_GPL(crypto_dequeue_request);

Expand Down
1 change: 1 addition & 0 deletions include/crypto/algapi.h
Expand Up @@ -137,6 +137,7 @@ struct crypto_instance *crypto_alloc_instance(const char *name,
void crypto_init_queue(struct crypto_queue *queue, unsigned int max_qlen);
int crypto_enqueue_request(struct crypto_queue *queue,
struct crypto_async_request *request);
void *__crypto_dequeue_request(struct crypto_queue *queue, unsigned int offset);
struct crypto_async_request *crypto_dequeue_request(struct crypto_queue *queue);
int crypto_tfm_in_queue(struct crypto_queue *queue, struct crypto_tfm *tfm);

Expand Down
4 changes: 2 additions & 2 deletions include/crypto/internal/skcipher.h
Expand Up @@ -79,8 +79,8 @@ static inline int skcipher_enqueue_givcrypt(
static inline struct skcipher_givcrypt_request *skcipher_dequeue_givcrypt(
struct crypto_queue *queue)
{
return container_of(ablkcipher_dequeue_request(queue),
struct skcipher_givcrypt_request, creq);
return __crypto_dequeue_request(
queue, offsetof(struct skcipher_givcrypt_request, creq.base));
}

static inline void *skcipher_givcrypt_reqctx(
Expand Down

0 comments on commit 0c7d400

Please sign in to comment.