aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSamuel Thibault <samuel.thibault@ens-lyon.org>2016-11-20 16:22:29 +0100
committerSamuel Thibault <samuel.thibault@ens-lyon.org>2016-11-20 16:22:29 +0100
commit62953f120bcdc976a3dfb96505066228464a78dd (patch)
treee7fa77309a920e7b87befcfd208d05254218a059
parent484a67719146e819ddad64fbda23b4b23afa3095 (diff)
downloadhurd-62953f120bcdc976a3dfb96505066228464a78dd.tar.gz
hurd-62953f120bcdc976a3dfb96505066228464a78dd.tar.bz2
hurd-62953f120bcdc976a3dfb96505066228464a78dd.zip
libpager, libstore: Fix crash on ENOSPC while writing data
We need to save blocked signals, otherwise longjmp will not unblock SIGSEGV/SIGBUS, and thus next exception will kill us. Also, we need to make sure that the preemptor is set at the right window in main memory before letting a handler see it. * libpager/pager-memcpy.c (do_memcpy): Call __sync_synchronize() between aligning the fault preemptor and actually accessing data. (fault): Use siglongjmp instead of longjmp. (pager_memcpy): Use sigsetjmp instead of setjmp. * libstore/memobj.c (copy, fault, memobj_memcpy): Likewise.
-rw-r--r--libpager/pager-memcpy.c5
-rw-r--r--libstore/memobj.c5
2 files changed, 6 insertions, 4 deletions
diff --git a/libpager/pager-memcpy.c b/libpager/pager-memcpy.c
index 7bdc248b..c7a420b2 100644
--- a/libpager/pager-memcpy.c
+++ b/libpager/pager-memcpy.c
@@ -121,6 +121,7 @@ pager_memcpy (struct pager *pager, memory_object_t memobj,
/* Realign the fault preemptor for the new mapping window. */
preemptor->first = window;
preemptor->last = window + window_size;
+ __sync_synchronize();
if (prot == VM_PROT_READ)
memcpy (other, (const void *) window + pageoff, copy_count);
@@ -176,7 +177,7 @@ pager_memcpy (struct pager *pager, memory_object_t memobj,
err = pager_get_error (pager, sigcode - window + offset);
n -= sigcode - window;
vm_deallocate (mach_task_self (), window, window_size);
- longjmp (buf, 1);
+ siglongjmp (buf, 1);
}
if (n == 0)
@@ -206,7 +207,7 @@ pager_memcpy (struct pager *pager, memory_object_t memobj,
window = 0;
window_size = 0;
- if (setjmp (buf) == 0)
+ if (sigsetjmp (buf) == 0)
hurd_catch_signal (sigmask (SIGSEGV) | sigmask (SIGBUS),
window, window + window_size,
&do_copy, (sighandler_t) &fault);
diff --git a/libstore/memobj.c b/libstore/memobj.c
index cc6c7cac..8bbc833d 100644
--- a/libstore/memobj.c
+++ b/libstore/memobj.c
@@ -83,6 +83,7 @@ memobj_memcpy (memory_object_t memobj,
/* Realign the fault preemptor for the new mapping window. */
preemptor->first = window;
preemptor->last = window + windowsize;
+ __sync_synchronize();
if (prot == VM_PROT_READ)
memcpy (other, (const void *) window + pageoff,
@@ -103,7 +104,7 @@ memobj_memcpy (memory_object_t memobj,
assert (scp->sc_error == EKERN_MEMORY_ERROR);
err = EIO;
to_copy -= sigcode - window;
- longjmp (buf, 1);
+ siglongjmp (buf, 1);
}
if (to_copy == 0)
@@ -111,7 +112,7 @@ memobj_memcpy (memory_object_t memobj,
ERR would not be initialized by the copy loop in this case. */
return 0;
- if (setjmp (buf) == 0)
+ if (sigsetjmp (buf) == 0)
hurd_catch_signal (sigmask (SIGSEGV) | sigmask (SIGBUS),
window, window + windowsize,
&copy, (sighandler_t) &fault);