From owner-svn-src-stable@freebsd.org Thu Jan 26 09:46:35 2017 Return-Path: Delivered-To: svn-src-stable@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 92C80CBFB7A; Thu, 26 Jan 2017 09:46:35 +0000 (UTC) (envelope-from avg@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 511D466E; Thu, 26 Jan 2017 09:46:35 +0000 (UTC) (envelope-from avg@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id v0Q9kYIo021337; Thu, 26 Jan 2017 09:46:34 GMT (envelope-from avg@FreeBSD.org) Received: (from avg@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id v0Q9kYet021336; Thu, 26 Jan 2017 09:46:34 GMT (envelope-from avg@FreeBSD.org) Message-Id: <201701260946.v0Q9kYet021336@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: avg set sender to avg@FreeBSD.org using -f From: Andriy Gapon Date: Thu, 26 Jan 2017 09:46:34 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-11@freebsd.org Subject: svn commit: r312794 - stable/11/sys/kern X-SVN-Group: stable-11 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for all the -stable branches of the src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 26 Jan 2017 09:46:35 -0000 Author: avg Date: Thu Jan 26 09:46:34 2017 New Revision: 312794 URL: https://svnweb.freebsd.org/changeset/base/312794 Log: MFC r312532: don't abort writing of a core dump after EFAULT Modified: stable/11/sys/kern/imgact_elf.c Directory Properties: stable/11/ (props changed) Modified: stable/11/sys/kern/imgact_elf.c ============================================================================== --- stable/11/sys/kern/imgact_elf.c Thu Jan 26 07:07:09 2017 (r312793) +++ stable/11/sys/kern/imgact_elf.c Thu Jan 26 09:46:34 2017 (r312794) @@ -1160,7 +1160,7 @@ struct coredump_params { static void cb_put_phdr(vm_map_entry_t, void *); static void cb_size_segment(vm_map_entry_t, void *); -static int core_write(struct coredump_params *, void *, size_t, off_t, +static int core_write(struct coredump_params *, const void *, size_t, off_t, enum uio_seg); static void each_writable_segment(struct thread *, segment_callback, void *); static int __elfN(corehdr)(struct coredump_params *, int, void *, size_t, @@ -1202,7 +1202,14 @@ compress_chunk(struct coredump_params *p while (len > 0) { chunk_len = MIN(len, CORE_BUF_SIZE); - copyin(base, buf, chunk_len); + + /* + * We can get EFAULT error here. + * In that case zero out the current chunk of the segment. + */ + error = copyin(base, buf, chunk_len); + if (error != 0) + bzero(buf, chunk_len); error = gzio_write(p->gzs, buf, chunk_len); if (error != 0) break; @@ -1222,12 +1229,12 @@ core_gz_write(void *base, size_t len, of #endif /* GZIO */ static int -core_write(struct coredump_params *p, void *base, size_t len, off_t offset, - enum uio_seg seg) +core_write(struct coredump_params *p, const void *base, size_t len, + off_t offset, enum uio_seg seg) { - return (vn_rdwr_inchunks(UIO_WRITE, p->vp, base, len, offset, - seg, IO_UNIT | IO_DIRECT | IO_RANGELOCKED, + return (vn_rdwr_inchunks(UIO_WRITE, p->vp, __DECONST(void *, base), + len, offset, seg, IO_UNIT | IO_DIRECT | IO_RANGELOCKED, p->active_cred, p->file_cred, NULL, p->td)); } @@ -1235,12 +1242,32 @@ static int core_output(void *base, size_t len, off_t offset, struct coredump_params *p, void *tmpbuf) { + int error; #ifdef GZIO if (p->gzs != NULL) return (compress_chunk(p, base, tmpbuf, len)); #endif - return (core_write(p, base, len, offset, UIO_USERSPACE)); + /* + * EFAULT is a non-fatal error that we can get, for example, + * if the segment is backed by a file but extends beyond its + * end. + */ + error = core_write(p, base, len, offset, UIO_USERSPACE); + if (error == EFAULT) { + log(LOG_WARNING, "Failed to fully fault in a core file segment " + "at VA %p with size 0x%zx to be written at offset 0x%jx " + "for process %s\n", base, len, offset, curproc->p_comm); + + /* + * Write a "real" zero byte at the end of the target region + * in the case this is the last segment. + * The intermediate space will be implicitly zero-filled. + */ + error = core_write(p, zero_region, 1, offset + len - 1, + UIO_SYSSPACE); + } + return (error); } /*