From patchwork Tue Oct 21 22:57:08 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: vkamensky X-Patchwork-Id: 39233 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-wi0-f198.google.com (mail-wi0-f198.google.com [209.85.212.198]) by ip-10-151-82-157.ec2.internal (Postfix) with ESMTPS id 0A5DB202DB for ; Tue, 21 Oct 2014 22:57:49 +0000 (UTC) Received: by mail-wi0-f198.google.com with SMTP id hi2sf1474345wib.5 for ; Tue, 21 Oct 2014 15:57:49 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:delivered-to:from:to:cc:subject :date:message-id:in-reply-to:references:sender:precedence:list-id :x-original-sender:x-original-authentication-results:mailing-list :list-post:list-help:list-archive:list-unsubscribe; bh=bMNfu1MvVyr8z8ZEoa6KTfn0t5+ClBq0stDADXqCFjA=; b=MsWvQlTCW75f5tjPhtxBL1DZ99Qb7t3W0664Rr0bvi+FEemmHQJ+MPRO3rtVZlv2XO h2VhAn/6SCBF0QdwYxax/TuB43LP01pi6YN0rfeFy3Es95rceZ1+YW/srIwClXU5gD3y yaamgBQzzf7lETr+ZGtvJ+FfJVNfym5d2FNj40SHhVX7LPTCUftqrIhrAIKfB/uoYHl5 EOhM91euR6RYVC56mwvqQWBjZ9fgn3f1sOXLpvcTriSJl6/kZA+/sh0UzEmuMXBdQr/K spw7MfDIIh5+iDxYmSRNUelL3WUwYiLFBeZtPu7IKBkBwdQeTNGv/16lrZx7HhvQyj5p 08UQ== X-Gm-Message-State: ALoCoQkdilHWmdGgE5CqPhTrKgLB912/QXcewXvm3PJyHKm+Dvz7XyJNfEUcokIgAFN/dRd7uvmU X-Received: by 10.180.186.142 with SMTP id fk14mr4053638wic.4.1413932269218; Tue, 21 Oct 2014 15:57:49 -0700 (PDT) MIME-Version: 1.0 X-BeenThere: patchwork-forward@linaro.org Received: by 10.152.7.230 with SMTP id m6ls115310laa.89.gmail; Tue, 21 Oct 2014 15:57:48 -0700 (PDT) X-Received: by 10.152.26.8 with SMTP id h8mr37894787lag.39.1413932268857; Tue, 21 Oct 2014 15:57:48 -0700 (PDT) Received: from mail-lb0-f171.google.com (mail-lb0-f171.google.com. [209.85.217.171]) by mx.google.com with ESMTPS id y2si21017413lae.49.2014.10.21.15.57.48 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Tue, 21 Oct 2014 15:57:48 -0700 (PDT) Received-SPF: pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.217.171 as permitted sender) client-ip=209.85.217.171; Received: by mail-lb0-f171.google.com with SMTP id z12so1876266lbi.16 for ; Tue, 21 Oct 2014 15:57:48 -0700 (PDT) X-Received: by 10.112.99.136 with SMTP id eq8mr28142721lbb.57.1413932268757; Tue, 21 Oct 2014 15:57:48 -0700 (PDT) X-Forwarded-To: patchwork-forward@linaro.org X-Forwarded-For: patch@linaro.org patchwork-forward@linaro.org Delivered-To: patch@linaro.org Received: by 10.112.84.229 with SMTP id c5csp594720lbz; Tue, 21 Oct 2014 15:57:47 -0700 (PDT) X-Received: by 10.68.102.100 with SMTP id fn4mr38625715pbb.48.1413932267206; Tue, 21 Oct 2014 15:57:47 -0700 (PDT) Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id cy1si12483610pdb.248.2014.10.21.15.57.44 for ; Tue, 21 Oct 2014 15:57:47 -0700 (PDT) Received-SPF: none (google.com: linux-kernel-owner@vger.kernel.org does not designate permitted sender hosts) client-ip=209.132.180.67; Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S933981AbaJUW5k (ORCPT + 27 others); Tue, 21 Oct 2014 18:57:40 -0400 Received: from mail-pa0-f49.google.com ([209.85.220.49]:53993 "EHLO mail-pa0-f49.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S933910AbaJUW5Z (ORCPT ); Tue, 21 Oct 2014 18:57:25 -0400 Received: by mail-pa0-f49.google.com with SMTP id hz1so2361021pad.36 for ; Tue, 21 Oct 2014 15:57:25 -0700 (PDT) X-Received: by 10.68.167.99 with SMTP id zn3mr38257336pbb.30.1413932245227; Tue, 21 Oct 2014 15:57:25 -0700 (PDT) Received: from kamensky-w530.cisco.com ([2001:420:301:1272:9d0:afbe:640f:21a1]) by mx.google.com with ESMTPSA id v4sm12826303pdh.57.2014.10.21.15.57.23 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 21 Oct 2014 15:57:24 -0700 (PDT) From: Victor Kamensky To: Alexander Viro , linux-fsdevel@vger.kernel.org Cc: Andrew Morton , Kees Cook , Oleg Nesterov , linux-kernel@vger.kernel.org, Victor Kamensky Subject: [RFC PATCH] coredump: fix incomplete core file created when dump_skip was used last Date: Tue, 21 Oct 2014 15:57:08 -0700 Message-Id: <1413932228-27642-2-git-send-email-victor.kamensky@linaro.org> X-Mailer: git-send-email 1.8.1.4 In-Reply-To: <1413932228-27642-1-git-send-email-victor.kamensky@linaro.org> References: <1413932228-27642-1-git-send-email-victor.kamensky@linaro.org> Sender: linux-kernel-owner@vger.kernel.org Precedence: list List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-Removed-Original-Auth: Dkim didn't pass. X-Original-Sender: victor.kamensky@linaro.org X-Original-Authentication-Results: mx.google.com; spf=pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.217.171 as permitted sender) smtp.mail=patch+caf_=patchwork-forward=linaro.org@linaro.org Mailing-list: list patchwork-forward@linaro.org; contact patchwork-forward+owners@linaro.org X-Google-Group-Id: 836684582541 List-Post: , List-Help: , List-Archive: List-Unsubscribe: , There are situation when dump_skip is used on last part of core file with intent of creating zeros. However if it is not followed by any write (through dump_emit) zeros will not be written into the file. I.e llseek without subsequent write does not create any content. Such issue happened during bigcore.exp gdb testsuite run on ARM V7 rootfs running on top of ARM V8 kenel (compat mode). For last vma in elf_core_dump function last 5 pages could not be mapped and as result dump_skip was called. And resulting core file was missing 5 last pages and gdb complained about that. Solution is to introduce new field into coredump_params struct that would track whether last helper used did real write or llseek. If last operation was llseek, move position back to 1 byte and write 1 zero byte. As result all content intended with last dump_skip will appear in core file as zeros. Signed-off-by: Victor Kamensky --- fs/coredump.c | 26 ++++++++++++++++++++++++++ include/linux/binfmts.h | 6 ++++++ 2 files changed, 32 insertions(+) diff --git a/fs/coredump.c b/fs/coredump.c index a93f7e6..da0000b 100644 --- a/fs/coredump.c +++ b/fs/coredump.c @@ -489,6 +489,27 @@ static int umh_pipe_setup(struct subprocess_info *info, struct cred *new) return err; } +/* + * Write last byte into core file. It is called if last operation + * on core file was llseek through dump_skip, and we need to write + * something at the end of the file, so zeros intended to be added + * by dump_skip will go into the file. + */ +static int dump_write_last_byte(struct coredump_params *cprm) +{ + char lastbyte = 0; + struct file *file = cprm->file; + + if (file->f_op->llseek && file->f_op->llseek != no_llseek) { + if (dump_interrupted() || + file->f_op->llseek(file, -1, SEEK_CUR) < 0) + return 0; + if (!dump_emit(cprm, &lastbyte, 1)) + return 0; + } + return 1; +} + void do_coredump(const siginfo_t *siginfo) { struct core_state core_state; @@ -514,6 +535,7 @@ void do_coredump(const siginfo_t *siginfo) * by any locks. */ .mm_flags = mm->flags, + .last_op_status = COREDUMP_LAST_WRITE, }; audit_core_dumps(siginfo->si_signo); @@ -664,6 +686,8 @@ void do_coredump(const siginfo_t *siginfo) if (!dump_interrupted()) { file_start_write(cprm.file); core_dumped = binfmt->core_dump(&cprm); + if (cprm.last_op_status == COREDUMP_LAST_LLSEEK) + dump_write_last_byte(&cprm); file_end_write(cprm.file); } if (ispipe && core_pipe_limit) @@ -706,6 +730,7 @@ int dump_emit(struct coredump_params *cprm, const void *addr, int nr) cprm->written += n; nr -= n; } + cprm->last_op_status = COREDUMP_LAST_WRITE; return 1; } EXPORT_SYMBOL(dump_emit); @@ -721,6 +746,7 @@ int dump_skip(struct coredump_params *cprm, size_t nr) file->f_op->llseek(file, nr, SEEK_CUR) < 0) return 0; cprm->written += nr; + cprm->last_op_status = COREDUMP_LAST_LLSEEK; return 1; } else { while (nr > PAGE_SIZE) { diff --git a/include/linux/binfmts.h b/include/linux/binfmts.h index 61f29e5..5f4ad91 100644 --- a/include/linux/binfmts.h +++ b/include/linux/binfmts.h @@ -53,6 +53,11 @@ struct linux_binprm { #define BINPRM_FLAGS_EXECFD_BIT 1 #define BINPRM_FLAGS_EXECFD (1 << BINPRM_FLAGS_EXECFD_BIT) +/* last coredump operation status */ + +#define COREDUMP_LAST_WRITE 1 +#define COREDUMP_LAST_LLSEEK 2 + /* Function parameter for binfmt->coredump */ struct coredump_params { const siginfo_t *siginfo; @@ -61,6 +66,7 @@ struct coredump_params { unsigned long limit; unsigned long mm_flags; loff_t written; + int last_op_status; }; /*