summaryrefslogtreecommitdiff
path: root/libstore
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 /libstore
parent484a67719146e819ddad64fbda23b4b23afa3095 (diff)
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.
Diffstat (limited to 'libstore')
-rw-r--r--libstore/memobj.c5
1 files changed, 3 insertions, 2 deletions
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);