From 4c117aa282628102558ca054006c03997ec1c13e Mon Sep 17 00:00:00 2001 From: mtak- Date: Thu, 26 Jul 2018 16:27:26 -0700 Subject: [PATCH] iOS: Fix the `longjmp`/`setjmp` ffi (#613) * iOS: Fix the `longjmp`/`setjmp` ffi. `jmp_buf` was the wrong size (too small) causing crashes on application launch, make longjmp return Never * remove extra parentheses around JBLEN, and add a changelog entry about the JmpBuf fix --- CHANGELOG.md | 1 + src/platform/ios/ffi.rs | 14 ++++++++++++-- src/platform/ios/mod.rs | 5 +++-- 3 files changed, 16 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 57e12e40..57237ac8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ - **Breaking:** On iOS, `UIView` is now the default root view. `WindowBuilderExt::with_root_view_class` can be used to set the root view objective-c class to `GLKView` (OpenGLES) or `MTKView` (Metal/MoltenVK). - On iOS, the `UIApplication` is not started until `Window::new` is called. - Fixed thread unsafety with cursor hiding on macOS. +- On iOS, fixed the size of the `JmpBuf` type used for `setjmp`/`longjmp` calls. Previously this was a buffer overflow on most architectures. # Version 0.16.2 (2018-07-07) diff --git a/src/platform/ios/ffi.rs b/src/platform/ios/ffi.rs index 3e69d128..6fd1a7ca 100644 --- a/src/platform/ios/ffi.rs +++ b/src/platform/ios/ffi.rs @@ -64,10 +64,20 @@ extern { extern { pub fn setjmp(env: *mut c_void) -> c_int; - pub fn longjmp(env: *mut c_void, val: c_int); + pub fn longjmp(env: *mut c_void, val: c_int) -> !; } -pub type JmpBuf = [c_int; 27]; +// values taken from "setjmp.h" header in xcode iPhoneOS/iPhoneSimulator SDK +#[cfg(any(target_arch = "x86_64"))] +pub const JBLEN: usize = (9 * 2) + 3 + 16; +#[cfg(any(target_arch = "x86"))] +pub const JBLEN: usize = 18; +#[cfg(target_arch = "arm")] +pub const JBLEN: usize = 10 + 16 + 2; +#[cfg(target_arch = "aarch64")] +pub const JBLEN: usize = (14 + 8 + 2) * 2; + +pub type JmpBuf = [c_int; JBLEN]; pub trait NSString: Sized { unsafe fn alloc(_: Self) -> id { diff --git a/src/platform/ios/mod.rs b/src/platform/ios/mod.rs index b18bf226..1c8e7c85 100644 --- a/src/platform/ios/mod.rs +++ b/src/platform/ios/mod.rs @@ -92,6 +92,7 @@ use self::ffi::{ CGPoint, CGRect, id, + JBLEN, JmpBuf, kCFRunLoopDefaultMode, kCFRunLoopRunHandledSource, @@ -209,7 +210,7 @@ impl EventsLoop { pub fn new() -> EventsLoop { unsafe { if !msg_send![class!(NSThread), isMainThread] { - panic!("`Window` can only be created on the main thread on iOS"); + panic!("`EventsLoop` can only be created on the main thread on iOS"); } } EventsLoop { events_queue: Default::default() } @@ -315,7 +316,7 @@ impl Window { ) -> Result { unsafe { debug_assert!(mem::size_of_val(&JMPBUF) == mem::size_of::>()); - assert!(mem::replace(&mut JMPBUF, Some(Box::new([0; 27]))).is_none(), "Only one `Window` is supported on iOS"); + assert!(mem::replace(&mut JMPBUF, Some(Box::new([0; JBLEN]))).is_none(), "Only one `Window` is supported on iOS"); } unsafe {