From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S942543AbcJZNGS (ORCPT ); Wed, 26 Oct 2016 09:06:18 -0400 Received: from mail.linuxfoundation.org ([140.211.169.12]:55616 "EHLO mail.linuxfoundation.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S965945AbcJZMbF (ORCPT ); Wed, 26 Oct 2016 08:31:05 -0400 From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Anton Vorontsov , Colin Cross , Kees Cook , Tony Luck , Namhyung Kim , Sebastian Andrzej Siewior Subject: [PATCH 4.4 015/112] pstore/ramoops: fixup driver removal Date: Wed, 26 Oct 2016 14:21:58 +0200 Message-Id: <20161026122305.434350214@linuxfoundation.org> X-Mailer: git-send-email 2.10.1 In-Reply-To: <20161026122304.797016625@linuxfoundation.org> References: <20161026122304.797016625@linuxfoundation.org> User-Agent: quilt/0.64 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 4.4-stable review patch. If anyone has any objections, please let me know. ------------------ From: Sebastian Andrzej Siewior commit 4407de74df18ed405cc5998990004c813ccfdbde upstream. A basic rmmod ramoops segfaults. Let's see why. Since commit 34f0ec82e0a9 ("pstore: Correct the max_dump_cnt clearing of ramoops") sets ->max_dump_cnt to zero before looping over ->przs but we didn't use it before that either. And since commit ee1d267423a1 ("pstore: add pstore unregister") we free that memory on rmmod. But even then, we looped until a NULL pointer or ERR. I don't see where it is ensured that the last member is NULL. Let's try this instead: simply error recovery and free. Clean up in error case where resources were allocated. And then, in the free path, rely on ->max_dump_cnt in the free path. Cc: Anton Vorontsov Cc: Colin Cross Cc: Kees Cook Cc: Tony Luck Cc: Namhyung Kim Acked-by: Namhyung Kim Signed-off-by: Sebastian Andrzej Siewior Signed-off-by: Kees Cook Signed-off-by: Greg Kroah-Hartman --- fs/pstore/ram.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) --- a/fs/pstore/ram.c +++ b/fs/pstore/ram.c @@ -375,13 +375,14 @@ static void ramoops_free_przs(struct ram { int i; - cxt->max_dump_cnt = 0; if (!cxt->przs) return; - for (i = 0; !IS_ERR_OR_NULL(cxt->przs[i]); i++) + for (i = 0; i < cxt->max_dump_cnt; i++) persistent_ram_free(cxt->przs[i]); + kfree(cxt->przs); + cxt->max_dump_cnt = 0; } static int ramoops_init_przs(struct device *dev, struct ramoops_context *cxt, @@ -406,7 +407,7 @@ static int ramoops_init_przs(struct devi GFP_KERNEL); if (!cxt->przs) { dev_err(dev, "failed to initialize a prz array for dumps\n"); - goto fail_prz; + goto fail_mem; } for (i = 0; i < cxt->max_dump_cnt; i++) { @@ -417,6 +418,11 @@ static int ramoops_init_przs(struct devi err = PTR_ERR(cxt->przs[i]); dev_err(dev, "failed to request mem region (0x%zx@0x%llx): %d\n", cxt->record_size, (unsigned long long)*paddr, err); + + while (i > 0) { + i--; + persistent_ram_free(cxt->przs[i]); + } goto fail_prz; } *paddr += cxt->record_size; @@ -424,7 +430,9 @@ static int ramoops_init_przs(struct devi return 0; fail_prz: - ramoops_free_przs(cxt); + kfree(cxt->przs); +fail_mem: + cxt->max_dump_cnt = 0; return err; } @@ -583,7 +591,6 @@ static int ramoops_remove(struct platfor struct ramoops_context *cxt = &oops_cxt; pstore_unregister(&cxt->pstore); - cxt->max_dump_cnt = 0; kfree(cxt->pstore.buf); cxt->pstore.bufsize = 0;