Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 26 Jan 2017 16:38:53 +0000 (UTC)
From:      Andriy Gapon <avg@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org
Subject:   svn commit: r312819 - stable/10/sys/kern
Message-ID:  <201701261638.v0QGcroW091532@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: avg
Date: Thu Jan 26 16:38:53 2017
New Revision: 312819
URL: https://svnweb.freebsd.org/changeset/base/312819

Log:
  MFC r312532: don't abort writing of a core dump after EFAULT
  
  Note that this change substantially differs from the change in head
  because of an unmerged earlier change that probably can not be merged
  for POLA reasons.

Modified:
  stable/10/sys/kern/imgact_elf.c
Directory Properties:
  stable/10/   (props changed)

Modified: stable/10/sys/kern/imgact_elf.c
==============================================================================
--- stable/10/sys/kern/imgact_elf.c	Thu Jan 26 16:36:12 2017	(r312818)
+++ stable/10/sys/kern/imgact_elf.c	Thu Jan 26 16:38:53 2017	(r312819)
@@ -1176,9 +1176,31 @@ core_output(struct vnode *vp, void *base
 		panic("shouldn't be here");
 #endif
 	} else {
+		/*
+		 * 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 = vn_rdwr_inchunks(UIO_WRITE, vp, base, len, offset,
 		    UIO_USERSPACE, IO_UNIT | IO_DIRECT, active_cred, file_cred,
 		    NULL, td);
+		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 = vn_rdwr_inchunks(UIO_WRITE, vp,
+			    __DECONST(void *, zero_region), 1, offset + len - 1,
+			    UIO_SYSSPACE, IO_UNIT | IO_DIRECT, active_cred,
+			    file_cred, NULL, td);
+		}
 	}
 	return (error);
 }
@@ -2309,7 +2331,16 @@ compress_core (gzFile file, char *inbuf,
 	while (len) {
 		if (inbuf != NULL) {
 			chunk_len = (len > CORE_BUF_SIZE) ? CORE_BUF_SIZE : len;
-			copyin(inbuf, dest_buf, chunk_len);
+
+			/*
+			 * We can get EFAULT error here.  In that case zero out
+			 * the current chunk of the segment.
+			 */
+			error = copyin(inbuf, dest_buf, chunk_len);
+			if (error != 0) {
+				bzero(dest_buf, chunk_len);
+				error = 0;
+			}
 			inbuf += chunk_len;
 		} else {
 			chunk_len = len;



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201701261638.v0QGcroW091532>