To avoid continued attempted use of a bad .eh_frame[_hdr] sections, remove
them on demand when the first sign of corruption is detected.

Based on Josh Poimboeuf's, Steven Rostedt's, and my unwind user sframe
implementation.

Signed-off-by: Jens Remus <[email protected]>
---
 kernel/unwind/eh_frame.c | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/kernel/unwind/eh_frame.c b/kernel/unwind/eh_frame.c
index 21f40805b417..327849ea4a69 100644
--- a/kernel/unwind/eh_frame.c
+++ b/kernel/unwind/eh_frame.c
@@ -1202,6 +1202,15 @@ int eh_frame_find(unsigned long ip, struct 
unwind_user_frame *frame)
        if (!ret)
                ret = __find_frame_row(sec, &fde, ip, frame);
 
+       /*
+        * Unregister .eh_frame[_hdr] in case of an error,
+        * e.g. EINVAL (corrupted) or EFAULT (inaccessible).
+        * Keep if ENOENT (not found) or EOPNOTSUPP (unsupported CFI).
+        */
+       if (ret && (ret != -ENOENT && ret != -EOPNOTSUPP))
+               if (eh_frame_remove_section(sec->eh_frame_hdr_start))
+                       dbg("eh_frame_remove_section() failed\n");
+
        return ret;
 }
 
-- 
2.53.0


Reply via email to