Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Local file path strings embedded in binary #56

Open
ptdecker opened this issue Nov 6, 2023 · 7 comments
Open

Local file path strings embedded in binary #56

ptdecker opened this issue Nov 6, 2023 · 7 comments

Comments

@ptdecker
Copy link

ptdecker commented Nov 6, 2023

Hello!

I'm working through this awesome guide to reduce the size of my compiled binaries. It is making a big difference. While inspecting the result, I used strings to take a look at what strings are still in the result. I see multiple places where it appears that the resultant release binary contains file paths which are a reflection of my local file system. Also, these paths are sometimes long and thus also contributing slightly to binary size. I'd like to understand why these full paths are being included and if there is a way to suppress them.

Your help, thoughts, and ideas are much appreciated!

Here is my release compile profile:

[profile.release]
# Cf. https://github.com/johnthagen/min-sized-rust
strip = true # automatically strip symbols from the binary
opt-level = "s" # optimize for binary size
lto = true # link-time optimization enabled
codegen-units = 1 # prevent build-time parallelization
debug = false
panic = "abort"

And, here is a redacted sample of the output of strings on the resultant binary:

release/macos/aarch64/bin/foo | grep "ptdecker"

Output (redacted):

[redacted]
/Users/ptdecker/.cargo/registry/src/index.crates.io-6f17d22bba15001f/indexmap-2.1.0/src/map/core.rsBigNumber failed to deserialize: 11Broadcast is less than 4 bytes and does not include key version Keys were generated with Crypto Module Version ./Users/ptdecker/PycharmProjects/foo/fizz/src/common/secure_big_num.rsSecureBigNumber failed to deserialize:
gcd(challenge,N) != 1 for Paillier GCD Proof Challenge Generation!/Users/ptdecker/PycharmProjects/bar/[redacted]
/rustc/cc66ad468955717ab92600c770da8c1601a4ff33/library/core/src/sync/atomic.rsthere is no such thing as an acquire storethere is no such thing as an acquire-release storeinternal error: entered unreachable code: unknown state: /Users/ptdecker/.cargo/registry/src/index.crates.io-6f17d22bba15001f/want-0.3.1/src/lib.rs/Users/ptdecker/.cargo/registry/src/index.crates.io-6f17d22bba15001f/zeroize-1.6.0/src/lib.rsassertion failed: size <= isize::MAX as usize
/Users/ptdecker/PycharmProjects/foo/fizz/target/aarch64-apple-darwin/release/build/openssl-sys-f6a0d3a636f0f1e4/out/openssl-build/install/lib/engines-3
/Users/ptdecker/PycharmProjects/foo/fizz/target/aarch64-apple-darwin/release/build/openssl-sys-f6a0d3a636f0f1e4/out/openssl-build/install/lib/ossl-modules
[redacted]

Note the /Users/ptdecker/PycharmProjects/baz/foo/target... paths

@johnthagen
Copy link
Owner

johnthagen commented Nov 6, 2023

@ptdecker
Copy link
Author

ptdecker commented Nov 8, 2023

Thank you @johnthagen, I will check these out!

Also, I was looking through the Unstable Book and found these--any thoughts if they are helpful too? On quick look, looks like perhaps the -Ztrim-paths is related to these. I really appreciate you chiming in on this thread. I'll read the links you provided and close with findings if it addresses my issue.

@ptdecker
Copy link
Author

ptdecker commented Nov 8, 2023

Ran with -Ztrim-paths on current nightly but the local paths are still in there. I'm probably doing something wrong with it and will keep working at it.

@johnthagen
Copy link
Owner

This won't help for size, but a short term idea to help avoid leaking your personal information into the binaries would be to build in a container (for Linux builds) or some kind of generic CI system or VM for Windows/macOS such as GitHub Actions.

@polarathene
Copy link

polarathene commented Nov 22, 2023

For reproduction, there is this example (which began the discussion that led to -Z trim-paths):

[dependencies]
rand = "0.8.0"
use rand::prelude::*;
    
fn main() {
    let r: f64 = rand::thread_rng().gen();
    println!("{}", r);
}

Then with either the mentioned -Z trim-paths or RUSTFLAGS -Z location-detail=none the home user is not present in the strings output:

$ cargo +nightly build --release -Z trim-paths
$ RUSTFLAGS="-Z location-detail=none" cargo +nightly build --release
  • I confirmed it did contain my user home path without either of those options (with or without your Cargo.toml release additons).
  • I built this reproduction:
    • With a fresh project created via cargo init + applying the above change snippets.
    • With the current nightly for Rust.
    • On Windows WSL2 x86_64 with the x86_64-unknown-linux-gnu target & toolchain.

Perhaps you can verify the above, and then try identify what is being done differently for those not to work. Make sure you're not building from any cache which may already have those paths too?

There is also this issue which notes that RUSTFLAGS will apply differently when an explicit --target is set. I could be misunderstanding that though, may only be relevant when using -C target-feature to override a target default. Still it highlights a gotcha where config compiled differently (the fix for the user was to provide the explicit --target).

TL;DR

Maybe try -Z location-detail=none (RUSTFLAG env, not cargo option), since it seems to achieve the same? (at least in the reproduction example, I assume it's a more aggressive approach with other side-effects)

@lihe07
Copy link

lihe07 commented Jan 21, 2024

I am able to get rid of all path and dependencies information by adding trim-paths = "all" to [profile.release].
Now the official RFC doc mentioned this option.

@johnthagen
Copy link
Owner

From https://rust-lang.github.io/rfcs/3127-trim-paths.html#cargo:

It is defaulted to none for debug profiles, and object for release profiles

The default release profile setting (object) sanitises only the paths in emitted executable or library files. It always affects paths from macros such as panic messages, and in debug information only if they will be embedded together with the binary (the default on platforms with ELF binaries, such as Linux and windows-gnu), but will not touch them if they are in separate files (the default on Windows MSVC and macOS). But the paths to these separate files are sanitised.

Reading the docs, it seems like this default for release profile should resolve most practical issues related to privacy. So when this goes stable, trimming paths should just work for everyone. Also seems like if you are using nightly, you can already get this behavior by default.

For reference, as of Rust 1.75.0, this is still a nightly-only feature.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants