summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authornobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2013-05-17 02:07:00 +0000
committernobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2013-05-17 02:07:00 +0000
commitf7624d984bb8c2d879606f1257b317331ad3d7d2 (patch)
tree45b4b217ab4c8e9fcd52e82fe4fa23558236498a
parentde03518cc7bb2f95df75fd56079b1b8e757436b8 (diff)
eval_intern.h: jmpbuf must be accessible
* eval_intern.h (TH_PUSH_TAG): ensure jmpbuf to be accessible before pushing tag to get rid of unaccessible tag by stack overflow. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@40791 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r--ChangeLog5
-rw-r--r--eval_intern.h11
2 files changed, 16 insertions, 0 deletions
diff --git a/ChangeLog b/ChangeLog
index 273ef3b28a..5611194e9f 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+Fri May 17 11:06:48 2013 Nobuyoshi Nakada <nobu@ruby-lang.org>
+
+ * eval_intern.h (TH_PUSH_TAG): ensure jmpbuf to be accessible before
+ pushing tag to get rid of unaccessible tag by stack overflow.
+
Thu May 16 17:15:32 2013 NARUSE, Yui <naruse@ruby-lang.org>
* vm_eval.c (rb_catch_obj): add volatile to tag to prevent crash
diff --git a/eval_intern.h b/eval_intern.h
index 190ef9195c..596d45ac82 100644
--- a/eval_intern.h
+++ b/eval_intern.h
@@ -91,9 +91,20 @@ extern int select_large_fdset(int, fd_set *, fd_set *, fd_set *, struct timeval
rb_fiber_start(); \
} while (0)
+/*
+ ensure tag to be accessible, `buf' is at the beginning.
+ the end is `prev' which is written in TH_PUSH_TAG().
+*/
+#if defined(__GNUC__) && __GNUC__ >= 4
+/* suppress -Wstrict-aliasing, and should be inlined */
+# define ENSURE_TAG_WRITABLE(tag) MEMZERO((tag).buf, int, 1)
+#else
+# define ENSURE_TAG_WRITABLE(tag) (*(volatile int *)(tag).buf = 0)
+#endif
#define TH_PUSH_TAG(th) do { \
rb_thread_t * const _th = (th); \
struct rb_vm_tag _tag; \
+ ENSURE_TAG_WRITABLE(_tag); \
_tag.tag = 0; \
_tag.prev = _th->tag; \
_th->tag = &_tag;