-
Notifications
You must be signed in to change notification settings - Fork 13.6k
Closed
Labels
A-linkageArea: linking into static, shared libraries and binariesArea: linking into static, shared libraries and binariesC-bugCategory: This is a bug.Category: This is a bug.O-windowsOperating system: WindowsOperating system: WindowsT-compilerRelevant to the compiler team, which will review and decide on the PR/issue.Relevant to the compiler team, which will review and decide on the PR/issue.
Description
I tried this code:
#[link(name = "api-ms-win-core-synch-l1-2-0", kind = "raw-dylib", import_name_type = "undecorated")]
extern "system" {
pub fn WakeByAddressSingle(address: *const c_void);
}
In WIndws x86, the symbol name that should be generated should be: __imp__WakeByAddressSingle@4
But, the symbol name of the rust generation is: __imp_WakeByAddressSingle
.
When generating the lib, the symbol name should remain __imp__WakeByAddressSingle@4
, just set the IMPORT_OBJECT_HEADER::NameType
property to IMPORT_NAME_UNDECORATE
. Then the linker will automatically convert the name to WakeByAddressSingle
.
// Windows SDK(winnt.h)
typedef struct IMPORT_OBJECT_HEADER {
WORD Sig1; // Must be IMAGE_FILE_MACHINE_UNKNOWN
WORD Sig2; // Must be IMPORT_OBJECT_HDR_SIG2.
WORD Version;
WORD Machine;
DWORD TimeDateStamp; // Time/date stamp
DWORD SizeOfData; // particularly useful for incremental links
union {
WORD Ordinal; // if grf & IMPORT_OBJECT_ORDINAL
WORD Hint;
} DUMMYUNIONNAME;
WORD Type : 2; // IMPORT_TYPE
WORD NameType : 3; // IMPORT_NAME_TYPE
WORD Reserved : 11; // Reserved. Must be zero.
} IMPORT_OBJECT_HEADER;
Metadata
Metadata
Assignees
Labels
A-linkageArea: linking into static, shared libraries and binariesArea: linking into static, shared libraries and binariesC-bugCategory: This is a bug.Category: This is a bug.O-windowsOperating system: WindowsOperating system: WindowsT-compilerRelevant to the compiler team, which will review and decide on the PR/issue.Relevant to the compiler team, which will review and decide on the PR/issue.
Type
Projects
Milestone
Relationships
Development
Select code repository
Activity
[-]Windows x86 platform, incorrect symbol names generated using rust raw-dylib undecorated[/-][+]Windows x86 platform, incorrect symbol names generated using rust `raw-dylib+undecorated`[/+][-]Windows x86 platform, incorrect symbol names generated using rust `raw-dylib+undecorated`[/-][+]in Windows x86, incorrect symbol names generated using rust `raw-dylib+undecorated`[/+][-]in Windows x86, incorrect symbol names generated using rust `raw-dylib+undecorated`[/-][+]in Windows x86, the symbol name generated by `raw-dylib+undecorated` are not as expected[/+]bjorn3 commentedon May 11, 2024
Why are you using
undecorated
if you need the@4
?import_name_type = "undecorated"
tells rustc to not generate any prefixes or suffixes to the symbol. If you want themimport_name_type = "decorated"
(the default) is what you should use afaik.mingkuang-Chuyu commentedon May 12, 2024
Normally, the import_name_type attribute should not change the symbol name.
You can check the "synchronization.lib" file of the Windows SDK, the info about
WakeByAddressSingle
function is as follows:dumpbin /HEADERS "C:\Program Files (x86)\Windows Kits\10\Lib\10.0.22621.0\um\x86\synchronization.lib"
Then we look at the disassembly code when using WakeByAddressSingle, and we can see that the symbol name is still __imp__WakeByAddressSingle@4.
Rust's behavior is not standard, and there are security issues.
In another lib file, there happens to be such a function. Because of Rust's non-standard behavior, they will have exactly the same symbol names. This makes it impossible for the linker to distinguish between them, and the linker will only use the first symbol.
In the following code, will rust use the
_Test
function or theTest
function? Why is this so? This is because rust's undecorated doesn't follow the C decorated name rule!ChrisDenton commentedon May 13, 2024
cc @dpaoliello for this and #124956
dpaoliello commentedon May 13, 2024
Can you please elaborate on this? If you are linking against a malicious import library or loading a malicious DLL, then name confusion doesn't provide any benefits to the attacker: they already have arbitrary read/write/execute and can use many other tricks to force their code to be executed.
This is a fair criticism, but we'd need to make sure that using
NameType
produces the same behavior that Rust currently has (i.e., that we can control exactly which function name is loaded at runtime) especially in cases where GCC and MSVC disagree (see theimport_name_type
MCP). I wouldn't want to change this now without an MCP and a motivating example where the Rust compiler has incorrect behavior.Can you please point me to documentation for this "standard" or "rule"?
Also, the intent of
import_name_type
is to opt-out of normal function name decoration and instead to use the modified name decoration that is documented in Rust's docs: https://doc.rust-lang.org/reference/items/external-blocks.html#the-import_name_type-key.It calls
Test
inDLL A.dll
because you asked it to callTest
without any decorations.You have shown that Rust produces different import headers than MSVC or Clang does, but you haven't explained why this is an issue. Please remember that the goal of the
raw-dylib
feature in Rust is that the final binary will load a specific function from a specific DLL without the developer having to provide an import library to the linker. This is a different goal than MSVC and Clang have for their import libraries.If you can show an example where Rust calls a function that does not match the name per the
import_name_type
spec in the Rust docs (conflicting symbol definitions? linker depending onSymbolName
being set?) then that would be a bug that we could address.6 remaining items
ChrisDenton commentedon Sep 19, 2024
Given the issue linked directly above it seems like this is an issue, at least for Firefox.
dpaoliello commentedon Sep 19, 2024
Working on a fix...
bjorn3 commentedon Sep 19, 2024
If we're at it, would it make sense to mangle the symbol name using the regular rust symbol mangling too? We do this for wasm imports too (
rust/compiler/rustc_symbol_mangling/src/lib.rs
Lines 191 to 204 in 749f80a
Rollup merge of rust-lang#130586 - dpaoliello:fixrawdylib, r=wesleywiser
Rollup merge of rust-lang#130586 - dpaoliello:fixrawdylib, r=wesleywiser
Rollup merge of rust-lang#130586 - dpaoliello:fixrawdylib, r=wesleywiser
Unrolled build for rust-lang#130586
Rollup merge of rust-lang#130586 - dpaoliello:fixrawdylib, r=wesleywiser
Rollup merge of rust-lang#130586 - dpaoliello:fixrawdylib, r=wesleywiser