summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorSebastian Holmin <sebastian.holmin@mullvad.net>2025-07-10 09:32:20 +0200
committerSebastian Holmin <sebastian.holmin@mullvad.net>2025-07-10 09:32:20 +0200
commit2cdb3c216a5ff3e0a12224666339f4444d2e18b8 (patch)
tree9c5e7e9e839a58ae5eecf56e656b0353ff1565a3
parent4d90ff4fd81b0692945df0c67e0e8074716c14f3 (diff)
parent7259eabc670ef78a2ab6029cd99f6708ac6f2754 (diff)
downloadmullvadvpn-2cdb3c216a5ff3e0a12224666339f4444d2e18b8.tar.xz
mullvadvpn-2cdb3c216a5ff3e0a12224666339f4444d2e18b8.zip
Merge branch 'fix-rust-warnings-prepare-2024-edition'
-rw-r--r--android/translations-converter/src/android/string_value.rs6
-rw-r--r--mullvad-ios/src/api_client/access_method_settings.rs4
-rw-r--r--mullvad-ios/src/api_client/account.rs15
-rw-r--r--mullvad-ios/src/api_client/address_cache_provider.rs2
-rw-r--r--mullvad-ios/src/api_client/api.rs15
-rw-r--r--mullvad-ios/src/api_client/cancellation.rs4
-rw-r--r--mullvad-ios/src/api_client/completion.rs2
-rw-r--r--mullvad-ios/src/api_client/device.rs31
-rw-r--r--mullvad-ios/src/api_client/helpers.rs30
-rw-r--r--mullvad-ios/src/api_client/mod.rs8
-rw-r--r--mullvad-ios/src/api_client/problem_report.rs15
-rw-r--r--mullvad-ios/src/api_client/response.rs26
-rw-r--r--mullvad-ios/src/api_client/retry_strategy.rs8
-rw-r--r--mullvad-ios/src/api_client/shadowsocks_loader.rs2
-rw-r--r--mullvad-ios/src/api_client/storekit.rs21
-rw-r--r--mullvad-ios/src/ephemeral_peer_proxy/mod.rs2
-rw-r--r--mullvad-ios/src/lib.rs1
-rw-r--r--mullvad-ios/src/shadowsocks_proxy/ffi.rs15
-rw-r--r--mullvad-ios/src/tunnel_obfuscator_proxy/ffi.rs31
-rw-r--r--mullvad-nsis/src/lib.rs54
-rw-r--r--mullvad-types/src/auth_failed.rs20
21 files changed, 178 insertions, 134 deletions
diff --git a/android/translations-converter/src/android/string_value.rs b/android/translations-converter/src/android/string_value.rs
index 31c753e3cf..1880d5f757 100644
--- a/android/translations-converter/src/android/string_value.rs
+++ b/android/translations-converter/src/android/string_value.rs
@@ -155,8 +155,8 @@ mod tests {
fn newline_collapsing() {
let input = StringValue::from_unescaped(
"This is
- a multi-line string
- that should be
+ a multi-line string
+ that should be
collapsed into a single line",
None,
);
@@ -217,7 +217,7 @@ mod tests {
}
let serialized_input = r#"<root>A multi-line string value
- with \"quotes\" and
+ with \"quotes\" and
parameters %2$s %d %1$d</root>"#;
let deserialized: Wrapper =
diff --git a/mullvad-ios/src/api_client/access_method_settings.rs b/mullvad-ios/src/api_client/access_method_settings.rs
index 2870047e24..40f0acd714 100644
--- a/mullvad-ios/src/api_client/access_method_settings.rs
+++ b/mullvad-ios/src/api_client/access_method_settings.rs
@@ -143,7 +143,7 @@ pub unsafe extern "C" fn init_access_method_settings_wrapper(
)
};
- let custom = access_methods_from_raw_array(custom_methods_raw, custom_method_count);
+ let custom = unsafe { access_methods_from_raw_array(custom_methods_raw, custom_method_count) };
let settings = Settings::new(direct, mullvad_bridges, encrypted_dns_proxy, custom);
let context = SwiftAccessMethodSettingsContext { settings };
SwiftAccessMethodSettingsWrapper::new(context)
@@ -177,7 +177,7 @@ impl SwiftAccessMethodSettingsWrapper {
}
pub unsafe fn into_rust_context(self) -> Box<SwiftAccessMethodSettingsContext> {
- Box::from_raw(self.0)
+ unsafe { Box::from_raw(self.0) }
}
}
diff --git a/mullvad-ios/src/api_client/account.rs b/mullvad-ios/src/api_client/account.rs
index 227e81ba30..eb755f3191 100644
--- a/mullvad-ios/src/api_client/account.rs
+++ b/mullvad-ios/src/api_client/account.rs
@@ -30,14 +30,15 @@ use super::{
/// `mullvad_api_retry_strategy_never`, `mullvad_api_retry_strategy_constant` or `mullvad_api_retry_strategy_exponential`
///
/// This function is not safe to call multiple times with the same `CompletionCookie`.
-#[no_mangle]
+#[unsafe(no_mangle)]
pub unsafe extern "C" fn mullvad_ios_get_account(
api_context: SwiftApiContext,
completion_cookie: *mut libc::c_void,
retry_strategy: SwiftRetryStrategy,
account_number: *const c_char,
) -> SwiftCancelHandle {
- let completion_handler = SwiftCompletionHandler::new(CompletionCookie::new(completion_cookie));
+ let completion_handler =
+ SwiftCompletionHandler::new(unsafe { CompletionCookie::new(completion_cookie) });
let Ok(tokio_handle) = crate::mullvad_ios_runtime() else {
completion_handler.finish(SwiftMullvadApiResponse::no_tokio_runtime());
@@ -86,13 +87,14 @@ pub unsafe extern "C" fn mullvad_ios_get_account(
/// `mullvad_api_retry_strategy_never`, `mullvad_api_retry_strategy_constant` or `mullvad_api_retry_strategy_exponential`
///
/// This function is not safe to call multiple times with the same `CompletionCookie`.
-#[no_mangle]
+#[unsafe(no_mangle)]
pub unsafe extern "C" fn mullvad_ios_create_account(
api_context: SwiftApiContext,
completion_cookie: *mut libc::c_void,
retry_strategy: SwiftRetryStrategy,
) -> SwiftCancelHandle {
- let completion_handler = SwiftCompletionHandler::new(CompletionCookie::new(completion_cookie));
+ let completion_handler =
+ SwiftCompletionHandler::new(unsafe { CompletionCookie::new(completion_cookie) });
let Ok(tokio_handle) = crate::mullvad_ios_runtime() else {
completion_handler.finish(SwiftMullvadApiResponse::no_tokio_runtime());
@@ -132,14 +134,15 @@ pub unsafe extern "C" fn mullvad_ios_create_account(
/// `mullvad_api_retry_strategy_never`, `mullvad_api_retry_strategy_constant` or `mullvad_api_retry_strategy_exponential`
///
/// This function is not safe to call multiple times with the same `CompletionCookie`.
-#[no_mangle]
+#[unsafe(no_mangle)]
pub unsafe extern "C" fn mullvad_ios_delete_account(
api_context: SwiftApiContext,
completion_cookie: *mut libc::c_void,
retry_strategy: SwiftRetryStrategy,
account_number: *const c_char,
) -> SwiftCancelHandle {
- let completion_handler = SwiftCompletionHandler::new(CompletionCookie::new(completion_cookie));
+ let completion_handler =
+ SwiftCompletionHandler::new(unsafe { CompletionCookie::new(completion_cookie) });
let Ok(tokio_handle) = crate::mullvad_ios_runtime() else {
completion_handler.finish(SwiftMullvadApiResponse::no_tokio_runtime());
diff --git a/mullvad-ios/src/api_client/address_cache_provider.rs b/mullvad-ios/src/api_client/address_cache_provider.rs
index 9d5f656c62..0458ae2fe3 100644
--- a/mullvad-ios/src/api_client/address_cache_provider.rs
+++ b/mullvad-ios/src/api_client/address_cache_provider.rs
@@ -3,7 +3,7 @@ use std::{ffi::c_void, net::SocketAddr};
use super::get_string;
-extern "C" {
+unsafe extern "C" {
/// Return the latest available endpoint, or a default one if none are cached
///
/// # SAFETY
diff --git a/mullvad-ios/src/api_client/api.rs b/mullvad-ios/src/api_client/api.rs
index 14c36bc595..20fe2ba248 100644
--- a/mullvad-ios/src/api_client/api.rs
+++ b/mullvad-ios/src/api_client/api.rs
@@ -30,13 +30,14 @@ use super::{
/// `mullvad_api_retry_strategy_never`, `mullvad_api_retry_strategy_constant` or `mullvad_api_retry_strategy_exponential`
///
/// This function is not safe to call multiple times with the same `CompletionCookie`.
-#[no_mangle]
+#[unsafe(no_mangle)]
pub unsafe extern "C" fn mullvad_ios_get_addresses(
api_context: SwiftApiContext,
completion_cookie: *mut libc::c_void,
retry_strategy: SwiftRetryStrategy,
) -> SwiftCancelHandle {
- let completion_handler = SwiftCompletionHandler::new(CompletionCookie::new(completion_cookie));
+ let completion_handler =
+ SwiftCompletionHandler::new(unsafe { CompletionCookie::new(completion_cookie) });
let Ok(tokio_handle) = crate::mullvad_ios_runtime() else {
completion_handler.finish(SwiftMullvadApiResponse::no_tokio_runtime());
@@ -74,14 +75,15 @@ pub unsafe extern "C" fn mullvad_ios_get_addresses(
/// `mullvad_api_retry_strategy_never`, `mullvad_api_retry_strategy_constant` or `mullvad_api_retry_strategy_exponential`
///
/// This function is not safe to call multiple times with the same `CompletionCookie`.
-#[no_mangle]
+#[unsafe(no_mangle)]
pub unsafe extern "C" fn mullvad_ios_api_addrs_available(
api_context: SwiftApiContext,
completion_cookie: *mut libc::c_void,
retry_strategy: SwiftRetryStrategy,
access_method_setting: *const c_void,
) -> SwiftCancelHandle {
- let completion_handler = SwiftCompletionHandler::new(CompletionCookie::new(completion_cookie));
+ let completion_handler =
+ SwiftCompletionHandler::new(unsafe { CompletionCookie::new(completion_cookie) });
let Ok(tokio_handle) = crate::mullvad_ios_runtime() else {
completion_handler.finish(SwiftMullvadApiResponse::no_tokio_runtime());
@@ -148,14 +150,15 @@ pub unsafe extern "C" fn mullvad_ios_api_addrs_available(
/// `mullvad_api_retry_strategy_never`, `mullvad_api_retry_strategy_constant` or `mullvad_api_retry_strategy_exponential`
///
/// This function is not safe to call multiple times with the same `CompletionCookie`.
-#[no_mangle]
+#[unsafe(no_mangle)]
pub unsafe extern "C" fn mullvad_ios_get_relays(
api_context: SwiftApiContext,
completion_cookie: *mut libc::c_void,
retry_strategy: SwiftRetryStrategy,
etag: *const c_char,
) -> SwiftCancelHandle {
- let completion_handler = SwiftCompletionHandler::new(CompletionCookie::new(completion_cookie));
+ let completion_handler =
+ SwiftCompletionHandler::new(unsafe { CompletionCookie::new(completion_cookie) });
let Ok(tokio_handle) = crate::mullvad_ios_runtime() else {
completion_handler.finish(SwiftMullvadApiResponse::no_tokio_runtime());
diff --git a/mullvad-ios/src/api_client/cancellation.rs b/mullvad-ios/src/api_client/cancellation.rs
index 4c86919e2d..eea57b6a0a 100644
--- a/mullvad-ios/src/api_client/cancellation.rs
+++ b/mullvad-ios/src/api_client/cancellation.rs
@@ -62,7 +62,7 @@ impl RequestCancelHandle {
/// # Safety
///
/// `handle_ptr` must be pointing to a valid instance of `SwiftCancelHandle`.
-#[no_mangle]
+#[unsafe(no_mangle)]
extern "C" fn mullvad_api_cancel_task(handle_ptr: &mut SwiftCancelHandle) {
if handle_ptr.ptr.is_null() {
return;
@@ -79,7 +79,7 @@ extern "C" fn mullvad_api_cancel_task(handle_ptr: &mut SwiftCancelHandle) {
/// # Safety
///
/// `handle_ptr` must be pointing to a valid instance of `SwiftCancelHandle`.
-#[no_mangle]
+#[unsafe(no_mangle)]
extern "C" fn mullvad_api_cancel_task_drop(handle_ptr: &mut SwiftCancelHandle) {
if handle_ptr.ptr.is_null() {
return;
diff --git a/mullvad-ios/src/api_client/completion.rs b/mullvad-ios/src/api_client/completion.rs
index 7689ad0f6a..aa1a00bb07 100644
--- a/mullvad-ios/src/api_client/completion.rs
+++ b/mullvad-ios/src/api_client/completion.rs
@@ -2,7 +2,7 @@ use std::sync::{Arc, Mutex};
use super::response::SwiftMullvadApiResponse;
-extern "C" {
+unsafe extern "C" {
/// Maps to `mullvadApiCompletionFinish` on Swift side to facilitate callback based completion flow when doing
/// network calls through Mullvad API on Rust side.
///
diff --git a/mullvad-ios/src/api_client/device.rs b/mullvad-ios/src/api_client/device.rs
index 6a6ee1b07e..e0eb44fa9f 100644
--- a/mullvad-ios/src/api_client/device.rs
+++ b/mullvad-ios/src/api_client/device.rs
@@ -42,7 +42,8 @@ pub unsafe extern "C" fn mullvad_ios_get_device(
account_number: *const c_char,
identifier: *const c_char,
) -> SwiftCancelHandle {
- let completion_handler = SwiftCompletionHandler::new(CompletionCookie::new(completion_cookie));
+ let completion_handler =
+ SwiftCompletionHandler::new(unsafe { CompletionCookie::new(completion_cookie) });
let Ok(tokio_handle) = crate::mullvad_ios_runtime() else {
completion_handler.finish(SwiftMullvadApiResponse::no_tokio_runtime());
@@ -52,8 +53,8 @@ pub unsafe extern "C" fn mullvad_ios_get_device(
let api_context = api_context.rust_context();
// Safety: The caller must guarantee that `retry_strategy` is not null and has not been freed
let retry_strategy = unsafe { retry_strategy.into_rust() };
- let account_number = get_string(account_number);
- let identifier = get_string(identifier);
+ let account_number = unsafe { get_string(account_number) };
+ let identifier = unsafe { get_string(identifier) };
let completion = completion_handler.clone();
let task = tokio_handle.spawn(async move {
@@ -100,7 +101,8 @@ pub unsafe extern "C" fn mullvad_ios_get_devices(
retry_strategy: SwiftRetryStrategy,
account_number: *const c_char,
) -> SwiftCancelHandle {
- let completion_handler = SwiftCompletionHandler::new(CompletionCookie::new(completion_cookie));
+ let completion_handler =
+ SwiftCompletionHandler::new(unsafe { CompletionCookie::new(completion_cookie) });
let Ok(tokio_handle) = crate::mullvad_ios_runtime() else {
completion_handler.finish(SwiftMullvadApiResponse::no_tokio_runtime());
@@ -110,7 +112,7 @@ pub unsafe extern "C" fn mullvad_ios_get_devices(
let api_context = api_context.rust_context();
// Safety: The caller must guarantee that `retry_strategy` is not null and has not been freed
let retry_strategy = unsafe { retry_strategy.into_rust() };
- let account_number = get_string(account_number);
+ let account_number = unsafe { get_string(account_number) };
let completion = completion_handler.clone();
let task = tokio_handle.spawn(async move {
@@ -158,7 +160,8 @@ pub unsafe extern "C" fn mullvad_ios_create_device(
account_number: *const c_char,
public_key: *const u8,
) -> SwiftCancelHandle {
- let completion_handler = SwiftCompletionHandler::new(CompletionCookie::new(completion_cookie));
+ let completion_handler =
+ SwiftCompletionHandler::new(unsafe { CompletionCookie::new(completion_cookie) });
let Ok(tokio_handle) = crate::mullvad_ios_runtime() else {
completion_handler.finish(SwiftMullvadApiResponse::no_tokio_runtime());
@@ -168,7 +171,7 @@ pub unsafe extern "C" fn mullvad_ios_create_device(
let api_context = api_context.rust_context();
// Safety: The caller must guarantee that `retry_strategy` is not null and has not been freed
let retry_strategy = unsafe { retry_strategy.into_rust() };
- let account_number = get_string(account_number);
+ let account_number = unsafe { get_string(account_number) };
// Safety: `public_key` pointer must be a valid pointer to 32 unsigned bytes.
let pub_key: [u8; 32] = unsafe { ptr::read(public_key as *const [u8; 32]) };
@@ -218,7 +221,8 @@ pub unsafe extern "C" fn mullvad_ios_delete_device(
account_number: *const c_char,
identifier: *const c_char,
) -> SwiftCancelHandle {
- let completion_handler = SwiftCompletionHandler::new(CompletionCookie::new(completion_cookie));
+ let completion_handler =
+ SwiftCompletionHandler::new(unsafe { CompletionCookie::new(completion_cookie) });
let Ok(tokio_handle) = crate::mullvad_ios_runtime() else {
completion_handler.finish(SwiftMullvadApiResponse::no_tokio_runtime());
@@ -228,8 +232,8 @@ pub unsafe extern "C" fn mullvad_ios_delete_device(
let api_context = api_context.rust_context();
// Safety: The caller must guarantee that `retry_strategy` is not null and has not been freed
let retry_strategy = unsafe { retry_strategy.into_rust() };
- let account_number = get_string(account_number);
- let identifier = get_string(identifier);
+ let account_number = unsafe { get_string(account_number) };
+ let identifier = unsafe { get_string(identifier) };
let completion = completion_handler.clone();
let task = tokio_handle.spawn(async move {
@@ -279,7 +283,8 @@ pub unsafe extern "C" fn mullvad_ios_rotate_device_key(
identifier: *const c_char,
public_key: *const u8,
) -> SwiftCancelHandle {
- let completion_handler = SwiftCompletionHandler::new(CompletionCookie::new(completion_cookie));
+ let completion_handler =
+ SwiftCompletionHandler::new(unsafe { CompletionCookie::new(completion_cookie) });
let Ok(tokio_handle) = crate::mullvad_ios_runtime() else {
completion_handler.finish(SwiftMullvadApiResponse::no_tokio_runtime());
@@ -289,8 +294,8 @@ pub unsafe extern "C" fn mullvad_ios_rotate_device_key(
let api_context = api_context.rust_context();
// Safety: The caller must guarantee that `retry_strategy` is not null and has not been freed
let retry_strategy = unsafe { retry_strategy.into_rust() };
- let account_number = get_string(account_number);
- let identifier = get_string(identifier);
+ let account_number = unsafe { get_string(account_number) };
+ let identifier = unsafe { get_string(identifier) };
// Safety: `public_key` pointer must be a valid pointer to 32 unsigned bytes.
let pub_key: [u8; 32] = unsafe { ptr::read(public_key as *const [u8; 32]) };
diff --git a/mullvad-ios/src/api_client/helpers.rs b/mullvad-ios/src/api_client/helpers.rs
index 556b679d71..e363c5862c 100644
--- a/mullvad-ios/src/api_client/helpers.rs
+++ b/mullvad-ios/src/api_client/helpers.rs
@@ -46,14 +46,15 @@ pub unsafe extern "C" fn new_shadowsocks_access_method_setting(
c_password: *const c_char,
c_cipher: *const c_char,
) -> *const c_void {
- let endpoint: SocketAddr = if let Some(ip_address) = parse_ip_addr(address, address_len) {
- SocketAddr::new(ip_address, port)
- } else {
- return std::ptr::null();
- };
+ let endpoint: SocketAddr =
+ if let Some(ip_address) = unsafe { parse_ip_addr(address, address_len) } {
+ SocketAddr::new(ip_address, port)
+ } else {
+ return std::ptr::null();
+ };
- let password = get_string(c_password);
- let cipher = get_string(c_cipher);
+ let password = unsafe { get_string(c_password) };
+ let cipher = unsafe { get_string(c_cipher) };
let shadowsocks_configuration = Shadowsocks {
endpoint,
@@ -79,18 +80,19 @@ pub unsafe extern "C" fn new_socks5_access_method_setting(
c_username: *const c_char,
c_password: *const c_char,
) -> *const c_void {
- let endpoint: SocketAddr = if let Some(ip_address) = parse_ip_addr(address, address_len) {
- SocketAddr::new(ip_address, port)
- } else {
- return std::ptr::null();
- };
+ let endpoint: SocketAddr =
+ if let Some(ip_address) = unsafe { parse_ip_addr(address, address_len) } {
+ SocketAddr::new(ip_address, port)
+ } else {
+ return std::ptr::null();
+ };
let auth = {
if c_username.is_null() || c_password.is_null() {
None
} else {
- let username = get_string(c_username);
- let password = get_string(c_password);
+ let username = unsafe { get_string(c_username) };
+ let password = unsafe { get_string(c_password) };
SocksAuth::new(username, password).ok()
}
};
diff --git a/mullvad-ios/src/api_client/mod.rs b/mullvad-ios/src/api_client/mod.rs
index 1c45fb3397..82535d0e40 100644
--- a/mullvad-ios/src/api_client/mod.rs
+++ b/mullvad-ios/src/api_client/mod.rs
@@ -91,7 +91,7 @@ pub unsafe extern "C" fn mullvad_api_update_access_methods(
api_context: SwiftApiContext,
settings_wrapper: SwiftAccessMethodSettingsWrapper,
) {
- let access_methods = settings_wrapper.into_rust_context().settings;
+ let access_methods = unsafe { settings_wrapper.into_rust_context().settings };
api_context
.rust_context()
.update_access_methods(access_methods);
@@ -109,7 +109,7 @@ pub unsafe extern "C" fn mullvad_api_use_access_method(
) {
let api_context = api_context.rust_context();
// SAFETY: See Safety notes for `get_string`
- let id = get_string(access_method_id);
+ let id = unsafe { get_string(access_method_id) };
let Some(id) = Id::from_string(id) else {
return;
@@ -130,7 +130,7 @@ pub unsafe extern "C" fn mullvad_api_use_access_method(
///
/// This function is safe.
#[cfg(feature = "api-override")]
-#[no_mangle]
+#[unsafe(no_mangle)]
pub extern "C" fn mullvad_api_init_new_tls_disabled(
host: *const c_char,
address: *const c_char,
@@ -162,7 +162,7 @@ pub extern "C" fn mullvad_api_init_new_tls_disabled(
/// to proceed in a meaningful way anyway.
///
/// This function is safe.
-#[no_mangle]
+#[unsafe(no_mangle)]
pub extern "C" fn mullvad_api_init_new(
host: *const c_char,
address: *const c_char,
diff --git a/mullvad-ios/src/api_client/problem_report.rs b/mullvad-ios/src/api_client/problem_report.rs
index 652d27550e..06101b86f7 100644
--- a/mullvad-ios/src/api_client/problem_report.rs
+++ b/mullvad-ios/src/api_client/problem_report.rs
@@ -42,7 +42,8 @@ pub unsafe extern "C" fn mullvad_ios_send_problem_report(
retry_strategy: SwiftRetryStrategy,
request: SwiftProblemReportRequest,
) -> SwiftCancelHandle {
- let completion_handler = SwiftCompletionHandler::new(CompletionCookie::new(completion_cookie));
+ let completion_handler =
+ SwiftCompletionHandler::new(unsafe { CompletionCookie::new(completion_cookie) });
let completion = completion_handler.clone();
let Ok(tokio_handle) = crate::mullvad_ios_runtime() else {
@@ -122,9 +123,9 @@ struct ProblemReportRequest {
impl ProblemReportRequest {
// SAFETY: the members of `SwiftProblemReportRequest` must point to null-terminated strings
unsafe fn from_swift_parameters(request: SwiftProblemReportRequest) -> Option<Self> {
- let address = get_string(request.address);
- let message = get_string(request.message);
- let log = get_string(request.log).into();
+ let address = unsafe { get_string(request.address) };
+ let message = unsafe { get_string(request.message) };
+ let log = unsafe { get_string(request.log) }.into();
let metadata = if request.metadata.inner.is_null() {
BTreeMap::new()
@@ -132,7 +133,7 @@ impl ProblemReportRequest {
let swift_map = &request.metadata;
let mut converted_map = BTreeMap::new();
- if let Some(inner) = swift_map.inner.as_ref() {
+ if let Some(inner) = unsafe { swift_map.inner.as_ref() } {
for (key, value) in &inner.0 {
converted_map.insert(key.clone(), value.clone());
}
@@ -199,7 +200,7 @@ impl Map {
}
}
-#[no_mangle]
+#[unsafe(no_mangle)]
pub extern "C" fn swift_problem_report_metadata_new() -> ProblemReportMetadata {
let map = Box::new(Map::new());
ProblemReportMetadata {
@@ -230,7 +231,7 @@ pub unsafe extern "C" fn swift_problem_report_metadata_add(
}
}
-#[no_mangle]
+#[unsafe(no_mangle)]
pub extern "C" fn swift_problem_report_metadata_free(map: ProblemReportMetadata) {
if !map.inner.is_null() {
// SAFETY: `map.inner` must be properly aligned and non-null
diff --git a/mullvad-ios/src/api_client/response.rs b/mullvad-ios/src/api_client/response.rs
index 4871a5d4bf..df7795b0c2 100644
--- a/mullvad-ios/src/api_client/response.rs
+++ b/mullvad-ios/src/api_client/response.rs
@@ -142,21 +142,23 @@ impl SwiftMullvadApiResponse {
///
/// `response` must be pointing to a valid instance of `SwiftMullvadApiResponse`. This function
/// is not safe to call multiple times with the same `SwiftMullvadApiResponse`.
-#[no_mangle]
+#[unsafe(no_mangle)]
pub unsafe extern "C" fn mullvad_response_drop(response: SwiftMullvadApiResponse) {
- if !response.body.is_null() {
- let _ = Vec::from_raw_parts(response.body, response.body_size, response.body_size);
- }
+ unsafe {
+ if !response.body.is_null() {
+ let _ = Vec::from_raw_parts(response.body, response.body_size, response.body_size);
+ }
- if !response.etag.is_null() {
- let _ = CString::from_raw(response.etag);
- }
+ if !response.etag.is_null() {
+ let _ = CString::from_raw(response.etag);
+ }
- if !response.error_description.is_null() {
- let _ = CString::from_raw(response.error_description);
- }
+ if !response.error_description.is_null() {
+ let _ = CString::from_raw(response.error_description);
+ }
- if !response.server_response_code.is_null() {
- let _ = CString::from_raw(response.server_response_code);
+ if !response.server_response_code.is_null() {
+ let _ = CString::from_raw(response.server_response_code);
+ }
}
}
diff --git a/mullvad-ios/src/api_client/retry_strategy.rs b/mullvad-ios/src/api_client/retry_strategy.rs
index 80a3b9668c..06b9aa94db 100644
--- a/mullvad-ios/src/api_client/retry_strategy.rs
+++ b/mullvad-ios/src/api_client/retry_strategy.rs
@@ -9,7 +9,7 @@ impl SwiftRetryStrategy {
/// # Safety
/// The pointer must be a pointing to a valid instance of a `Box<RetryStrategy>`.
pub unsafe fn into_rust(self) -> RetryStrategy {
- *Box::from_raw(self.0)
+ unsafe { *Box::from_raw(self.0) }
}
}
@@ -46,7 +46,7 @@ pub enum RetryDelay {
/// Creates a retry strategy that never retries after failure.
/// The result needs to be consumed.
-#[no_mangle]
+#[unsafe(no_mangle)]
pub extern "C" fn mullvad_api_retry_strategy_never() -> SwiftRetryStrategy {
let retry_strategy = RetryStrategy {
delays: RetryDelay::Never,
@@ -59,7 +59,7 @@ pub extern "C" fn mullvad_api_retry_strategy_never() -> SwiftRetryStrategy {
/// Creates a retry strategy that retries `max_retries` times with a constant delay of `delay_sec`.
/// The result needs to be consumed.
-#[no_mangle]
+#[unsafe(no_mangle)]
pub extern "C" fn mullvad_api_retry_strategy_constant(
max_retries: usize,
delay_sec: u64,
@@ -77,7 +77,7 @@ pub extern "C" fn mullvad_api_retry_strategy_constant(
/// Creates a retry strategy that retries `max_retries` times with a exponantially increating delay.
/// The delay will never exceed `max_delay_sec`
/// The result needs to be consumed.
-#[no_mangle]
+#[unsafe(no_mangle)]
pub extern "C" fn mullvad_api_retry_strategy_exponential(
max_retries: usize,
initial_sec: u64,
diff --git a/mullvad-ios/src/api_client/shadowsocks_loader.rs b/mullvad-ios/src/api_client/shadowsocks_loader.rs
index 161ee8a30a..2d63b179d3 100644
--- a/mullvad-ios/src/api_client/shadowsocks_loader.rs
+++ b/mullvad-ios/src/api_client/shadowsocks_loader.rs
@@ -1,7 +1,7 @@
use std::ffi::c_void;
use talpid_types::net::proxy::Shadowsocks;
-extern "C" {
+unsafe extern "C" {
/// Creates a `Shadowsocks` configuration.
///
/// # SAFETY
diff --git a/mullvad-ios/src/api_client/storekit.rs b/mullvad-ios/src/api_client/storekit.rs
index 994e6628d7..f5e149b7a4 100644
--- a/mullvad-ios/src/api_client/storekit.rs
+++ b/mullvad-ios/src/api_client/storekit.rs
@@ -34,7 +34,7 @@ use super::{
/// `body_size` must be the size of the body
///
/// This function is not safe to call multiple times with the same `CompletionCookie`.
-#[no_mangle]
+#[unsafe(no_mangle)]
pub unsafe extern "C" fn mullvad_ios_legacy_storekit_payment(
api_context: SwiftApiContext,
completion_cookie: *mut libc::c_void,
@@ -43,7 +43,8 @@ pub unsafe extern "C" fn mullvad_ios_legacy_storekit_payment(
body: *const u8,
body_size: usize,
) -> SwiftCancelHandle {
- let completion_handler = SwiftCompletionHandler::new(CompletionCookie::new(completion_cookie));
+ let completion_handler =
+ SwiftCompletionHandler::new(unsafe { CompletionCookie::new(completion_cookie) });
let Ok(tokio_handle) = crate::mullvad_ios_runtime() else {
completion_handler.finish(SwiftMullvadApiResponse::no_tokio_runtime());
@@ -57,7 +58,7 @@ pub unsafe extern "C" fn mullvad_ios_legacy_storekit_payment(
let completion = completion_handler.clone();
// SAFETY: See param documentation for `account_number`.
- let account_number = AccountNumber::from(get_string(account_number));
+ let account_number = AccountNumber::from(unsafe { get_string(account_number) });
// SAFETY: See param documentation for `body`.
let body = unsafe { std::slice::from_raw_parts(body, body_size) }.to_vec();
@@ -110,14 +111,15 @@ async fn mullvad_ios_legacy_storekit_payment_inner(
/// `mullvad_api_retry_strategy_never`, `mullvad_api_retry_strategy_constant` or `mullvad_api_retry_strategy_exponential`
///
/// This function is not safe to call multiple times with the same `CompletionCookie`.
-#[no_mangle]
+#[unsafe(no_mangle)]
pub unsafe extern "C" fn mullvad_ios_init_storekit_payment(
api_context: SwiftApiContext,
completion_cookie: *mut libc::c_void,
retry_strategy: SwiftRetryStrategy,
account_number: *const c_char,
) -> SwiftCancelHandle {
- let completion_handler = SwiftCompletionHandler::new(CompletionCookie::new(completion_cookie));
+ let completion_handler =
+ SwiftCompletionHandler::new(unsafe { CompletionCookie::new(completion_cookie) });
let Ok(tokio_handle) = crate::mullvad_ios_runtime() else {
completion_handler.finish(SwiftMullvadApiResponse::no_tokio_runtime());
@@ -132,7 +134,7 @@ pub unsafe extern "C" fn mullvad_ios_init_storekit_payment(
let completion = completion_handler.clone();
// SAFETY: See param documentation for `account_number`.
- let account_number = AccountNumber::from(get_string(account_number));
+ let account_number = AccountNumber::from(unsafe { get_string(account_number) });
let task = tokio_handle.spawn(async move {
match mullvad_ios_init_storekit_payment_inner(
@@ -184,7 +186,7 @@ async fn mullvad_ios_init_storekit_payment_inner(
/// `body_size` must be the size of the body
///
/// This function is not safe to call multiple times with the same `CompletionCookie`.
-#[no_mangle]
+#[unsafe(no_mangle)]
pub unsafe extern "C" fn mullvad_ios_check_storekit_payment(
api_context: SwiftApiContext,
completion_cookie: *mut libc::c_void,
@@ -193,7 +195,8 @@ pub unsafe extern "C" fn mullvad_ios_check_storekit_payment(
body: *const u8,
body_size: usize,
) -> SwiftCancelHandle {
- let completion_handler = SwiftCompletionHandler::new(CompletionCookie::new(completion_cookie));
+ let completion_handler =
+ SwiftCompletionHandler::new(unsafe { CompletionCookie::new(completion_cookie) });
let Ok(tokio_handle) = crate::mullvad_ios_runtime() else {
completion_handler.finish(SwiftMullvadApiResponse::no_tokio_runtime());
@@ -207,7 +210,7 @@ pub unsafe extern "C" fn mullvad_ios_check_storekit_payment(
let completion = completion_handler.clone();
// SAFETY: See param documentation for `account_number`.
- let account_number = AccountNumber::from(get_string(account_number));
+ let account_number = AccountNumber::from(unsafe { get_string(account_number) });
// SAFETY: See param documentation for `body`.
let body = unsafe { std::slice::from_raw_parts(body, body_size) }.to_vec();
diff --git a/mullvad-ios/src/ephemeral_peer_proxy/mod.rs b/mullvad-ios/src/ephemeral_peer_proxy/mod.rs
index 9942c78f62..e0fc9420aa 100644
--- a/mullvad-ios/src/ephemeral_peer_proxy/mod.rs
+++ b/mullvad-ios/src/ephemeral_peer_proxy/mod.rs
@@ -94,7 +94,7 @@ impl Drop for DaitaParameters {
}
}
-extern "C" {
+unsafe extern "C" {
/// To be called when ephemeral peer exchange has finished. All parameters except
/// `raw_packet_tunnel` are optional.
///
diff --git a/mullvad-ios/src/lib.rs b/mullvad-ios/src/lib.rs
index b98960f158..305e044fd5 100644
--- a/mullvad-ios/src/lib.rs
+++ b/mullvad-ios/src/lib.rs
@@ -1,4 +1,5 @@
#![cfg(target_os = "ios")]
+#![allow(clippy::undocumented_unsafe_blocks)]
use libc::c_char;
use std::ffi::CStr;
use std::sync::OnceLock;
diff --git a/mullvad-ios/src/shadowsocks_proxy/ffi.rs b/mullvad-ios/src/shadowsocks_proxy/ffi.rs
index 815862fb52..cf038d6933 100644
--- a/mullvad-ios/src/shadowsocks_proxy/ffi.rs
+++ b/mullvad-ios/src/shadowsocks_proxy/ffi.rs
@@ -35,16 +35,17 @@ pub unsafe extern "C" fn start_shadowsocks_proxy(
.init();
});
- let forward_ip =
- if let Some(forward_address) = { parse_ip_addr(forward_address, forward_address_len) } {
- forward_address
- } else {
- return -1;
- };
+ let forward_ip = if let Some(forward_address) =
+ { unsafe { parse_ip_addr(forward_address, forward_address_len) } }
+ {
+ forward_address
+ } else {
+ return -1;
+ };
let forward_socket_addr = SocketAddr::new(forward_ip, forward_port);
- let bridge_ip = if let Some(addr) = { parse_ip_addr(addr, addr_len) } {
+ let bridge_ip = if let Some(addr) = { unsafe { parse_ip_addr(addr, addr_len) } } {
addr
} else {
return -1;
diff --git a/mullvad-ios/src/tunnel_obfuscator_proxy/ffi.rs b/mullvad-ios/src/tunnel_obfuscator_proxy/ffi.rs
index 849d4336cc..50ac53d3be 100644
--- a/mullvad-ios/src/tunnel_obfuscator_proxy/ffi.rs
+++ b/mullvad-ios/src/tunnel_obfuscator_proxy/ffi.rs
@@ -26,14 +26,11 @@ pub unsafe extern "C" fn start_udp2tcp_obfuscator_proxy(
) -> i32 {
init_logging();
- let peer_sock_addr = throw_int_error!(get_socket_address(
- peer_address,
- peer_address_len,
- peer_port
- ));
+ let peer_sock_addr =
+ throw_int_error!(unsafe { get_socket_address(peer_address, peer_address_len, peer_port) });
let result = TunnelObfuscatorRuntime::new_udp2tcp(peer_sock_addr).run();
- start(proxy_handle, result)
+ unsafe { start(proxy_handle, result) }
}
#[unsafe(no_mangle)]
@@ -45,14 +42,11 @@ pub unsafe extern "C" fn start_shadowsocks_obfuscator_proxy(
) -> i32 {
init_logging();
- let peer_sock_addr = throw_int_error!(get_socket_address(
- peer_address,
- peer_address_len,
- peer_port
- ));
+ let peer_sock_addr =
+ throw_int_error!(unsafe { get_socket_address(peer_address, peer_address_len, peer_port) });
let result = TunnelObfuscatorRuntime::new_shadowsocks(peer_sock_addr).run();
- start(proxy_handle, result)
+ unsafe { start(proxy_handle, result) }
}
#[unsafe(no_mangle)]
@@ -66,16 +60,13 @@ pub unsafe extern "C" fn start_quic_obfuscator_proxy(
) -> i32 {
init_logging();
- let peer_sock_addr = throw_int_error!(get_socket_address(
- peer_address,
- peer_address_len,
- peer_port
- ));
- let hostname = get_string(hostname);
- let token = get_string(token);
+ let peer_sock_addr =
+ throw_int_error!(unsafe { get_socket_address(peer_address, peer_address_len, peer_port) });
+ let hostname = unsafe { get_string(hostname) };
+ let token = unsafe { get_string(token) };
let result = TunnelObfuscatorRuntime::new_quic(peer_sock_addr, hostname, token).run();
- start(proxy_handle, result)
+ unsafe { start(proxy_handle, result) }
}
fn init_logging() {
diff --git a/mullvad-nsis/src/lib.rs b/mullvad-nsis/src/lib.rs
index e47436da5d..5aed1389c0 100644
--- a/mullvad-nsis/src/lib.rs
+++ b/mullvad-nsis/src/lib.rs
@@ -21,7 +21,10 @@ pub enum Status {
/// Max path size allowed
const MAX_PATH_SIZE: isize = 32_767;
-/// SAFETY: path needs to be a windows path encoded as a string of u16 that terminates in 0 (two
+/// Creates a privileged directory at the specified Windows path.
+///
+/// # SAFETY
+/// path needs to be a windows path encoded as a string of u16 that terminates in 0 (two
/// nul-bytes). The string is also not allowed to be greater than `MAX_PATH_SIZE`.
#[unsafe(no_mangle)]
pub unsafe extern "C" fn create_privileged_directory(path: *const u16) -> Status {
@@ -29,14 +32,18 @@ pub unsafe extern "C" fn create_privileged_directory(path: *const u16) -> Status
let mut i = 0;
// Calculate the length of the path by checking when the first u16 == 0
let len = loop {
- if *(path.offset(i)) == 0 {
+ // SAFETY: We assume that `path` is a valid pointer to a u16 array,
+ // ending with a null terminator.
+ if unsafe { *(path.offset(i)) } == 0 {
break i;
} else if i >= MAX_PATH_SIZE {
return Status::InvalidArguments;
}
i += 1;
};
- let path = std::slice::from_raw_parts(path, len as usize);
+ // SAFETY: Because we checked the length, we can safely create a slice
+ // from the raw pointer.
+ let path = unsafe { std::slice::from_raw_parts(path, len as usize) };
let path = OsString::from_wide(path);
let path = Path::new(&path);
@@ -52,6 +59,10 @@ pub unsafe extern "C" fn create_privileged_directory(path: *const u16) -> Status
/// is returned, and the required buffer size (in chars) is returned in `buffer_size`.
/// On success, `buffer_size` is set to the length of the string, including
/// the final null terminator.
+///
+/// # SAFETY
+/// if `buffer` is not null, it must point to a valid memory location that can hold
+/// at least `buffer_size` number of `u16` values.
#[unsafe(no_mangle)]
pub unsafe extern "C" fn get_system_local_appdata(
buffer: *mut u16,
@@ -72,15 +83,20 @@ pub unsafe extern "C" fn get_system_local_appdata(
let path = path.as_os_str();
let path_u16: Vec<u16> = path.encode_wide().chain(std::iter::once(0u16)).collect();
- let prev_len = *buffer_size;
+ // SAFETY: `buffer_size` is non-null because we checked it above.
+ unsafe {
+ let prev_len = *buffer_size;
+ *buffer_size = path_u16.len();
- *buffer_size = path_u16.len();
-
- if prev_len < path_u16.len() || buffer.is_null() {
- return Status::InsufficientBufferSize;
+ if prev_len < path_u16.len() || buffer.is_null() {
+ return Status::InsufficientBufferSize;
+ }
}
- ptr::copy_nonoverlapping(path_u16.as_ptr(), buffer, path_u16.len());
+ // SAFETY: We assume that `buffer` is a valid pointer to a u16 array
+ // and because of the previous check, we know that `buffer` has enough space
+ // to hold the contents of `path_u16`.
+ unsafe { ptr::copy_nonoverlapping(path_u16.as_ptr(), buffer, path_u16.len()) };
Status::Ok
})
@@ -91,6 +107,10 @@ pub unsafe extern "C" fn get_system_local_appdata(
/// `InsufficientBufferSize` is returned, and the required buffer size (in
/// chars) is returned in `buffer_size`. On success, `buffer_size` is set to the
/// length of the string, including the final null terminator.
+///
+/// # Safety
+/// If `buffer` is not null, it must point to a valid memory location that can hold
+/// at least `*buffer_size` number of `u16` values. `buffer_size` must be a valid pointer.
#[unsafe(no_mangle)]
pub unsafe extern "C" fn get_system_version(buffer: *mut u16, buffer_size: *mut usize) -> Status {
use talpid_platform_metadata::version;
@@ -105,13 +125,19 @@ pub unsafe extern "C" fn get_system_version(buffer: *mut u16, buffer_size: *mut
.chain(iter::once(0u16))
.collect();
- if *buffer_size < build_number.len() || buffer.is_null() {
- return Status::InsufficientBufferSize;
- }
+ // SAFETY: `buffer_size` is non-null because we checked it above.
+ unsafe {
+ if *buffer_size < build_number.len() || buffer.is_null() {
+ return Status::InsufficientBufferSize;
+ }
- *buffer_size = build_number.len();
+ *buffer_size = build_number.len();
+ }
- ptr::copy_nonoverlapping(build_number.as_ptr(), buffer, build_number.len());
+ // SAFETY: We assume that `buffer` is a valid pointer to a u16 array
+ // and because of the previous check, we know that `buffer` has enough space
+ // to hold the contents of `build_number`.
+ unsafe { ptr::copy_nonoverlapping(build_number.as_ptr(), buffer, build_number.len()) };
Status::Ok
})
}
diff --git a/mullvad-types/src/auth_failed.rs b/mullvad-types/src/auth_failed.rs
index 335f8463f3..a86540eca6 100644
--- a/mullvad-types/src/auth_failed.rs
+++ b/mullvad-types/src/auth_failed.rs
@@ -79,13 +79,19 @@ mod tests {
#[test]
fn test_parsing() {
- let tests = vec![
- (Some("INVALID_ACCOUNT"),
- "[INVALID_ACCOUNT] This is not a valid Mullvad account"),
- (Some("EXPIRED_ACCOUNT"),
- "[EXPIRED_ACCOUNT] This account has no time left"),
- (Some("TOO_MANY_CONNECTIONS"),
- "[TOO_MANY_CONNECTIONS] This Mullvad account is already used by the maximum number of simultaneous connections"),
+ let tests = [
+ (
+ Some("INVALID_ACCOUNT"),
+ "[INVALID_ACCOUNT] This is not a valid Mullvad account",
+ ),
+ (
+ Some("EXPIRED_ACCOUNT"),
+ "[EXPIRED_ACCOUNT] This account has no time left",
+ ),
+ (
+ Some("TOO_MANY_CONNECTIONS"),
+ "[TOO_MANY_CONNECTIONS] This Mullvad account is already used by the maximum number of simultaneous connections",
+ ),
(None, "[Incomplete String"),
(Some("REASON_REASON"), "[REASON_REASON]"),
(Some("REASON_REASON"), "[REASON_REASON]A"),