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

Avoid overflows in JNI allocations #639

Merged
merged 4 commits into from
May 15, 2020
Merged

Commits on May 14, 2020

  1. Avoid overflows in JNI allocations

    Themis Core API works with "size_t" for buffer size inputs and outputs,
    that is uint32_t on 32-bit systems or uint64_t on 64-bit ones. In most
    cases Themis data structures use uint32_t for data length fields,
    allowing input data to be up to 4 GB long, theoretically.
    
    On the other hand, JVM uses "int" type for its array indices, that is
    int32_t everywhere, regardless of the host system. Note that it is a
    *signed* integer, meaning that native JVM byte[] arrays cannot fit more
    than 2 GB of data, inclusive. There are hacks to overcome this limit,
    but with byte[] API -- as in Themis -- you are limited to 2 GB.
    
    JNI type "jsize" reflects this limitation, it is defined to be "jint"
    which is typically defined as "signed int", assuming 32-bit "int" types
    on most modern platforms. Thanks to C being very safe language, sizes
    bigger than 2^31-1 silently overflow into negative space and then it's
    up to JNI to handle this situation. Desktop Java systems typically throw
    a NegativeArraySizeException when trying to allocate an array with
    negative size, but Android systems typically kill the process due to
    an assertion failure.
    
    In order to have predictable behavior in this case, check all sizes
    before trying to allocate an array of that size, and exit with an error
    if the allocation would overflow. This way instead of crashing we will
    throw an appropriate Themis subsystem exception.
    
    Note that in some cases the array sizes do not depend on user input, but
    we still check just in case the Core library does something silly. In
    other cases the output can get that big due to input being sufficiently
    big -- slightly smaller than 2 GB, but enough for Themis data overhead
    to push that over the 2 GB limit. However, in most cases this situation
    can be triggered by corrupted input where the data length fields contain
    values inconsistent with actual input size.
    ilammy committed May 14, 2020
    Configuration menu
    Copy the full SHA
    de18eb4 View commit details
    Browse the repository at this point in the history
  2. Restore broken tests

    With the JNI changes we can unignore a couple of tests for Token Protect
    mode which actually discovered the overflows. Now Secure Cell should
    correctly handle corrupted token values.
    ilammy committed May 14, 2020
    Configuration menu
    Copy the full SHA
    6bb48a6 View commit details
    Browse the repository at this point in the history
  3. Note the fix for crashes in changelog

    Since it affects mostly Android, put the note into that section.
    ilammy committed May 14, 2020
    Configuration menu
    Copy the full SHA
    cc4df4f View commit details
    Browse the repository at this point in the history
  4. Allow OutOfMemoryError in "swapTokenAndData" test

    Here we use encrypted data as token which is essentially random.
    Depending on how broken it turns out, Themis might genuinely believe
    that this is a valid authentication token and proceed with allocation.
    You get an exception if the allocation is bigger than JVM heap, which
    it very well might be on emulated devices. Allow OutOfMemoryError to
    happen in this test.
    ilammy committed May 14, 2020
    Configuration menu
    Copy the full SHA
    582810e View commit details
    Browse the repository at this point in the history