# Hidden unsafe due to unintentionally abusable macros and include

**URL:** <https://internals.rust-lang.org/t/hidden-unsafe-due-to-unintentionally-abusable-macros-and-include/14107>\
**Category:** Unsafe Code Guidelines\
**Created:** [February 23, 2021, 5:40pm UTC](https://internals.rust-lang.org/t/hidden-unsafe-due-to-unintentionally-abusable-macros-and-include/14107 "2021-02-23T17:40:49Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![CTurt](https://avatars.discourse-cdn.com/v4/letter/c/c0e974/32.png) [@CTurt](https://internals.rust-lang.org/u/CTurt)\
**Post date:** [February 23, 2021, 5:40pm UTC](https://internals.rust-lang.org/t/hidden-unsafe-due-to-unintentionally-abusable-macros-and-include/14107/1 "2021-02-23T17:40:49Z")

</div>

I wanted to re-raise the discussions around preventing 'hidden unsafe', meaning Rust code in the `unsafe` dialect that doesn’t require the direct use of the `unsafe` keyword nearby.

It may be tempting to dismiss these concerns because the patterns are so contrived that they would never organically appear in non-malicious code, but the angle I’m coming from is that they could be used to hide subtle backdoors in Rust code (underhanded Rust contest anyone?).

I'm also not talking about hiding vulnerabilities in safe Rust code; obviously in a security review it’s not sufficient to just grep for `unsafe` to find vulnerabilities since safe code can be vulnerable too, but at least you would expect to find all of the unsafe Rust by doing this... otherwise, what’s the point of the keyword?

I’ve talked about `unsafe` macros being the main technique in a [previous thread](https://internals.rust-lang.org/t/explicitly-marking-unsafe-macro-expressions/9425), but it’s now closed, so I’m creating a new one so I can add new thoughts on an idea to combine this with the `include` built-in macro for more chaos.

Essentially, the simplest, shortest, ‘default’, way people use `expr` with `unsafe` in macros allows the `unsafe` block to spread, meaning that a malicious actor can use someone else's macro to hide their own `unsafe` statements without needing to introduce their own corresponding `unsafe` blocks.

A [clearer example](https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=b5d44239b87ff8dca034ba41993e2ff2) than originally shown (although there is some irony that some of the [initial replies](https://internals.rust-lang.org/t/explicitly-marking-unsafe-macro-expressions/9425/4) missed the hidden `get_unchecked` in the original example): if you naively create a `mmap` wrapper macro that takes a size, it allows any of the callers to hide their own unsafe code in the macro arguments without needing their own unsafe blocks:

Crate:

```
use libc::*;

#[macro_export]
macro_rules! alloc_pages {
    ($length:expr) => (
        unsafe {
            mmap(0 as *mut c_void, $length, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0)
        }
    );
}

```

Malicious code containing 'hidden unsafe’ (dereferencing an arbitrary pointer):

```
fn main() {
    // Intended use of library
    let p = alloc_pages!(0x4000);
    println!("{:p}", p);
    
    // Unsafely dereferencing raw pointer without using unsafe keyword!
    let p2 = alloc_pages!(*(0x41414141 as *mut usize));
    println!("{:p}", p2);
}

```

Again, this violates the idea that you can simply grep for `unsafe` to find all of the unsafe Rust in a project. Not only that, but it was [pointed out](https://internals.rust-lang.org/t/explicitly-marking-unsafe-macro-expressions/9425/10) that more advanced tools like Cargo-Geiger and even `#![forbid(unsafe_code)]` do not detect/forbid the hidden unsafe dereference. I can’t understand how anyone wouldn’t consider this a bug, but even assuming the possibility of the existence of ‘legitimate’ use-cases of this as a feature, should they really be prioritised over violating the ability to easily search for unsafe Rust? I think a breaking change is warranted.

I would like for that example to no longer compile, without an additional unsafe block:

```
alloc_pages!(unsafe { *(0x41414141 as *mut usize) } );

```

I believe there would be real appeal to hiding backdoors this way. If you are reviewing Rust code, it would be very easy to quickly assume certain lines are safe under the rationale that an `unsafe` keyword would be nearby if it were doing anything sketchy. For example, a variable assignment like `x = y` would look extremely innocuous if there were no `unsafe` keyword drawing attention to it, but if it happens to be against a global variable (disabling `#[warn(non_upper_case_globals)]` to disguise further) and this introduces an exploitable data race condition, this could be extremely easy for a review to miss.

It’s particularly annoying because Rust macros are supposed to be more sophisticated than in C where expressions are just ‘pasted’ and hope for the best. For example, Rust macros do solve the common C mistake where pasting an expression could lead to unintended order of operations; with an input like `1 + 2` a macro that does `input * 2` will always get `6`, as opposed to `5` like it may be in an equivalent C macro. Why can’t macros also be smarter against pasting code into `unsafe` blocks by default, essentially creating unintended implicit `unsafe` blocks everywhere?

I wanted to add a handful of real examples to back up that people do indeed write macros this way. I don’t blame these authors; I think the language is at fault here:

> <https://github.com/BurntSushi/byteorder/blob/0ead1057d4d1ea59ad9c8e5bc35514646ef8fb83/src/lib.rs#L1908>

> <https://github.com/cryptocorrosion/cryptocorrosion/blob/1eb8f4b6879cc41b130f1afe62c648b4ac1f3328/utils-simd/ppv-lite86/src/x86_64/sse2.rs#L783>

> <https://github.com/rust-random/rand/blob/736a6e06ce4f17a4935f53bfc93c0da9b1336f79/rand_core/src/impls.rs#L77>

These are all protected at least against external code introducing `unsafe` since they are not exposed via `#[macro_export]`.

Anyway, what I wanted to add to the discussion today is that the `include` macro has the potential to copy these macros into a context where they can be abused. The idea would be an attacker could `include` some ‘utils’ file from another library as an unusual and bad, but not overly suspicious from a security review, practice. They would then be able to abuse these macros, which were originally thought to be safe from abuse due to not being exposed, to introduce their own hidden unsafe. Again, if the unsafe code they introduce is as simple as a variable assignment that happens to be on a global, would you really be confident that a reviewer would spot that without an `unsafe` keyword nearby?

Fortunately(?) I couldn’t get the `include` macro to work against source files that happen to contain documentation, which covers the 3 examples I listed above - but this definitely shouldn’t be considered as any kind of durable mitigation, and I think the idea still has potential (and we should consider solutions). [Playground](https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=29d12e17c1ce5d61a4d6b1c57a34ac28):

```
use rand_core; // 0.6.2
include!("/playground/.cargo/registry/src/github.com-1ecc6299db9ec823/rand_core-0.6.2/src/impls.rs");

```

(In the context of a malicious library, Cargo thankfully standardizes library directory structure, and so we can just use a predictable relative path to another library `"../../rand_core-0.6.2/src/impls.rs"` instead).

```
error[E0753]: expected outer doc comment
 --> src/../.cargo/registry/src/github.com-1ecc6299db9ec823/rand_core-0.6.2/src/impls.rs:9:1
  |
9 | //! Helper functions for implementing `RngCore` functions.
  | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  |
  = note: inner doc comments like this (starting with `//!` or `/*!`) can only appear before items

```

There may be a bunch of other unscrupulous opportunities for `include` to activate potentially unreviewed code such as a non-code file like the LICENSE that obviously won’t have been reviewed as Rust code. What would be truly evil would be to have a documentation file “Unsafe guidelines” that contains examples of unsafe Rust, but is crafted to be a fully valid Rust source file and can be subtly `include`d and abused deep in some ‘util’ macro in another crate.

UPDATE: I managed to find a crate that doesn't have documentation, so isn't affected by the above compiler error. I was able to produce a [working Playground demo](https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=9964142b6a9e45c206c9bfea8dbf5195) for the `include!` idea - gaining access to unsound macros that are not supposed to be exposed, and then abusing them to introduce unsafe behavior (accessing global mutable without our own `unsafe` block). This macro was just using `ident` instead of `expr` so we can't introduce arbitrary code, but I think it's still interesting.

---

<div class="post-metadata">

**Author:** ![RustyYato](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/rustyyato/32/13627_2.png) [@RustyYato](https://internals.rust-lang.org/u/RustyYato)\
**Post date:** [February 23, 2021, 5:56pm UTC](https://internals.rust-lang.org/t/hidden-unsafe-due-to-unintentionally-abusable-macros-and-include/14107/2 "2021-02-23T17:56:15Z")

</div>

~~Sticking the include into a module will subvert outer doc comments,~~

```rust
mod dummy {
    include!("sus file path");
}

```

edit: nvm, this doesn't work

---

<div class="post-metadata">

**Author:** ![mjbshaw](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/mjbshaw/32/5103_2.png) [@mjbshaw](https://internals.rust-lang.org/u/mjbshaw)\
**Post date:** [February 23, 2021, 6:04pm UTC](https://internals.rust-lang.org/t/hidden-unsafe-due-to-unintentionally-abusable-macros-and-include/14107/3 "2021-02-23T18:04:40Z")

</div>

If I'm understanding this correctly, is this basically "unsafe hygiene" for macros?

---

<div class="post-metadata">

**Author:** ![CTurt](https://avatars.discourse-cdn.com/v4/letter/c/c0e974/32.png) [@CTurt](https://internals.rust-lang.org/u/CTurt)\
**Post date:** [February 23, 2021, 6:09pm UTC](https://internals.rust-lang.org/t/hidden-unsafe-due-to-unintentionally-abusable-macros-and-include/14107/4 "2021-02-23T18:09:46Z")

</div>

Unfortunately it seems to give the same error. [Playground](https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=25713e4dc90d4e95dd1977d071f9b049).

---

<div class="post-metadata">

**Author:** ![CTurt](https://avatars.discourse-cdn.com/v4/letter/c/c0e974/32.png) [@CTurt](https://internals.rust-lang.org/u/CTurt)\
**Post date:** [February 23, 2021, 6:29pm UTC](https://internals.rust-lang.org/t/hidden-unsafe-due-to-unintentionally-abusable-macros-and-include/14107/5 "2021-02-23T18:29:46Z")

</div>

I would like for the `mmap` example ([playground](https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=b5d44239b87ff8dca034ba41993e2ff2)) to not compile because there is unsafe code (dereferencing raw pointer) without an `unsafe` block, this is an unintentional abuse of the macro (which could be someone else's code in a different crate).

---

<div class="post-metadata">

**Author:** ![toc](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/toc/32/6692_2.png) [@toc](https://internals.rust-lang.org/u/toc)\
**Post date:** [February 23, 2021, 6:53pm UTC](https://internals.rust-lang.org/t/hidden-unsafe-due-to-unintentionally-abusable-macros-and-include/14107/6 "2021-02-23T18:53:14Z")

</div>

Would it be enough (or at least a start) to lint/warn against macro expansion inside unsafe blocks? Assuming the macro is being written in good faith it should be written:

```rust
#[macro_export]
macro_rules! alloc_pages {
    ($length:expr) => ({
        let n = $length;
        unsafe {
            mmap(0 as *mut c_void, n, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0)
        }
    });
}

```

As far as I know there's not easy way (at macro expansion time) to detect that `*(0x41414141 as *mut usize)` is unsafe because the macro could be interpreting that token stream to mean _anything_. I would probably most prefer to write the example macro as:

```rust
#[macro_export]
macro_rules! alloc_pages {
    ($length:expr) => ({
        mmap(0 as *mut c_void, $length, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0)
    });
}

```

To require invoking it as `unsafe { alloc_pages!(*(0x41414141 as *mut usize)) };`. But I understand that may not apply to more complex usage.

---

<div class="post-metadata">

**Author:** ![CTurt](https://avatars.discourse-cdn.com/v4/letter/c/c0e974/32.png) [@CTurt](https://internals.rust-lang.org/u/CTurt)\
**Post date:** [February 23, 2021, 7:09pm UTC](https://internals.rust-lang.org/t/hidden-unsafe-due-to-unintentionally-abusable-macros-and-include/14107/8 "2021-02-23T19:09:56Z")

</div>

Slight nit, invoking the macro itself isn't/shouldn't be the `unsafe` thing here, it's specific to the expression passed in the argument, so to reduce the size of the `unsafe` block and be most explicit this would be optimal use in my opinion:

```rust
alloc_pages!(unsafe { *(0x41414141 as *mut usize) } );

```

---

<div class="post-metadata">

**Author:** ![atagunov](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/atagunov/32/5877_2.png) [@atagunov](https://internals.rust-lang.org/u/atagunov)\
**Post date:** [February 23, 2021, 7:28pm UTC](https://internals.rust-lang.org/t/hidden-unsafe-due-to-unintentionally-abusable-macros-and-include/14107/9 "2021-02-23T19:28:18Z")

</div>

Is it the right answer to

- `color` code blocks inside `unsafe`
- carry over code `color` when substituting values inside a macro
- not allow un-`colored` code inside `unsafe` after macro expansion

.

- opt-in to this check via a `rustc` flag initially

?

---

<div class="post-metadata">

**Author:** ![bascule](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/bascule/32/3057_2.png) [@bascule](https://internals.rust-lang.org/u/bascule)\
**Post date:** [February 23, 2021, 7:42pm UTC](https://internals.rust-lang.org/t/hidden-unsafe-due-to-unintentionally-abusable-macros-and-include/14107/10 "2021-02-23T19:42:09Z")

</div>

This is something that bothers me as well, particularly in the context of `#![forbid(unsafe_code)]`, which still allows crate-local unsafe code via these "escape hatches", and therefore provides a misleading sense of what it actually does.

See also unsafe attributes which work in a `#![forbid(unsafe_code)]` context, e.g. `#[no_mangle]` (and there are many more than that).

Perhaps at an edition boundary `#![forbid(unsafe_code)]` could be changed to disallow all of these as well.

Or perhaps things could be take a step farther: at an edition boundary, `#![allow(unsafe_code)]` could be required to enable them, as was proposed before here:

> [@Disabling 'unsafe' by default](https://internals.rust-lang.org/t/disabling-unsafe-by-default/7988):
>
> [This discussion](https://www.reddit.com/r/rust/comments/8zpp5f/auditing_popular_crates_how_a_oneline_unsafe_has/e2lbp7g) on reddit got me thinking got me thinking about making the usage of unsafe more restricted. I think a reasonable case can be made for switching from “always allow unsafe unless #![forbid(unsafe\_code)] is specified” to "always deny unsafe unless #![allow(unsafe\_code)] is specified. Would it make sense to write an RFC for this? Pro Allowing the availability of unsafe to be tied to features or other attributes This allows for users to: only allow the usage of unsafe when a spec…

---

<div class="post-metadata">

**Author:** ![scottmcm](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/scottmcm/32/2355_2.png) [@scottmcm](https://internals.rust-lang.org/u/scottmcm)\
**Post date:** [February 23, 2021, 7:52pm UTC](https://internals.rust-lang.org/t/hidden-unsafe-due-to-unintentionally-abusable-macros-and-include/14107/11 "2021-02-23T19:52:05Z")

</div>

> [@bascule](#):
>
> See also unsafe attributes which work in a `#![forbid(unsafe_code)]` context, e.g. `#[no_mangle]` (and there are many more than that).

This specific example is fixed on nightly:

> <https://github.com/rust-lang/rust/pull/72209>
>
> fixes #72188 
> 
> r? @estebank

Which implies that updates to do the same for other such constructs would likely be accepted too.

---

<div class="post-metadata">

**Author:** ![CAD97](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/cad97/32/3460_2.png) [@CAD97](https://internals.rust-lang.org/u/CAD97)\
**Post date:** [February 23, 2021, 11:28pm UTC](https://internals.rust-lang.org/t/hidden-unsafe-due-to-unintentionally-abusable-macros-and-include/14107/12 "2021-02-23T23:28:47Z")

</div>

I think making `macro_rules!` respect hygiene with respect to `unsafe`ty is a reasonable change for an upcoming edition (or at the very least `macro` macros, "macros 2.0").

(And I argued against the plutonium advisory, in favor of the `safe!` macro (which is just aliased `unsafe`).)

Given that it's purely safe code to `rm -rf / --no-preserve-root`, though, I don't think "finding potentially malicious code with `rg unsafe`" is a good argument for it.

---

<div class="post-metadata">

**Author:** ![kornel](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/kornel/32/2711_2.png) [@kornel](https://internals.rust-lang.org/u/kornel)\
**Post date:** [February 24, 2021, 3:21pm UTC](https://internals.rust-lang.org/t/hidden-unsafe-due-to-unintentionally-abusable-macros-and-include/14107/13 "2021-02-24T15:21:29Z")

</div>

You _can't_ rely on the `unsafe` keyword to check safety of crates. There are many other "safe" ways to inject arbitrary code and evade the checks:

> [@About supply-chain attacks](https://internals.rust-lang.org/t/about-supply-chain-attacks/14038/6):
>
> Regarding forbidding unsafe, I think it's commonly overestimated how much it would help, and underestimated how difficult it is to implement and how damaging it would be to the ecosystem. Rust would have to create a new, much bigger concept of "unsafe", because: std::process::Command is safe #[no\_mangle] is safe #[link\_section] is safe #[export\_name] is safe #[link(…)] extern "C" {} is safe println!("cargo:rustc-link-lib=native=…") is safe proc-macros are safe, and turing-complete, and …

This is because `unsafe` is not a security boundary. It's a lint for double-checking programmer's own assumptions, and not a sandbox.

---

<div class="post-metadata">

**Author:** ![CTurt](https://avatars.discourse-cdn.com/v4/letter/c/c0e974/32.png) [@CTurt](https://internals.rust-lang.org/u/CTurt)\
**Post date:** [February 24, 2021, 3:38pm UTC](https://internals.rust-lang.org/t/hidden-unsafe-due-to-unintentionally-abusable-macros-and-include/14107/14 "2021-02-24T15:38:52Z")

</div>

> [@CAD97](#):
>
> Given that it's purely safe code to `rm -rf / --no-preserve-root` , though, I don't think "finding potentially malicious code with `rg unsafe` " is a good argument for it.

> [@](#):
>
> You _can't_ rely on the `unsafe` keyword to check safety of crates. There are many other "safe" ways to inject arbitrary code and evade the checks:

Agreed, I never claimed to rely on grepping for `unsafe` to be sufficient for a review. I specifically addressed that hiding vulnerabilities in safe Rust is obviously possible, but it's not relevant to this discussion.

> [@CTurt](#):
>
> I'm also not talking about hiding vulnerabilities in safe Rust code; obviously in a security review it’s not sufficient to just grep for `unsafe` to find vulnerabilities, but at least you would expect to find all of the unsafe Rust by doing this... otherwise, what’s the point of the keyword?

The idea is that because Rust makes this useful distinction between safe and unsafe dialects, as a reviewer I would assume that Rust code isn't doing certain things if there is no `unsafe` block nearby, since the language is supposed to forbid this. For example, I would assume that a line such as `x = y` isn't assigning to a global variable if it's not inside an `unsafe` block, but using this trick it could. This concept of 'hidden unsafe' provides opportunities to create significantly harder to spot backdoors than with safe Rust.

---

<div class="post-metadata">

**Author:** ![kornel](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/kornel/32/2711_2.png) [@kornel](https://internals.rust-lang.org/u/kornel)\
**Post date:** [February 24, 2021, 3:42pm UTC](https://internals.rust-lang.org/t/hidden-unsafe-due-to-unintentionally-abusable-macros-and-include/14107/15 "2021-02-24T15:42:26Z")

</div>

But there's lots of "hidden" unsafe everywhere. `vec.push(x)` contains hidden unsafe. Why `push!(vec, x)` shouldn't be allowed to?

---

<div class="post-metadata">

**Author:** ![CTurt](https://avatars.discourse-cdn.com/v4/letter/c/c0e974/32.png) [@CTurt](https://internals.rust-lang.org/u/CTurt)\
**Post date:** [February 24, 2021, 3:44pm UTC](https://internals.rust-lang.org/t/hidden-unsafe-due-to-unintentionally-abusable-macros-and-include/14107/16 "2021-02-24T15:44:28Z")

</div>

The key point is that we're introducing completely _new_ `unsafe` code without an unsafe block, not calling existing `unsafe` code that has been thoroughly reviewed. The difference between my example and yours should be clear - you can't use `push!` to introduce _new_ `unsafe`:

```rust
alloc_pages!(*(0x41414141 as *mut usize));

```

```
push!(vec, x)

```

To introduce the dereference here a new `unsafe` block would be required, which is a good thing:

```
push!(vec, unsafe { *(0x41414141 as *mut usize) })
```

---

<div class="post-metadata">

**Author:** ![kornel](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/kornel/32/2711_2.png) [@kornel](https://internals.rust-lang.org/u/kornel)\
**Post date:** [February 24, 2021, 3:47pm UTC](https://internals.rust-lang.org/t/hidden-unsafe-due-to-unintentionally-abusable-macros-and-include/14107/17 "2021-02-24T15:47:26Z")

</div>

Maybe Rust should support `unsafe macro_rules!` to let people write macros that aren't safe to call?

---

<div class="post-metadata">

**Author:** ![CTurt](https://avatars.discourse-cdn.com/v4/letter/c/c0e974/32.png) [@CTurt](https://internals.rust-lang.org/u/CTurt)\
**Post date:** [February 24, 2021, 3:49pm UTC](https://internals.rust-lang.org/t/hidden-unsafe-due-to-unintentionally-abusable-macros-and-include/14107/18 "2021-02-24T15:49:24Z")

</div>

It absolutely is different, as a function, the code in `alloc_pages` is self contained and can theoretically be reviewed for upholding safety for all inputs. As a macro, arbitrary _new_ `unsafe` code can be inserted, which obviously won't be caught in a review of the crate since the code isn't there to be seen; in the context of reviewing the consumer of the macro, it would be very difficult for a reviewer to spot as there's no `unsafe` block showing that it's using the unsafe dialect.

---

<div class="post-metadata">

**Author:** ![kornel](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/kornel/32/2711_2.png) [@kornel](https://internals.rust-lang.org/u/kornel)\
**Post date:** [February 24, 2021, 3:50pm UTC](https://internals.rust-lang.org/t/hidden-unsafe-due-to-unintentionally-abusable-macros-and-include/14107/19 "2021-02-24T15:50:59Z")

</div>

edit: nevermind, I misunderstood the issue

---

<div class="post-metadata">

**Author:** ![mjbshaw](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/mjbshaw/32/5103_2.png) [@mjbshaw](https://internals.rust-lang.org/u/mjbshaw)\
**Post date:** [February 24, 2021, 3:58pm UTC](https://internals.rust-lang.org/t/hidden-unsafe-due-to-unintentionally-abusable-macros-and-include/14107/20 "2021-02-24T15:58:39Z")

</div>

This is about safety hygiene in macros. It seems like a reasonable request, IMO. I see it as more of an exercise in _intentional_ unsafety. _Of course_ there are a large number of opportunities for bad things to happen. Just because I can "safely" exec `rm -rf` doesn't mean that `unsafe` is now totally worthless. `unsafe` has its purposes. And I think it's worth being _intentional_ when it comes to using `unsafe`.

But there's been a lot of rapid back-and-forth here. I think it's worth taking a little break to slow things down so responses can be more methodical.

---

<div class="post-metadata">

**Author:** ![burntsushi](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/burntsushi/32/279_2.png) [@burntsushi](https://internals.rust-lang.org/u/burntsushi)\
**Post date:** [February 24, 2021, 3:59pm UTC](https://internals.rust-lang.org/t/hidden-unsafe-due-to-unintentionally-abusable-macros-and-include/14107/21 "2021-02-24T15:59:49Z")

</div>

Look at the macro defined in the byteorder crate. It is not safe to call for all possible arguments. Merely, all such uses of it in the module are safe. If that macro could be defined as a function and it wasn't defined with `unsafe`, then we would call it unsound.

Perhaps the macro should not write the unsafe block itself and instead require the caller to do it. But this is a sub-optimal work-around.

[Next page](https://internals.rust-lang.org/t/hidden-unsafe-due-to-unintentionally-abusable-macros-and-include/14107.md?page=2)
