Skip to content

Commit

Permalink
Merge pull request #1088 from bugsnag/PLAT-5746/jni-exc-check
Browse files Browse the repository at this point in the history
Check internal JNI calls for pending exceptions and no-op
  • Loading branch information
fractalwrench committed Jan 25, 2021
2 parents 6b33480 + b5d3c58 commit 4119a5b
Show file tree
Hide file tree
Showing 7 changed files with 360 additions and 48 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
# Changelog

## TBD

* Check internal JNI calls for pending exceptions and no-op
[#1088](https://github.com/bugsnag/bugsnag-android/pull/1088)

## 5.5.1 (2021-01-21)

* Alter ANR SIGQUIT handler to stop interfering with Google's ANR reporting, and to avoid unsafe JNI calls from within a signal handler
Expand Down
1 change: 1 addition & 0 deletions bugsnag-plugin-android-ndk/src/main/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ add_library( # Specifies the name of the library.
jni/bugsnag_ndk.c
jni/bugsnag.c
jni/metadata.c
jni/safejni.c
jni/event.c
jni/handlers/signal_handler.c
jni/handlers/cpp_handler.cpp
Expand Down
90 changes: 74 additions & 16 deletions bugsnag-plugin-android-ndk/src/main/jni/bugsnag.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include "bugsnag_ndk.h"
#include "event.h"
#include "metadata.h"
#include "safejni.h"
#include "utils/stack_unwinder.h"
#include "utils/string.h"
#include <jni.h>
Expand Down Expand Up @@ -86,20 +87,45 @@ void bugsnag_notify_env(JNIEnv *env, char *name, char *message,
ssize_t frame_count =
bsg_unwind_stack(bsg_configured_unwind_style(), stacktrace, NULL, NULL);

// lookup com/bugsnag/android/NativeInterface
jclass interface_class =
(*env)->FindClass(env, "com/bugsnag/android/NativeInterface");
jmethodID notify_method = (*env)->GetStaticMethodID(
bsg_safe_find_class(env, "com/bugsnag/android/NativeInterface");
if (interface_class == NULL) {
return;
}

// lookup NativeInterface.notify()
jmethodID notify_method = bsg_safe_get_static_method_id(
env, interface_class, "notify",
"([B[BLcom/bugsnag/android/Severity;[Ljava/lang/StackTraceElement;)V");
jclass trace_class = (*env)->FindClass(env, "java/lang/StackTraceElement");
if (notify_method == NULL) {
return;
}

// lookup java/lang/StackTraceElement
jclass trace_class = bsg_safe_find_class(env, "java/lang/StackTraceElement");
if (trace_class == NULL) {
return;
}

// lookup com/bugsnag/android/Severity
jclass severity_class =
(*env)->FindClass(env, "com/bugsnag/android/Severity");
jmethodID trace_constructor = (*env)->GetMethodID(
bsg_safe_find_class(env, "com/bugsnag/android/Severity");
if (severity_class == NULL) {
return;
}

// lookup StackTraceElement constructor
jmethodID trace_constructor = bsg_safe_get_method_id(
env, trace_class, "<init>",
"(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;I)V");
if (trace_constructor == NULL) {
return;
}

jobjectArray trace = (*env)->NewObjectArray(
env, (jsize)frame_count,
(*env)->FindClass(env, "java/lang/StackTraceElement"), NULL);
bsg_safe_find_class(env, "java/lang/StackTraceElement"), NULL);

for (int i = 0; i < frame_count; i++) {
bugsnag_stackframe frame = stacktrace[i];
Expand Down Expand Up @@ -150,10 +176,19 @@ void bugsnag_notify_env(JNIEnv *env, char *name, char *message,
}

void bugsnag_set_binary_arch(JNIEnv *env) {
// lookup com/bugsnag/android/NativeInterface
jclass interface_class =
(*env)->FindClass(env, "com/bugsnag/android/NativeInterface");
jmethodID set_arch_method = (*env)->GetStaticMethodID(
bsg_safe_find_class(env, "com/bugsnag/android/NativeInterface");
if (interface_class == NULL) {
return;
}

// lookup NativeInterface.setBinaryArch()
jmethodID set_arch_method = bsg_safe_get_static_method_id(
env, interface_class, "setBinaryArch", "(Ljava/lang/String;)V");
if (set_arch_method == NULL) {
return;
}

jstring arch = (*env)->NewStringUTF(env, bsg_binary_arch());
(*env)->CallStaticVoidMethod(env, interface_class, set_arch_method, arch);
Expand All @@ -162,10 +197,19 @@ void bugsnag_set_binary_arch(JNIEnv *env) {
}

void bugsnag_set_user_env(JNIEnv *env, char *id, char *email, char *name) {
// lookup com/bugsnag/android/NativeInterface
jclass interface_class =
(*env)->FindClass(env, "com/bugsnag/android/NativeInterface");
jmethodID set_user_method =
(*env)->GetStaticMethodID(env, interface_class, "setUser", "([B[B[B)V");
bsg_safe_find_class(env, "com/bugsnag/android/NativeInterface");
if (interface_class == NULL) {
return;
}

// lookup NativeInterface.setUser()
jmethodID set_user_method = bsg_safe_get_static_method_id(
env, interface_class, "setUser", "([B[B[B)V");
if (set_user_method == NULL) {
return;
}

jbyteArray jid = bsg_byte_ary_from_string(env, id);
jbyteArray jemail = bsg_byte_ary_from_string(env, email);
Expand Down Expand Up @@ -208,13 +252,27 @@ jfieldID bsg_parse_jcrumb_type(JNIEnv *env, bugsnag_breadcrumb_type type,

void bugsnag_leave_breadcrumb_env(JNIEnv *env, char *message,
bugsnag_breadcrumb_type type) {
// lookup com/bugsnag/android/NativeInterface
jclass interface_class =
(*env)->FindClass(env, "com/bugsnag/android/NativeInterface");
jmethodID leave_breadcrumb_method =
(*env)->GetStaticMethodID(env, interface_class, "leaveBreadcrumb",
"([BLcom/bugsnag/android/BreadcrumbType;)V");
bsg_safe_find_class(env, "com/bugsnag/android/NativeInterface");
if (interface_class == NULL) {
return;
}

// lookup NativeInterface.leaveBreadcrumb()
jmethodID leave_breadcrumb_method = bsg_safe_get_static_method_id(
env, interface_class, "leaveBreadcrumb",
"([BLcom/bugsnag/android/BreadcrumbType;)V");
if (interface_class == NULL) {
return;
}

// lookup com/bugsnag/android/BreadcrumbType
jclass type_class =
(*env)->FindClass(env, "com/bugsnag/android/BreadcrumbType");
bsg_safe_find_class(env, "com/bugsnag/android/BreadcrumbType");
if (interface_class == NULL) {
return;
}

jobject jtype = (*env)->GetStaticObjectField(
env, type_class, bsg_parse_jcrumb_type(env, type, type_class));
Expand Down
16 changes: 14 additions & 2 deletions bugsnag-plugin-android-ndk/src/main/jni/bugsnag_ndk.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include "handlers/cpp_handler.h"
#include "handlers/signal_handler.h"
#include "metadata.h"
#include "safejni.h"
#include "utils/serializer.h"
#include "utils/string.h"

Expand Down Expand Up @@ -151,10 +152,21 @@ Java_com_bugsnag_android_ndk_NativeBridge_deliverReportAtPath(
if (event != NULL) {
char *payload = bsg_serialize_event_to_json_string(event);
if (payload != NULL) {

// lookup com/bugsnag/android/NativeInterface
jclass interface_class =
(*env)->FindClass(env, "com/bugsnag/android/NativeInterface");
jmethodID jdeliver_method = (*env)->GetStaticMethodID(
bsg_safe_find_class(env, "com/bugsnag/android/NativeInterface");
if (interface_class == NULL) {
return;
}

// lookup NativeInterface.deliverReport()
jmethodID jdeliver_method = bsg_safe_get_static_method_id(
env, interface_class, "deliverReport", "([B[BLjava/lang/String;)V");
if (jdeliver_method == NULL) {
return;
}

size_t payload_length = bsg_strlen(payload);
jbyteArray jpayload = (*env)->NewByteArray(env, payload_length);
(*env)->SetByteArrayRegion(env, jpayload, 0, payload_length,
Expand Down
Loading

0 comments on commit 4119a5b

Please sign in to comment.