Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Check internal JNI calls for pending exceptions and no-op #1088

Merged
merged 1 commit into from
Jan 25, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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