firebase / firebase/firebase-cpp-sdk

Use after free triggered on application exit

Đang mở
#110 2 bình luận 0 reaction 0 người được giao Xem trên GitHub
api: auth type: bug
Ngôn ngữ chính
C++
Star
326
Fork
137
Merge trung bình
3 ngày 9 giờ
Pull request đã merge (30 ngày)
5

Mô tả

### Please fill in the following fields:
Pre-built SDK from the [website](https://firebase.google.com/download/cpp) or open-source from this repo: pre-built
Firebase C++ SDK version: 6.15.0
Firebase plugins in use (Auth, Database, etc.): Auth
Additional SDKs you are using (Facebook, AdMob, etc.): none
Platform you are using the C++ SDK on (Mac, Windows, or Linux): mac
Platform you are targeting (iOS, Android, and/or desktop): all

### Please describe the issue here:
When the c++ runtime is cleaning on exit, the cleanup call at https://github.com/firebase/firebase-cpp-sdk/blob/d464bcfd26eec7735d7a8374b0cd325e77fc0280/auth/src/auth.cc#L160 causes a use after free memory access:
```
=================================================================
==6558==ERROR: AddressSanitizer: heap-use-after-free on address 0x604000004450 at pc 0x000106e57cc1 bp 0x7ffee8f89d30 sp 0x7ffee8f89d28
READ of size 8 at 0x604000004450 thread T0
#0 0x106e57cc0 in void std::__1::__tree_remove*>(std::__1::__tree_node_base*, std::__1::__tree_node_base*) __tree:354
#1 0x1076f2655 in firebase::auth::Auth::DeleteInternal() (flib-ui:x86_64+0x100a7d655)
#2 0x1076f27a8 in firebase::auth::Auth::~Auth() (flib-ui:x86_64+0x100a7d7a8)
#3 0x1071e574a in std::__1::default_delete::operator()(firebase::auth::Auth*) const memory:2338
#4 0x1071e56ce in std::__1::unique_ptr >::reset(firebase::auth::Auth*) memory:2593
#5 0x1071e5608 in std::__1::unique_ptr >::~unique_ptr() memory:2547
#6 0x1071e5284 in std::__1::unique_ptr >::~unique_ptr() memory:2547
#7 0x1071e5190 in my_ns::backend_firebase::~backend_firebase() backend_firebase.hpp:33
```
This is more or less the way I create and use the auth object:
```c++
class backend {
std::unique_ptr app;
std::unique_ptr auth;
static std::shared_ptr instance;

public:
std::shared_ptr get_instance() {
if (instance == nullptr) {
instance = std::make_shared();
instance.app = std::unique_ptr(App::Create(...));
firebase::InitResult result{};
auto *auth = auth::Auth::GetAuth(instance.app.get(), &result);
assert(result == firebase::kInitResultSuccess);
instance.auth = std::unique_ptr(auth);
}
return instance;
}
}
```

So I lazy load the auth to avoid loading firebase for part of my application that doesn't use it. On exit the c++ runtime will cleanup globals in the reverse order that they were created. It happens that in my case the runtime first instanciates the backend `std::shared_ptr` with `nullptr` as value, then the firebase `g_auths` global. Then I call `get_instance` and the shared ptr is now holding a backend instance. Then I exit the application. The c++ runtime then first destructs the `g_auths` and then destructs my backend instance which in turn destructs the auth instance which tries to remove it self from the already destructed `g_auths` map.

I'm now working around this by setting the backend instance static global to `nullptr` on exit but it kind of ruin the point of using smart pointers. Maybe the `g_auth` map could be part of some global context that I could also lazy load in a smart pointer. Anyway, not a big problem at all but I wanted to let you know of my use case and the problem with the current api. Also maybe you have a better solution for me: if so, I'm all ears ;) Thank you!

### Please answer the following, if applicable:
Have you been able to reproduce this issue with just the [Firebase C++ quickstarts](https://github.com/firebase/quickstart-cpp) ? n/a

What's the issue repro rate? (eg 100%, 1/5 etc) 100%

Hướng dẫn đóng góp

Mở hướng dẫn đóng góp

Đánh giá

Issue này chưa được đánh giá.

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.