Skip to content

Commit

Permalink
Fix possible deadlock in bsg_ksmachfreeMemory
Browse files Browse the repository at this point in the history
  • Loading branch information
nickdowell committed Feb 25, 2021
1 parent 1a74851 commit e374fd8
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 20 deletions.
47 changes: 29 additions & 18 deletions Bugsnag/KSCrash/Source/KSCrash/Recording/Tools/BSG_KSMach.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,9 @@
#include <mach-o/arch.h>
#include <mach/mach_time.h>
#include <sys/sysctl.h>
#if defined(__IPHONE_13_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_13_0
#import <os/proc.h>

#if __has_include(<os/proc.h>)
#include <os/proc.h>
#endif

// Avoiding static functions due to linker issues.
Expand All @@ -60,26 +61,33 @@ static pthread_t bsg_g_topThread;
#pragma mark - General Information -
// ============================================================================

uint64_t bsg_ksmachfreeMemory(void) {
size_t mem = 0;

#if BSG_PLATFORM_IOS && defined(__IPHONE_13_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_13_0
if (__builtin_available(iOS 13.0, *)) {
mem = os_proc_available_memory();
}
#endif

#if BSG_PLATFORM_TVOS && defined(__TVOS_13_0) && __TV_OS_VERSION_MAX_ALLOWED >= __TVOS_13_0
if (__builtin_available(tvOS 13.0, *)) {
mem = os_proc_available_memory();
/**
* A pointer to `os_proc_available_memory` if it is available and usable.
*
* We cannot use the `__builtin_available` check at runtime because its
* implementation uses malloc() which is not async-signal-safe and can result in
* a deadlock if called from a crash handler or while threads are suspended.
*/
static size_t (* get_available_memory)(void);

static void bsg_ksmachfreeMemory_init(void) {
#if __has_include(<os/proc.h>)
if (__builtin_available(iOS 13.0, tvOS 13.0, watchOS 6.0, *)) {
// Only use `os_proc_available_memory` if it appears to be working.
// 0 is returned if the calling process is not an app or is running
// on a Simulator, and may also erroneously be returned by some early
// implementations like iOS 13.0.
if (os_proc_available_memory()) {
get_available_memory = os_proc_available_memory;
}
}
#endif
}

// Note: Some broken versions of iOS always return 0.
if(mem != 0) {
return mem;
uint64_t bsg_ksmachfreeMemory(void) {
if (get_available_memory) {
return get_available_memory();
}

vm_statistics_data_t vmStats;
vm_size_t pageSize;
if (bsg_ksmachi_VMStats(&vmStats, &pageSize)) {
Expand Down Expand Up @@ -227,6 +235,9 @@ void bsg_ksmach_init(void) {
}
vm_deallocate(thisTask, (vm_address_t)threads,
sizeof(thread_t) * numThreads);

bsg_ksmachfreeMemory_init();

initialized = true;
}
}
Expand Down
4 changes: 2 additions & 2 deletions Bugsnag/KSCrash/Source/KSCrash/Recording/Tools/BSG_KSMach.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,8 @@ extern "C" {
// ============================================================================

/** Initializes KSMach.
* Some functions (currently only bsg_ksmachpthreadFromMachThread) require
* initialization before use.
* Some functions (currently only bsg_ksmachpthreadFromMachThread and
* bsg_ksmachfreeMemory) require initialization before use.
*/
void bsg_ksmach_init(void);

Expand Down
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
Changelog
=========

## TBD

### Bug fixes

* Fix a possible deadlock when writing crash reports for unhandled errors.
[#1013](https://github.com/bugsnag/bugsnag-cocoa/pull/1013)

## 6.6.4 (2021-02-24)

### Bug fixes
Expand Down

0 comments on commit e374fd8

Please sign in to comment.