Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F137049063
D9233.id24232.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
2 KB
Referenced Files
None
Subscribers
None
D9233.id24232.diff
View Options
Index: sys/kern/imgact_elf.c
===================================================================
--- sys/kern/imgact_elf.c
+++ sys/kern/imgact_elf.c
@@ -1160,7 +1160,7 @@
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_dumpable_segment(struct thread *, segment_callback, void *);
static int __elfN(corehdr)(struct coredump_params *, int, void *, size_t,
@@ -1202,7 +1202,14 @@
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 @@
#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 @@
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);
}
/*
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sat, Nov 22, 1:24 AM (20 h, 26 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
25753314
Default Alt Text
D9233.id24232.diff (2 KB)
Attached To
Mode
D9233: don't abort writing of a core dump after EFAULT
Attached
Detach File
Event Timeline
Log In to Comment