diff options
author | Simon Marlow <marlowsd@gmail.com> | 2015-10-30 19:53:44 +0100 |
---|---|---|
committer | Ben Gamari <ben@smart-cactus.org> | 2015-10-30 19:53:45 +0100 |
commit | 2624298a0d81e348b879c521b9fae3f389ebab08 (patch) | |
tree | b62a0cab0864abdd246e59c3571508c892980e52 /rts | |
parent | 314395e00be10e6343840c215a4779aeec2542df (diff) | |
download | haskell-2624298a0d81e348b879c521b9fae3f389ebab08.tar.gz |
Fix segfault due to reading non-existent memory
It was possible to read non-existent memory, if we try to read the
srt_offset field of an info table when there is no SRT, and the info
table is right at the start of the text section.
This actually happened to me, I'm not sure why it never happened
before.
Test Plan: validate
Reviewers: rwbarton, ezyang, austin, bgamari
Reviewed By: austin, bgamari
Subscribers: thomie
Differential Revision: https://phabricator.haskell.org/D1401
Diffstat (limited to 'rts')
-rw-r--r-- | rts/sm/Scav.c | 16 |
1 files changed, 14 insertions, 2 deletions
diff --git a/rts/sm/Scav.c b/rts/sm/Scav.c index c441a3d3cc..a28d84226f 100644 --- a/rts/sm/Scav.c +++ b/rts/sm/Scav.c @@ -359,22 +359,34 @@ STATIC_INLINE GNUC_ATTR_HOT void scavenge_thunk_srt(const StgInfoTable *info) { StgThunkInfoTable *thunk_info; + nat bitmap; if (!major_gc) return; thunk_info = itbl_to_thunk_itbl(info); - scavenge_srt((StgClosure **)GET_SRT(thunk_info), thunk_info->i.srt_bitmap); + bitmap = thunk_info->i.srt_bitmap; + if (bitmap) { + // don't read srt_offset if bitmap==0, because it doesn't exist + // and so the memory might not be readable. + scavenge_srt((StgClosure **)GET_SRT(thunk_info), bitmap); + } } STATIC_INLINE GNUC_ATTR_HOT void scavenge_fun_srt(const StgInfoTable *info) { StgFunInfoTable *fun_info; + nat bitmap; if (!major_gc) return; fun_info = itbl_to_fun_itbl(info); - scavenge_srt((StgClosure **)GET_FUN_SRT(fun_info), fun_info->i.srt_bitmap); + bitmap = fun_info->i.srt_bitmap; + if (bitmap) { + // don't read srt_offset if bitmap==0, because it doesn't exist + // and so the memory might not be readable. + scavenge_srt((StgClosure **)GET_FUN_SRT(fun_info), bitmap); + } } /* ----------------------------------------------------------------------------- |