Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 4346f3c5 authored by Philip P. Moltmann's avatar Philip P. Moltmann
Browse files

Set buffer before UsbRequest is queued

Otherwise a second thread might dequeue() it in between
native_queue_direct and mBuffer = buffer. If that happens the dequeue
operation does mBuffer.isDirect which triggers a NPE.

Fixes: 30914003
Change-Id: I3ca3b72db8f53a14be1c5f0e37f8924eba44b9bc
parent 0bef88f3
Loading
Loading
Loading
Loading
+8 −4
Original line number Diff line number Diff line
@@ -150,6 +150,11 @@ public class UsbRequest {
     */
    public boolean queue(ByteBuffer buffer, int length) {
        boolean out = (mEndpoint.getDirection() == UsbConstants.USB_DIR_OUT);

        // save our buffer for when the request has completed
        mBuffer = buffer;
        mLength = length;

        boolean result;
        if (buffer.isDirect()) {
            result = native_queue_direct(buffer, length, out);
@@ -158,10 +163,9 @@ public class UsbRequest {
        } else {
            throw new IllegalArgumentException("buffer is not direct and has no array");
        }
        if (result) {
            // save our buffer for when the request has completed
            mBuffer = buffer;
            mLength = length;
        if (!result) {
            mBuffer = null;
            mLength = 0;
        }
        return result;
    }
+10 −10
Original line number Diff line number Diff line
@@ -47,7 +47,7 @@ android_hardware_UsbRequest_init(JNIEnv *env, jobject thiz, jobject java_device,
    struct usb_device* device = get_device_from_object(env, java_device);
    if (!device) {
        ALOGE("device null in native_init");
        return false;
        return JNI_FALSE;
    }

    // construct an endpoint descriptor from the Java object fields
@@ -83,13 +83,13 @@ android_hardware_UsbRequest_queue_array(JNIEnv *env, jobject thiz,
    struct usb_request* request = get_request_from_object(env, thiz);
    if (!request) {
        ALOGE("request is closed in native_queue");
        return false;
        return JNI_FALSE;
    }

    if (buffer && length) {
        request->buffer = malloc(length);
        if (!request->buffer)
            return false;
            return JNI_FALSE;
        memset(request->buffer, 0, length);
        if (out) {
            // copy data from Java buffer to native buffer
@@ -110,9 +110,9 @@ android_hardware_UsbRequest_queue_array(JNIEnv *env, jobject thiz,
            request->buffer = NULL;
        }
        env->DeleteGlobalRef((jobject)request->client_data);
        return false;
        return JNI_FALSE;
    }
    return true;
    return JNI_TRUE;
}

static jint
@@ -141,13 +141,13 @@ android_hardware_UsbRequest_queue_direct(JNIEnv *env, jobject thiz,
    struct usb_request* request = get_request_from_object(env, thiz);
    if (!request) {
        ALOGE("request is closed in native_queue");
        return false;
        return JNI_FALSE;
    }

    if (buffer && length) {
        request->buffer = env->GetDirectBufferAddress(buffer);
        if (!request->buffer)
            return false;
            return JNI_FALSE;
    } else {
        request->buffer = NULL;
    }
@@ -161,9 +161,9 @@ android_hardware_UsbRequest_queue_direct(JNIEnv *env, jobject thiz,
    if (usb_request_queue(request)) {
        request->buffer = NULL;
        env->DeleteGlobalRef((jobject)request->client_data);
        return false;
        return JNI_FALSE;
    }
    return true;
    return JNI_TRUE;
}

static jint
@@ -185,7 +185,7 @@ android_hardware_UsbRequest_cancel(JNIEnv *env, jobject thiz)
    struct usb_request* request = get_request_from_object(env, thiz);
    if (!request) {
        ALOGE("request is closed in native_cancel");
        return false;
        return JNI_FALSE;
    }
    return (usb_request_cancel(request) == 0);
}