Skip to content
  1. Jan 14, 2018
  2. Jan 13, 2018
  3. Jan 10, 2018
  4. Jan 09, 2018
  5. Jan 08, 2018
  6. Jan 07, 2018
  7. Jan 06, 2018
  8. Jan 05, 2018
  9. Jan 04, 2018
  10. Dec 27, 2017
  11. Dec 17, 2017
  12. Dec 16, 2017
  13. Dec 15, 2017
  14. Dec 13, 2017
  15. Dec 12, 2017
    • Patrick Steuer's avatar
    • Richard Levitte's avatar
      Fix leak in ERR_get_state() when OPENSSL_init_crypto() isn't called yet · 2717f2b7
      Richard Levitte authored
      
      
      If OPENSSL_init_crypto() hasn't been called yet when ERR_get_state()
      is called, it need to be called early, so the base initialization is
      done.  On some platforms (those who support DSO functionality and
      don't define OPENSSL_USE_NODELETE), that includes a call of
      ERR_set_mark(), which calls this function again.
      Furthermore, we know that ossl_init_thread_start(), which is called
      later in ERR_get_state(), calls OPENSSL_init_crypto(0, NULL), except
      that's too late.
      Here's what happens without an early call of OPENSSL_init_crypto():
      
          => ERR_get_state():
               => CRYPTO_THREAD_get_local():
               <= NULL;
               # no state is found, so it gets allocated.
               => ossl_init_thread_start():
                    => OPENSSL_init_crypto():
                         # Here, base_inited is set to 1
                         # before ERR_set_mark() call
                         => ERR_set_mark():
                              => ERR_get_state():
                                   => CRYPTO_THREAD_get_local():
                                   <= NULL;
                                   # no state is found, so it gets allocated!!!!!
                                   => ossl_init_thread_start():
                                        => OPENSSL_init_crypto():
                                             # base_inited is 1,
                                             # so no more init to be done
                                        <= 1
                                   <=
                                   => CRYPTO_thread_set_local():
                                   <=
                              <=
                         <=
                    <= 1
               <=
               => CRYPTO_thread_set_local()      # previous value removed!
          <=
      
      Result: double allocation, and we have a leak.
      
      By calling the base OPENSSL_init_crypto() early, we get this instead:
      
          => ERR_get_state():
               => OPENSSL_init_crypto():
                    # Here, base_inited is set to 1
                    # before ERR_set_mark() call
                    => ERR_set_mark():
                         => ERR_get_state():
                              => OPENSSL_init_crypto():
                                   # base_inited is 1,
                                   # so no more init to be done
                              <= 1
                              => CRYPTO_THREAD_get_local():
                              <= NULL;
                              # no state is found, so it gets allocated
                              # let's assume we got 0xDEADBEEF
                              => ossl_init_thread_start():
                                   => OPENSSL_init_crypto():
                                        # base_inited is 1,
                                        # so no more init to be done
                                   <= 1
                              <= 1
                              => CRYPTO_thread_set_local():
                              <=
                         <=
                    <=
               <= 1
               => CRYPTO_THREAD_get_local():
               <= 0xDEADBEEF
          <= 0xDEADBEEF
      
      Result: no leak.
      
      Reviewed-by: default avatarRich Salz <rsalz@openssl.org>
      (Merged from https://github.com/openssl/openssl/pull/4913)
      
      (cherry picked from commit aef84bb4)
      2717f2b7
  16. Dec 11, 2017
  17. Dec 10, 2017
  18. Dec 08, 2017