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

[SR-5405] Security: Swift on Linux not compiled as position independent executable #47979

Closed
weissi opened this issue Jul 8, 2017 · 6 comments
Labels
bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. compiler The Swift compiler in itself Linux Platform: Linux

Comments

@weissi
Copy link
Member

weissi commented Jul 8, 2017

Previous ID SR-5405
Radar None
Original Reporter @weissi
Type Bug
Status Resolved
Resolution Done
Additional Detail from JIRA
Votes 0
Component/s Compiler
Labels Bug, Linux
Assignee None
Priority Medium

md5: f27c5ea608b19e3f52b4ecaecf00b78c

relates to:

  • SR-4443 Android: Cannot run swift executable on Android 7.0 emulator (armv7) as it is not a PIE

Issue Description:

Problem

On Linux, Swift executables don't seem to be position-independent executables (https://en.wikipedia.org/wiki/Position-independent_code). That's a security issue as it will make exploitation pretty easy (building a ROP chain (https://en.wikipedia.org/wiki/Return-oriented_programming) from known addresses).

The whole main Swift program seems to reside at fixed addresses. On macOS, everything seems fine.

Repro

The following command creates a simple Swift program that just crashes (and as a side-effect prints addresses), then compiles and executes it 10 times.

echo 'fatalError()' > testprogram.swift && swiftc testprogram.swift && for f in $(seq 10); do ./testprogram 2>&1; done | grep testprogram

Linux

$ echo 'fatalError()' > testprogram.swift && swiftc testprogram.swift && for f in $(seq 10); do ./testprogram 2>&1; done | grep testprogram
fatal error: file testprogram.swift, line 1
9    testprogram                        0x0000000000400a90 <unavailable> + 2704
11   testprogram                        0x0000000000400909 <unavailable> + 2313
fatal error: file testprogram.swift, line 1
9    testprogram                        0x0000000000400a90 <unavailable> + 2704
11   testprogram                        0x0000000000400909 <unavailable> + 2313
fatal error: file testprogram.swift, line 1
9    testprogram                        0x0000000000400a90 <unavailable> + 2704
11   testprogram                        0x0000000000400909 <unavailable> + 2313
fatal error: file testprogram.swift, line 1
9    testprogram                        0x0000000000400a90 <unavailable> + 2704
11   testprogram                        0x0000000000400909 <unavailable> + 2313
fatal error: file testprogram.swift, line 1
9    testprogram                        0x0000000000400a90 <unavailable> + 2704
11   testprogram                        0x0000000000400909 <unavailable> + 2313
fatal error: file testprogram.swift, line 1
9    testprogram                        0x0000000000400a90 <unavailable> + 2704
11   testprogram                        0x0000000000400909 <unavailable> + 2313
fatal error: file testprogram.swift, line 1
9    testprogram                        0x0000000000400a90 <unavailable> + 2704
11   testprogram                        0x0000000000400909 <unavailable> + 2313
fatal error: file testprogram.swift, line 1
9    testprogram                        0x0000000000400a90 <unavailable> + 2704
11   testprogram                        0x0000000000400909 <unavailable> + 2313
fatal error: file testprogram.swift, line 1
9    testprogram                        0x0000000000400a90 <unavailable> + 2704
11   testprogram                        0x0000000000400909 <unavailable> + 2313
fatal error: file testprogram.swift, line 1
9    testprogram                        0x0000000000400a90 <unavailable> + 2704
11   testprogram                        0x0000000000400909 <unavailable> + 2313

the addresses 0x400a90 and 0x400909 are the same for all the 10 runs.

macOS

$ echo 'fatalError()' > testprogram.swift && swiftc testprogram.swift && for f in $(seq 10); do ./testprogram 2>&1; done | grep testprogram
fatal error: file testprogram.swift, line 1
10   testprogram                        0x000000010edc3580 __ARCLite__load() + 0
fatal error: file testprogram.swift, line 1
10   testprogram                        0x000000010baeb580 __ARCLite__load() + 0
fatal error: file testprogram.swift, line 1
10   testprogram                        0x00000001068d9580 __ARCLite__load() + 0
fatal error: file testprogram.swift, line 1
10   testprogram                        0x000000010e334580 __ARCLite__load() + 0
fatal error: file testprogram.swift, line 1
10   testprogram                        0x000000010656a580 __ARCLite__load() + 0
fatal error: file testprogram.swift, line 1
10   testprogram                        0x00000001087dc580 __ARCLite__load() + 0
fatal error: file testprogram.swift, line 1
10   testprogram                        0x000000010b54c580 __ARCLite__load() + 0
fatal error: file testprogram.swift, line 1
10   testprogram                        0x0000000100461580 __ARCLite__load() + 0
fatal error: file testprogram.swift, line 1
10   testprogram                        0x000000010bb5d580 __ARCLite__load() + 0
fatal error: file testprogram.swift, line 1
10   testprogram                        0x000000010150a580 __ARCLite__load() + 0

as expected, we see different addresses: 0x10150a580, 0x10bb5d580, 0x10b54c580.

Versions and stuff

  • macOS 10.12.5 (16F2104)

  • Ubuntu Xenial

  • Linux swiftc: Swift version 4.0-dev (LLVM 2c7b572db2, Clang 54c8e38855, Swift d9fb110)

@belkadan
Copy link
Contributor

We shouldn't have any dependencies on fixed addresses on Linux, so this should just be a matter of adding the right flags.

@jckarter
Copy link
Member

Hopefully setting -fpie will also help with some of the obscure linker bugs some people are seeing, since some of the things ELF linkers try to do with non-PIE executables are fundamentally at odds with Swift's resilience goals, such as using copy relocations to copy fixed-size globals into fixed addresses in the executable.

@alblue
Copy link
Contributor

alblue commented Aug 2, 2017

Joe, I think #11272 solves this issue by adding -pie to the linker stage; can you take a look?

@jckarter
Copy link
Member

jckarter commented Aug 2, 2017

Yep, that should be all that's needed. Thanks!

@weissi
Copy link
Member Author

weissi commented Aug 22, 2017

@jckartergmilos (JIRA User) I'll close this as I believe it's fixed.

@jckarter
Copy link
Member

It sounds like we may want to be more specific about when we pass `-pie`, since clang warns about the argument being unused in some situations: https://bugs.swift.org/browse/SR-5721

@swift-ci swift-ci transferred this issue from apple/swift-issues Apr 25, 2022
This issue was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. compiler The Swift compiler in itself Linux Platform: Linux
Projects
None yet
Development

No branches or pull requests

4 participants