惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

V2EX - 技术
V2EX - 技术
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
T
Threat Research - Cisco Blogs
T
The Exploit Database - CXSecurity.com
S
Schneier on Security
S
Securelist
P
Privacy & Cybersecurity Law Blog
Scott Helme
Scott Helme
T
Threatpost
C
Cybersecurity and Infrastructure Security Agency CISA
L
LINUX DO - 热门话题
Cyberwarzone
Cyberwarzone
Cisco Talos Blog
Cisco Talos Blog
量子位
博客园 - Franky
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
Latest news
Latest news
T
Troy Hunt's Blog
N
News | PayPal Newsroom
Google Online Security Blog
Google Online Security Blog
Apple Machine Learning Research
Apple Machine Learning Research
N
Netflix TechBlog - Medium
小众软件
小众软件
P
Palo Alto Networks Blog
Spread Privacy
Spread Privacy
C
Cyber Attacks, Cyber Crime and Cyber Security
C
Check Point Blog
aimingoo的专栏
aimingoo的专栏
WordPress大学
WordPress大学
L
Lohrmann on Cybersecurity
L
LINUX DO - 最新话题
D
Darknet – Hacking Tools, Hacker News & Cyber Security
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
The Last Watchdog
The Last Watchdog
S
Security @ Cisco Blogs
P
Privacy International News Feed
Last Week in AI
Last Week in AI
Microsoft Security Blog
Microsoft Security Blog
T
Tailwind CSS Blog
博客园_首页
云风的 BLOG
云风的 BLOG
V
Vulnerabilities – Threatpost
D
DataBreaches.Net
Recent Announcements
Recent Announcements
酷 壳 – CoolShell
酷 壳 – CoolShell
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
罗磊的独立博客
Engineering at Meta
Engineering at Meta
Forbes - Security
Forbes - Security
T
Tenable Blog

Rust Blog

Security Advisory for Cargo (CVE-2026-5223) | Rust Blog Security Advisory for Cargo (CVE-2026-5222) | Rust Blog Project goals update — April 2026 (end of 2025H2) | Rust Blog Rust is participating in Outreachy | Rust Blog Raising the baseline for the `nvptx64-nvidia-cuda` target | Rust Blog Announcing Google Summer of Code 2026 selected projects | Rust Blog Announcing Rust 1.95.0 | Rust Blog docs.rs: building fewer targets by default | Rust Blog Announcing Rust 1.94.1 | Rust Blog Security advisory for Cargo | Rust Blog What we heard about Rust's challenges | Rust Blog Call for Testing: Build Dir Layout v2 | Rust Blog Announcing rustup 1.29.0 | Rust Blog Announcing Rust 1.94.0 | Rust Blog 2025 State of Rust Survey Results | Rust Blog Rust debugging survey 2026 | Rust Blog Update on the October 15, 2018 incident on crates.io Announcing Rust 1.29.2 Announcing Rust 1.29 Launching the 2018 State of Rust Survey Announcing Rust 1.28 What is Rust 2018? Announcing Rust 1.27.2 Announcing Rust 1.27.1 Security Advisory for rustdoc Announcing Rust 1.27 Announcing Rust 1.26.2 Announcing Rust 1.26.1 Rust turns three Announcing Rust 1.26 The Rust Team All Hands in Berlin: a Recap Increasing Rust’s Reach 2018 Announcing Rust 1.25 Rust's 2018 roadmap Announcing Rust 1.24.1 Announcing Rust 1.24 The 2018 Rust Event Lineup Announcing Rust 1.23 New Year's Rust: A Call for Community Blogposts Rust in 2017: what we achieved Announcing Rust 1.22 (and 1.22.1) Fearless Concurrency in Firefox Quantum Announcing Rust 1.21 impl Future for Rust Rust 2017 Survey Results Announcing Rust 1.20 Announcing Rust 1.19 The 2017 Rust Conference Lineup Rust's 2017 roadmap, six months in Increasing Rust’s Reach Announcing Rust 1.18 Two years of Rust The Rust Libz Blitz Launching the 2017 State of Rust Survey Announcing Rust 1.17 Announcing Rust 1.16 Rust's language ergonomics initiative Announcing Rust 1.15.1 Rust's 2017 roadmap Announcing Rust 1.15 Announcing Rust 1.14 Announcing the First Underhanded Rust Contest Announcing Rust 1.13 Announcing Rust 1.12.1 Announcing Rust 1.12 Incremental Compilation Announcing Rust 1.11 Shape of errors to come The 2016 Rust Conference Lineup Announcing Rust 1.10 State of Rust Survey 2016 Announcing Rust 1.9 One year of Rust Taking Rust everywhere with rustup Launching the 2016 State of Rust Survey Cargo: predictable dependency management Introducing MIR Announcing Rust 1.8 Announcing Rust 1.7 Announcing Rust 1.6 Announcing Rust 1.5 Announcing Rust 1.4 Announcing Rust 1.3 Rust in 2016 Announcing Rust 1.2 Rust 1.1 stable, the Community Subteam, and RustCamp Announcing Rust 1.0 Abstraction without overhead: traits in Rust Rust Once, Run Everywhere Mixing matching, mutation, and moves in Rust Fearless Concurrency with Rust Announcing Rust 1.0 Beta Announcing Rust 1.0.0.alpha.2 Rust 1.0: status report and final timeline Announcing Rust 1.0 Alpha Rust 1.0: Scheduling the trains Yehuda Katz and Steve Klabnik are joining the Rust Core Team Cargo: Rust's community crate host Stability as a Deliverable Road to Rust 1.0
Changes to WebAssembly targets and handling undefined symbols | Rust Blog
Apr. 4, 2026 · Alex Crichton · 2026-04-04 · via Rust Blog

Rust's WebAssembly targets are soon going to experience a change which has a risk of breaking existing projects, and this post is intended to notify users of this upcoming change, explain what it is, and how to handle it. Specifically, all WebAssembly targets in Rust have been linked using the --allow-undefined flag to wasm-ld, and this flag is being removed.

What is --allow-undefined?

WebAssembly binaries in Rust today are all created by linking with wasm-ld. This serves a similar purpose to ld, lld, and mold, for example; it takes separately compiled crates/object files and creates one final binary. Since the first introduction of WebAssembly targets in Rust, the --allow-undefined flag has been passed to wasm-ld. This flag is documented as:

  --allow-undefined       Allow undefined symbols in linked binary. This options
                          is equivalent to --import-undefined and
                          --unresolved-symbols=ignore-all

The term "undefined" here specifically means with respect to symbol resolution in wasm-ld itself. Symbols used by wasm-ld correspond relatively closely to what native platforms use, for example all Rust functions have a symbol associated with them. Symbols can be referred to in Rust through extern "C" blocks, for example:

unsafe extern "C" {
    fn mylibrary_init();
}

fn init() {
    unsafe {
        mylibrary_init();
    }
}

The symbol mylibrary_init is an undefined symbol. This is typically defined by a separate component of a program, such as an externally compiled C library, which will provide a definition for this symbol. By passing --allow-undefined to wasm-ld, however, it means that the above would generate a WebAssembly module like so:

(module
    (import "env" "mylibrary_init" (func $mylibrary_init))

    ;; ...
)

This means that the undefined symbol was ignored and ended up as an imported symbol in the final WebAssembly module that is produced.

The precise history here is somewhat lost to time, but the current understanding is that --allow-undefined was effectively required in the very early days of introducing wasm-ld to the Rust toolchain. This historical workaround stuck around till today and hasn't changed.

What's wrong with --allow-undefined?

By passing --allow-undefined on all WebAssembly targets, rustc is introducing diverging behavior between other platforms and WebAssembly. The main risk of --allow-undefined is that misconfiguration or mistakes in building can result in broken WebAssembly modules being produced, as opposed to compilation errors. This means that the proverbial can is kicked down the road and lengthens the distance from where the problem is discovered to where it was introduced. Some example problematic situations are:

  • If mylibrary_init was typo'd as mylibraryinit then the final binary would import the mylibraryinit symbol instead of calling the linked mylibrary_init C symbol.

  • If mylibrary was mistakenly not compiled and linked into a final application then the mylibrary_init symbol would end up imported rather than producing a linker error saying it's undefined.

  • If external tooling is used to process a WebAssembly module, such as wasm-bindgen or wasm-tools component new, these tools don't know what to do with "env" imports by default and they are likely to provide an error message of some form that isn't clearly connected back to the original source code and where the symbols was imported from.

  • For web users if you've ever seen an error along the lines of Uncaught TypeError: Failed to resolve module specifier "env". Relative references must start with either "/", "./", or "../". this can mean that "env" leaked into the final module unexpectedly and the true error is the undefined symbol error, not the lack of "env" items provided.

All native platforms consider undefined symbols to be an error by default, and thus by passing --allow-undefined rustc is introducing surprising behavior on WebAssembly targets. The goal of the change is to remove this surprise and behave more like native platforms.

What is going to break, and how to fix?

In theory, not a whole lot is expected to break from this change. If the final WebAssembly binary imports unexpected symbols, then it's likely that the binary won't be runnable in the desired embedding, as the desired embedding probably doesn't provide the symbol as a definition. For example, if you compile an application for wasm32-wasip1 if the final binary imports mylibrary_init then it'll fail to run in most runtimes because it's considered an unresolved import. This means that most of the time this change won't break users, but it'll instead provide better diagnostics.

The reason for this post, however, is that it's possible users could be intentionally relying on this behavior. For example your application might have:

unsafe extern "C" {
    fn js_log(n: u32);
}

// ...

And then perhaps some JS code that looks like:

let instance = await WebAssembly.instantiate(module, {
    env: {
        js_log: n => console.log(n),
    }
});

Effectively it's possible for users to explicitly rely on the behavior of --allow-undefined generating an import in the final WebAssembly binary.

If users encounter this then the code can be fixed through a #[link] attribute which explicitly specifies the wasm_import_module name:

#[link(wasm_import_module = "env")]
unsafe extern "C" {
    fn js_log(n: u32);
}

// ...

This will have the same behavior as before and will no longer be considered an undefined symbol to wasm-ld, and it'll work both before and after this change.

Affected users can also compile with -Clink-arg=--allow-undefined as well to quickly restore the old behavior.

When is this change being made?

Removing --allow-undefined on wasm targets is being done in rust-lang/rust#149868. That change is slated to land in nightly soon, and will then get released with Rust 1.96 on 2026-05-28. If you see any issues as a result of this fallout please don't hesitate to file an issue on rust-lang/rust.