Skip to content

Commit

Permalink
Added finalizers to ssl.EVP_PKEY, removing remaining known memory leaks
Browse files Browse the repository at this point in the history
  • Loading branch information
jonasfj committed Sep 24, 2020
1 parent 8f9befd commit 6b6806f
Show file tree
Hide file tree
Showing 28 changed files with 529 additions and 357 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
# 0.2.1
* Added finalizers for `ssl.EVP_PKEY` and running tests under `valgrind` unable
to find any obvious memory leaks.
* Increased Flutter SDK constraint to `>=1.22.0-12.1.pre` (current beta).

# 0.2.0
* Added `ios` support.
* Added `<2.0.0` upper-bound on Flutter SDK constraint.
Expand Down
2 changes: 0 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,6 @@ Future<void> main() async {

**Missing:**
* Exceptions and errors thrown for invalid input is not tested yet.
* Finalizers not implemented yet, hence, memory leaks of keys is a known
issues in the native implementation.
* The native implementation executes on the main-thread, however, all expensive
APIs are asynchronous, so they can be offloaded in the future.

Expand Down
1 change: 1 addition & 0 deletions android/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ add_library(

# Source files
../src/webcrypto.c
../src/webcrypto_dart_dl.c
../src/symbols.generated.c
${dart_dl_sources}
${crypto_sources}
Expand Down
65 changes: 29 additions & 36 deletions example/pubspec.lock
Original file line number Diff line number Diff line change
Expand Up @@ -35,28 +35,28 @@ packages:
name: async
url: "https://pub.dartlang.org"
source: hosted
version: "2.4.2"
version: "2.5.0-nullsafety"
boolean_selector:
dependency: transitive
description:
name: boolean_selector
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.0"
version: "2.1.0-nullsafety"
characters:
dependency: transitive
description:
name: characters
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.0"
version: "1.1.0-nullsafety.2"
charcode:
dependency: transitive
description:
name: charcode
url: "https://pub.dartlang.org"
source: hosted
version: "1.1.3"
version: "1.2.0-nullsafety"
cli_util:
dependency: transitive
description:
Expand All @@ -70,14 +70,14 @@ packages:
name: clock
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.1"
version: "1.1.0-nullsafety"
collection:
dependency: transitive
description:
name: collection
url: "https://pub.dartlang.org"
source: hosted
version: "1.14.13"
version: "1.15.0-nullsafety.2"
convert:
dependency: "direct main"
description:
Expand Down Expand Up @@ -119,7 +119,7 @@ packages:
name: fake_async
url: "https://pub.dartlang.org"
source: hosted
version: "1.1.0"
version: "1.1.0-nullsafety"
ffi:
dependency: transitive
description:
Expand All @@ -133,7 +133,7 @@ packages:
name: file
url: "https://pub.dartlang.org"
source: hosted
version: "5.2.1"
version: "6.0.0-nullsafety.1"
flutter:
dependency: "direct main"
description: flutter
Expand Down Expand Up @@ -194,13 +194,6 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "3.1.4"
intl:
dependency: transitive
description:
name: intl
url: "https://pub.dartlang.org"
source: hosted
version: "0.16.1"
io:
dependency: transitive
description:
Expand All @@ -214,7 +207,7 @@ packages:
name: js
url: "https://pub.dartlang.org"
source: hosted
version: "0.6.2"
version: "0.6.3-nullsafety.1"
json_rpc_2:
dependency: transitive
description:
Expand All @@ -235,14 +228,14 @@ packages:
name: matcher
url: "https://pub.dartlang.org"
source: hosted
version: "0.12.8"
version: "0.12.10-nullsafety"
meta:
dependency: transitive
description:
name: meta
url: "https://pub.dartlang.org"
source: hosted
version: "1.1.8"
version: "1.3.0-nullsafety.2"
mime:
dependency: transitive
description:
Expand Down Expand Up @@ -284,35 +277,35 @@ packages:
name: path
url: "https://pub.dartlang.org"
source: hosted
version: "1.7.0"
version: "1.8.0-nullsafety"
pedantic:
dependency: transitive
description:
name: pedantic
url: "https://pub.dartlang.org"
source: hosted
version: "1.9.0"
version: "1.10.0-nullsafety.1"
platform:
dependency: transitive
description:
name: platform
url: "https://pub.dartlang.org"
source: hosted
version: "2.2.1"
version: "3.0.0-nullsafety.1"
pool:
dependency: transitive
description:
name: pool
url: "https://pub.dartlang.org"
source: hosted
version: "1.4.0"
version: "1.5.0-nullsafety.1"
process:
dependency: transitive
description:
name: process
url: "https://pub.dartlang.org"
source: hosted
version: "3.0.13"
version: "4.0.0-nullsafety.1"
pub_semver:
dependency: transitive
description:
Expand Down Expand Up @@ -359,42 +352,42 @@ packages:
name: source_map_stack_trace
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.0"
version: "2.1.0-nullsafety.2"
source_maps:
dependency: transitive
description:
name: source_maps
url: "https://pub.dartlang.org"
source: hosted
version: "0.10.9"
version: "0.10.10-nullsafety.1"
source_span:
dependency: transitive
description:
name: source_span
url: "https://pub.dartlang.org"
source: hosted
version: "1.7.0"
version: "1.8.0-nullsafety"
stack_trace:
dependency: transitive
description:
name: stack_trace
url: "https://pub.dartlang.org"
source: hosted
version: "1.9.5"
version: "1.10.0-nullsafety"
stream_channel:
dependency: transitive
description:
name: stream_channel
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.0"
version: "2.1.0-nullsafety"
string_scanner:
dependency: transitive
description:
name: string_scanner
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.5"
version: "1.1.0-nullsafety"
sync_http:
dependency: transitive
description:
Expand All @@ -408,42 +401,42 @@ packages:
name: term_glyph
url: "https://pub.dartlang.org"
source: hosted
version: "1.1.0"
version: "1.2.0-nullsafety"
test:
dependency: "direct dev"
description:
name: test
url: "https://pub.dartlang.org"
source: hosted
version: "1.15.2"
version: "1.16.0-nullsafety.4"
test_api:
dependency: transitive
description:
name: test_api
url: "https://pub.dartlang.org"
source: hosted
version: "0.2.17"
version: "0.2.19-nullsafety"
test_core:
dependency: transitive
description:
name: test_core
url: "https://pub.dartlang.org"
source: hosted
version: "0.3.10"
version: "0.3.12-nullsafety.4"
typed_data:
dependency: transitive
description:
name: typed_data
url: "https://pub.dartlang.org"
source: hosted
version: "1.2.0"
version: "1.3.0-nullsafety.2"
vector_math:
dependency: transitive
description:
name: vector_math
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.8"
version: "2.1.0-nullsafety.2"
vm_service:
dependency: transitive
description:
Expand Down Expand Up @@ -501,5 +494,5 @@ packages:
source: hosted
version: "2.2.1"
sdks:
dart: ">=2.9.0-14.0.dev <3.0.0"
dart: ">=2.10.0-4.0.dev <2.10.0"
flutter: ">=1.17.0 <2.0.0"
1 change: 1 addition & 0 deletions ios/Classes/include_webcrypto.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,4 @@

#include "../../src/symbols.generated.c"
#include "../../src/webcrypto.c"
#include "../../src/webcrypto_dart_dl.c"
17 changes: 12 additions & 5 deletions lib/src/boringssl/evp.dart
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,16 @@ final EVP_PKEY_new = resolve(Sym.EVP_PKEY_new)
/// ```c
/// void EVP_PKEY_free(EVP_PKEY *pkey);
/// ```
final EVP_PKEY_free = resolve(Sym.EVP_PKEY_free)
.lookupFunc<Void Function(Pointer<EVP_PKEY>)>()
.asFunction<void Function(Pointer<EVP_PKEY>)>();
final EVP_PKEY_free_ =
resolve(Sym.EVP_PKEY_free).lookupFunc<Void Function(Pointer<EVP_PKEY>)>();

/// EVP_PKEY_free frees all data referenced by pkey and then frees pkey itself.
///
/// ```c
/// void EVP_PKEY_free(EVP_PKEY *pkey);
/// ```
final EVP_PKEY_free =
EVP_PKEY_free_.asFunction<void Function(Pointer<EVP_PKEY>)>();

/// EVP_PKEY_id returns the type of pkey, which is one of the EVP_PKEY_* values.
///
Expand Down Expand Up @@ -86,15 +93,15 @@ final EVP_PKEY_set1_RSA = resolve(Sym.EVP_PKEY_set1_RSA)
.lookupFunc<Int32 Function(Pointer<EVP_PKEY>, Pointer<RSA>)>()
.asFunction<int Function(Pointer<EVP_PKEY>, Pointer<RSA>)>();

final EVP_PKEY_get0_RSA = resolve(Sym.EVP_PKEY_get0_RSA)
final EVP_PKEY_get1_RSA = resolve(Sym.EVP_PKEY_get1_RSA)
.lookupFunc<Pointer<RSA> Function(Pointer<EVP_PKEY>)>()
.asFunction<Pointer<RSA> Function(Pointer<EVP_PKEY>)>();

final EVP_PKEY_set1_EC_KEY = resolve(Sym.EVP_PKEY_set1_EC_KEY)
.lookupFunc<Int32 Function(Pointer<EVP_PKEY>, Pointer<EC_KEY>)>()
.asFunction<int Function(Pointer<EVP_PKEY>, Pointer<EC_KEY>)>();

final EVP_PKEY_get0_EC_KEY = resolve(Sym.EVP_PKEY_get0_EC_KEY)
final EVP_PKEY_get1_EC_KEY = resolve(Sym.EVP_PKEY_get1_EC_KEY)
.lookupFunc<Pointer<EC_KEY> Function(Pointer<EVP_PKEY>)>()
.asFunction<Pointer<EC_KEY> Function(Pointer<EVP_PKEY>)>();

Expand Down
30 changes: 1 addition & 29 deletions lib/src/boringssl/lookup/lookup_symbol_dart.dart
Original file line number Diff line number Diff line change
Expand Up @@ -23,37 +23,9 @@ final Pointer<Void> Function(Sym) lookupSymbol = () {
return lookup;
}

try {
// If there is no binary webcrypto library to be found we check if the
// current executable already contains BoringSSL symbols. This happens to be
// the case for the Dart Linux release at-least.
final library = DynamicLibrary.executable();

// CRYPTO_library_init initializes the crypto library. It must be called if
// the library is built with BORINGSSL_NO_STATIC_INITIALIZER. Otherwise, it
// does nothing and a static initializer is used instead. It is safe to call
// this function multiple times and concurrently from multiple threads.
//
// On some ARM configurations, this function may require filesystem access
// and should be called before entering a sandbox.
//
// OPENSSL_EXPORT void CRYPTO_library_init(void);
// ignore: non_constant_identifier_names
final CRYPTO_library_init = library
.lookup<NativeFunction<Void Function()>>('CRYPTO_library_init')
.asFunction<void Function()>();

// Always initalize BoringSSL to be on the safe side.
CRYPTO_library_init();

return (Sym s) => library.lookup<Void>(s.name);
} on ArgumentError {
// pass, we'll throw UnsupportedError a few lines further down.
}

throw UnsupportedError(
'package:webcrypto cannot be used from Dart or `pub run test` '
'unless `pub run webcrypto:setup` has been run for the current '
'unless `flutter pub run webcrypto:setup` has been run for the current '
'root project.',
);
}();
7 changes: 6 additions & 1 deletion lib/src/boringssl/lookup/lookup_symbol_flutter.dart
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,12 @@ final Pointer<Void> Function(Sym) lookupSymbol = () {
.asFunction<Pointer<Void> Function(int)>();

// Return a function from Sym to lookup using `webcrypto_lookup_symbol`
return (Sym s) => webcrypto_lookup_symbol(s.index);
final lookup = (Sym s) => webcrypto_lookup_symbol(s.index);

// Initialize the dynamic linking with Dart.
initialize_dart_dl(lookup);

return lookup;
} on ArgumentError {
final lookup = lookupLibraryInDotDartTool();
if (lookup != null) {
Expand Down
Loading

0 comments on commit 6b6806f

Please sign in to comment.