Skip to content

Commit 3d14eb7

Browse files
committed
android: Use OpenSSL instead of curl.
Linking against libcurl.so is not guaranteed to work on newer Android versions. That's why we're using Crashpad's SSL code instead.
1 parent b0b4c8e commit 3d14eb7

File tree

10 files changed

+184
-12
lines changed

10 files changed

+184
-12
lines changed

.github/workflows/main.yml

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -162,18 +162,25 @@ jobs:
162162
with:
163163
submodules: recursive
164164

165+
- name: Set env armeabi-v7a
166+
if: ${{ matrix.abi == 'armeabi-v7a' }}
167+
run: echo "SSL_MODE=NONE" >> $GITHUB_ENV
168+
169+
- name: Set env others
170+
if: ${{ matrix.abi != 'armeabi-v7a' }}
171+
run: echo "SSL_MODE=OPENSSL" >> $GITHUB_ENV
172+
165173
- name: Install NDK (optional)
166174
# available on GitHub Actions host (as of 7/24/22) listed below
167175
if: ${{ matrix.ndk }} != '21.4.7075529' && ${{ matrix.ndk }} != '23.2.8568313' && ${{ matrix.ndk }} != '24.0.8215888'
168176
run: |
169177
echo "y" | sudo $ANDROID_HOME/tools/bin/sdkmanager --install "ndk;${{ matrix.ndk }}" --sdk_root=${ANDROID_SDK_ROOT} >/dev/null 2>&1
170178
#ls -lsa $ANDROID_HOME/ndk/${{ matrix.ndk }}/platforms
171179
172-
173180
- name: CMake
174181
run: |
175182
mkdir cbuild
176-
cmake -S . -B cbuild/ -DCMAKE_TOOLCHAIN_FILE=$ANDROID_HOME/ndk/${{ matrix.ndk }}/build/cmake/android.toolchain.cmake -DANDROID_ABI=${{ matrix.abi }} -DANDROID_PLATFORM=android-${{ matrix.apiLevel }} -DANDROID_NATIVE_API_LEVEL=${{ matrix.apiLevel }} -DANDROID_TOOLCHAIN=clang -DBUILD_EXAMPLES=TRUE
183+
cmake -S . -B cbuild/ -DCMAKE_TOOLCHAIN_FILE=$ANDROID_HOME/ndk/${{ matrix.ndk }}/build/cmake/android.toolchain.cmake -DANDROID_ABI=${{ matrix.abi }} -DANDROID_PLATFORM=android-${{ matrix.apiLevel }} -DANDROID_NATIVE_API_LEVEL=${{ matrix.apiLevel }} -DANDROID_TOOLCHAIN=clang -DANDROID_SSL_MODE=${{ env.SSL_MODE }} -DBUILD_EXAMPLES=TRUE
177184
cmake --build cbuild/
178185
179186
- name: Crashpad distribution ZIP

CMakeLists.txt

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
cmake_minimum_required(VERSION 3.12)
22
project(backtrace_crashpad LANGUAGES C CXX)
3+
cmake_policy(SET CMP0077 NEW)
34

45
if (UNIX AND NOT APPLE)
56
set(LINUX TRUE)
@@ -42,7 +43,10 @@ target_compile_definitions(backtrace_common INTERFACE
4243
CRASHPAD_LSS_SOURCE_EMBEDDED)
4344

4445
if (ANDROID)
45-
add_subdirectory(third_party/openssl-android-binary)
46+
option(ANDROID_SSL_MODE "Android SSL mode" "OPENSSL")
47+
if (ANDROID_SSL_MODE STREQUAL "OPENSSL")
48+
add_subdirectory(third_party/openssl-android-binary)
49+
endif()
4650
elseif (APPLE)
4751
# do nothing
4852
elseif (LINUX)

client/crash_report_database.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,11 @@ class CrashReportDatabase {
176176
return attachment_map_;
177177
}
178178

179+
#if BUILDFLAG(IS_ANDROID)
180+
//! \brief Returns the database that this report belongs to.
181+
CrashReportDatabase* GetDatabase() const { return database_; }
182+
#endif
183+
179184
private:
180185
friend class CrashReportDatabase;
181186
friend class CrashReportDatabaseGeneric;

client/crashpad_client_linux.cc

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,10 @@
5050
#include "util/posix/signals.h"
5151
#include "util/posix/spawn_subprocess.h"
5252

53+
#if defined(CRASHPAD_USE_BORINGSSL) && BUILDFLAG(IS_ANDROID)
54+
#include "util/backtrace/android_cert_store.h"
55+
#endif
56+
5357
namespace crashpad {
5458

5559
namespace {
@@ -449,6 +453,10 @@ bool CrashpadClient::StartHandler(
449453
const std::vector<base::FilePath>& attachments) {
450454
DCHECK(!asynchronous_start);
451455

456+
#if defined(CRASHPAD_USE_BORINGSSL) && BUILDFLAG(IS_ANDROID)
457+
backtrace::android_cert_store::create(database);
458+
#endif
459+
452460
ScopedFileHandle client_sock, handler_sock;
453461
if (!UnixCredentialSocket::CreateCredentialSocketpair(&client_sock,
454462
&handler_sock)) {
@@ -727,6 +735,10 @@ bool CrashpadClient::StartHandlerAtCrash(
727735
std::vector<std::string> argv = BuildHandlerArgvStrings(
728736
handler, database, metrics_dir, url, annotations, arguments, attachments);
729737

738+
#if defined(CRASHPAD_USE_BORINGSSL) && BUILDFLAG(IS_ANDROID)
739+
backtrace::android_cert_store::create(database);
740+
#endif
741+
730742
if (crash_loop_detection_) {
731743
namespace clc = backtrace::crash_loop_detection;
732744
bool ok = clc::CrashLoopDetectionAppend(database, run_uuid_);

handler/crash_report_upload_thread.cc

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -341,6 +341,13 @@ CrashReportUploadThread::UploadResult CrashReportUploadThread::UploadReport(
341341
// TODO(mark): The timeout should be configurable by the client.
342342
http_transport->SetTimeout(internal::kUploadReportTimeoutSeconds);
343343

344+
#if defined(CRASHPAD_USE_BORINGSSL)
345+
#if BUILDFLAG(IS_ANDROID)
346+
http_transport->SetRootCACertificatePath(
347+
report->GetDatabase()->DatabasePath());
348+
#endif // BUILDFLAG(IS_ANDROID)
349+
#endif // defined(CRASHPAD_USE_BORINGSSL)
350+
344351
std::string url = url_;
345352
if (options_.identify_client_via_url) {
346353
// Add parameters to the URL which identify the client to the server.

util/CMakeLists.txt

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -230,7 +230,6 @@ if (LINUX)
230230
./misc/capture_context_linux.S
231231
./misc/paths_linux.cc
232232
./misc/time_linux.cc
233-
./net/http_transport_libcurl.cc
234233
./net/http_transport_socket.cc
235234
./posix/process_info_linux.cc
236235
./posix/scoped_mmap.cc
@@ -310,6 +309,13 @@ if (WIN32)
310309
endif ()
311310
endif (WIN32)
312311

312+
if (ANDROID)
313+
list(APPEND CRASHPAD_UTIL_LIBRARY_FILES
314+
./backtrace/android_cert_store.cc
315+
./backtrace/android_cert_store.h
316+
./backtrace/certs_pem.h
317+
)
318+
endif (ANDROID)
313319

314320
add_library(util OBJECT ${CRASHPAD_UTIL_LIBRARY_FILES})
315321
target_compile_features(util PUBLIC cxx_std_17)
@@ -362,7 +368,10 @@ if (APPLE)
362368
endif (APPLE)
363369

364370
if (ANDROID)
365-
target_link_libraries(util PUBLIC openssl-android-binary)
371+
if (ANDROID_SSL_MODE STREQUAL "OPENSSL")
372+
target_link_libraries(util PUBLIC openssl-android-binary)
373+
elseif(ANDROID_SSL_MODE STREQUAL "NONE")
374+
endif ()
366375
endif (ANDROID)
367376

368377
if (UNIX)
@@ -377,16 +386,22 @@ target_include_directories(util PUBLIC ..)
377386
target_link_libraries(util PUBLIC mini_chromium ZLIB::ZLIB backtrace_common)
378387

379388
if (LINUX AND NOT ANDROID)
380-
if (CURL_FOUND)
381-
target_link_libraries(util PUBLIC curl)
382-
endif (CURL_FOUND)
383-
384389
if (OPENSSL_FOUND)
385390
target_compile_definitions(util PUBLIC CRASHPAD_USE_BORINGSSL)
386391
target_link_libraries(util PUBLIC OpenSSL::SSL OpenSSL::Crypto)
387392
endif (OPENSSL_FOUND)
388393
endif (LINUX AND NOT ANDROID)
389394

395+
if (ANDROID)
396+
if (ANDROID_SSL_MODE STREQUAL "OPENSSL")
397+
target_link_libraries(util PUBLIC openssl-android-binary)
398+
target_compile_definitions(util PUBLIC CRASHPAD_USE_BORINGSSL)
399+
elseif(ANDROID_SSL_MODE STREQUAL "NONE")
400+
else()
401+
message(FATAL_ERROR "Unknown value for ANDROID_SSL_MODE: ${ANDROID_SSL_MODE}")
402+
endif ()
403+
endif (ANDROID)
404+
390405
if (${CMAKE_CXX_COMPILER_ID} STREQUAL "GNU")
391406
target_compile_options(util PUBLIC -Wno-multichar)
392407
endif ()
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
#include "android_cert_store.h"
2+
3+
#if !BUILDFLAG(IS_ANDROID)
4+
#error "This file is only for Android"
5+
#endif // !BUILDFLAG(IS_ANDROID)
6+
7+
#include <fcntl.h>
8+
#include <unistd.h>
9+
#include <sys/stat.h>
10+
11+
namespace crashpad {
12+
namespace backtrace {
13+
namespace android_cert_store {
14+
15+
#include "certs_pem.h"
16+
17+
namespace {
18+
19+
bool file_exists(const base::FilePath& path) {
20+
return access(path.value().c_str(), F_OK) != -1;
21+
}
22+
23+
size_t file_size(const base::FilePath& path) {
24+
struct stat st;
25+
if (stat(path.value().c_str(), &st) == -1)
26+
return 0;
27+
return st.st_size;
28+
}
29+
30+
} // anonymous namespace
31+
32+
create_result create(const base::FilePath& database) {
33+
34+
auto certs_file = database.Append("/backtrace-cacert.pem");
35+
36+
if (file_exists(certs_file) && file_size(certs_file) == certs_pem_len)
37+
return create_result::already_exists;
38+
39+
int file_handle = open(certs_file.value().c_str(),
40+
O_CREAT | O_TRUNC | O_WRONLY, 0644);
41+
42+
if (file_handle == -1)
43+
return create_result::failure;
44+
45+
auto written = write(file_handle, certs_pem, certs_pem_len);
46+
if (written != certs_pem_len){
47+
close(file_handle);
48+
return create_result::failure;
49+
}
50+
51+
close(file_handle);
52+
return create_result::success;
53+
}
54+
55+
} // android_cert_store
56+
} // backtrace
57+
} // crashpad
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
// Copyright 2023 Sauce Labs. All rights reserved.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
#pragma once
16+
17+
#include "base/files/file_path.h"
18+
#include "util/misc/uuid.h"
19+
20+
namespace crashpad {
21+
namespace backtrace {
22+
namespace android_cert_store {
23+
24+
enum class create_result {
25+
success,
26+
failure,
27+
already_exists,
28+
};
29+
30+
create_result create(const base::FilePath& database);
31+
32+
} // android_cert_store
33+
} // backtrace
34+
} // crashpad

util/net/http_transport_socket.cc

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,9 @@
3636

3737
#if defined(CRASHPAD_USE_BORINGSSL)
3838
#include <openssl/ssl.h>
39+
#if BUILDFLAG(IS_ANDROID)
40+
#include "util/backtrace/android_cert_store.h"
41+
#endif
3942
#endif
4043

4144
namespace crashpad {
@@ -121,14 +124,41 @@ class SSLStream : public Stream {
121124
SSL_CTX_set_verify(ctx_.get(), SSL_VERIFY_PEER, nullptr);
122125
SSL_CTX_set_verify_depth(ctx_.get(), 5);
123126

127+
#if BUILDFLAG(IS_ANDROID)
128+
{
129+
namespace cs = crashpad::backtrace::android_cert_store;
130+
auto result = cs::create(root_cert_path);
131+
if (result == cs::create_result::failure) {
132+
LOG(ERROR) << "Failed to create AndroidCertStore";
133+
return false;
134+
}
135+
}
136+
#endif
137+
124138
if (!root_cert_path.empty()) {
139+
#if BUILDFLAG(IS_ANDROID)
140+
auto path = root_cert_path.value() + "/backtrace-cacert.pem";
141+
if (SSL_CTX_load_verify_locations(
142+
ctx_.get(), path.c_str(), nullptr) <= 0) {
143+
LOG(ERROR) << "SSL_CTX_load_verify_locations";
144+
return false;
145+
}
146+
#else
125147
if (SSL_CTX_load_verify_locations(
126148
ctx_.get(), root_cert_path.value().c_str(), nullptr) <= 0) {
127149
LOG(ERROR) << "SSL_CTX_load_verify_locations";
128150
return false;
129151
}
152+
#endif
130153
} else {
131-
#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
154+
#if BUILDFLAG(IS_ANDROID)
155+
auto path = root_cert_path.value() + "/backtrace-cacert.pem";
156+
if (SSL_CTX_load_verify_locations(
157+
ctx_.get(), path.c_str(), nullptr) <= 0) {
158+
LOG(ERROR) << "SSL_CTX_load_verify_locations";
159+
return false;
160+
}
161+
#elif BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
132162
if (SSL_CTX_load_verify_locations(
133163
ctx_.get(), nullptr, "/etc/ssl/certs") <= 0) {
134164
LOG(ERROR) << "SSL_CTX_load_verify_locations";
@@ -165,7 +195,8 @@ class SSLStream : public Stream {
165195
return false;
166196
}
167197

168-
if (SSL_connect(ssl_.get()) <= 0) {
198+
int connect = SSL_connect(ssl_.get());
199+
if (connect <= 0) {
169200
LOG(ERROR) << "SSL_connect";
170201
return false;
171202
}

0 commit comments

Comments
 (0)