Project

General

Profile

Actions

Bug #14024

closed

Segment fault on OpenSSL::Cipher#auth_data=

Added by darfux (Lee YX) over 6 years ago. Updated over 6 years ago.

Status:
Closed
Assignee:
-
Target version:
-
ruby -v:
ruby 2.4.2p198 (2017-09-14 revision 59899) [x86_64-linux]
[ruby-core:83337]

Description

The doc of auth_data= says that "If no associated data shall be used, this method must still be called with a value of '' . " http://ruby-doc.org/stdlib-2.4.2/libdoc/openssl/rdoc/OpenSSL/Cipher.html#method-i-auth_data-3D
But if I call this method with a non-empty string when there's no associated data, ruby just crash rather than raise an error.

require 'openssl'
cipher = OpenSSL::Cipher::AES.new(128, :CFB)
cipher.auth_data="123"
ssl.rb:3: [BUG] Segmentation fault at 0x00000000026365d8
ruby 2.4.2p198 (2017-09-14 revision 59899) [x86_64-linux]

-- Control frame information -----------------------------------------------
c:0003 p:---- s:0013 e:000012 CFUNC  :auth_data=
c:0002 p:0043 s:0008 E:002348 EVAL   ssl.rb:3 [FINISH]
c:0001 p:0000 s:0003 E:0021e0 (none) [FINISH]

-- Ruby level backtrace information ----------------------------------------
ssl.rb:3:in `<main>'
ssl.rb:3:in `auth_data='

I guess this is because the function ossl_cipher_set_auth_data doesn't verify the ctx and simply pass a NULL to openssl.

static VALUE
ossl_cipher_set_auth_data(VALUE self, VALUE data)
{
    EVP_CIPHER_CTX *ctx;
    unsigned char *in;
    long in_len, out_len;

    StringValue(data);

    in = (unsigned char *) RSTRING_PTR(data);
    in_len = RSTRING_LEN(data);

    GetCipher(self, ctx);

    // HERE out is NULL
    if (!ossl_cipher_update_long(ctx, NULL, &out_len, in, in_len))
        ossl_raise(eCipherError, "couldn't set additional authenticated data");

    return data;
}

While the function CRYPTO_cfb128_encrypt of openssl(openssl/crypto/modes/cfb128.c) also doesn't verify the value of out. Then the access of out(0x0) leads to a segment fault.

#1  0x00007ffff58b1c99 in CRYPTO_cfb128_encrypt (in=0x6e51c8 "123", out=0x0, len=3, key=0x9da8a0, ivec=0x953948 "", num=0x953978, enc=0, block=0x80b150) at cfb128.c:155
...
#5  0x00007ffff591d90c in EVP_CipherUpdate (ctx=ctx@entry=0x953920, out=out@entry=0x0, outl=outl@entry=0x7fffffffcbb4, in=in@entry=0x6e51c8 "123", inl=inl@entry=3) at evp_enc.c:273
#6  0x00007ffff5ecbf6a in ossl_cipher_update_long (out=<optimized out>, in_len=3, in=0x6e51c8 "123", out_len_ptr=<optimized out>, ctx=<optimized out>) at ossl_cipher.c:349
#7  ossl_cipher_set_auth_data (self=<optimized out>, data=7229880) at ossl_cipher.c:584

Files

crash.log (15.1 KB) crash.log darfux (Lee YX), 10/18/2017 01:46 PM
auth_data.rb (86 Bytes) auth_data.rb reproducible ruby script darfux (Lee YX), 10/18/2017 01:46 PM

Updated by rhenium (Kazuki Yamaguchi) over 6 years ago

  • Status changed from Open to Closed

Since CFB isn't an authenticated encryption mode, OpenSSL::Cipher#auth_data= must not be called. It is definitely a bug that calling it crashes, though.

https://github.com/ruby/openssl/commit/bb10767b0570d44f240632a7399c882764a48649

Actions

Also available in: Atom PDF

Like0
Like0