From patchwork Thu Aug 10 14:40:03 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stephan Mueller X-Patchwork-Id: 9893871 X-Patchwork-Delegate: herbert@gondor.apana.org.au Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 9D14060384 for ; Thu, 10 Aug 2017 14:40:07 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 8F20C28B35 for ; Thu, 10 Aug 2017 14:40:07 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 83CE028B38; Thu, 10 Aug 2017 14:40:07 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.9 required=2.0 tests=BAYES_00,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id AD03B28B35 for ; Thu, 10 Aug 2017 14:40:06 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752317AbdHJOkF (ORCPT ); Thu, 10 Aug 2017 10:40:05 -0400 Received: from mail.eperm.de ([89.247.134.16]:58480 "EHLO mail.eperm.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752091AbdHJOkF (ORCPT ); Thu, 10 Aug 2017 10:40:05 -0400 Received: from positron.chronox.de (mail.eperm.de [89.247.134.16]) by mail.eperm.de (Postfix) with ESMTPA id C66B3181607A; Thu, 10 Aug 2017 16:40:03 +0200 (CEST) From: Stephan =?ISO-8859-1?Q?M=FCller?= To: herbert@gondor.apana.org.au Cc: linux-crypto@vger.kernel.org Subject: [PATCH] crypto: AF_ALG - get_page upon reassignment to TX SGL Date: Thu, 10 Aug 2017 16:40:03 +0200 Message-ID: <2704295.VBAGuigrBX@positron.chronox.de> MIME-Version: 1.0 Sender: linux-crypto-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-crypto@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Hi Herbert, The error can be triggered with the following test. Invoking that test in a while [ 1 ] loop shows that no memory is leaked. #include #include int main(int argc, char *argv[]) { char buf[8192]; struct kcapi_handle *handle; struct iovec iov; int ret; (void)argc; (void)argv; iov.iov_base = buf; ret = kcapi_cipher_init(&handle, "ctr(aes)", 0); if (ret) return ret; ret = kcapi_cipher_setkey(handle, (unsigned char *)"0123456789abcdef", 16); if (ret) return ret; ret = kcapi_cipher_stream_init_enc(handle, (unsigned char *)"0123456789abcdef", NULL, 0); if (ret < 0) return ret; iov.iov_len = 4152; ret = kcapi_cipher_stream_update(handle, &iov, 1); if (ret < 0) return ret; iov.iov_len = 4096; ret = kcapi_cipher_stream_op(handle, &iov, 1); if (ret < 0) return ret; kcapi_cipher_destroy(handle); return 0; } ---8<--- When a page is assigned to a TX SGL, call get_page to increment the reference counter. It is possible that one page is referenced in multiple SGLs: - in the global TX SGL in case a previous af_alg_pull_tsgl only reassigned parts of a page to a per-request TX SGL - in the per-request TX SGL as assigned by af_alg_pull_tsgl Note, multiple requests can be active at the same time whose TX SGLs all point to different parts of the same page. Signed-off-by: Stephan Mueller --- crypto/af_alg.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/crypto/af_alg.c b/crypto/af_alg.c index d6936c0e08d9..ffa9f4ccd9b4 100644 --- a/crypto/af_alg.c +++ b/crypto/af_alg.c @@ -641,9 +641,9 @@ void af_alg_pull_tsgl(struct sock *sk, size_t used, struct scatterlist *dst, if (dst_offset >= plen) { /* discard page before offset */ dst_offset -= plen; - put_page(page); } else { /* reassign page to dst after offset */ + get_page(page); sg_set_page(dst + j, page, plen - dst_offset, sg[i].offset + dst_offset); @@ -661,9 +661,7 @@ void af_alg_pull_tsgl(struct sock *sk, size_t used, struct scatterlist *dst, if (sg[i].length) return; - if (!dst) - put_page(page); - + put_page(page); sg_assign_page(sg + i, NULL); }