04 Jul 2025

feedPlanet Mozilla

Steve Fink: Effectful Logging

These recent blog posts are veering in the "here's a horrible thing I just did!" direction. No apologies. Recently, I was working on a weird problem where I wanted to snapshot /proc/$pid/maps before and after a couple of mmap and madvise calls. But I didn't particularly want to write C++ code to do it. So: […]

04 Jul 2025 2:02am GMT

Don Marti: practical tips for limiting web tracking

From the California Privacy Protection Agency: Understanding Website Tracking and How to Limit It by Tom Kemp.

A good start, but I understand that a state agency can't recommend specific software, and the surveillance business has changed tactics quite a bit recently. So here are some related links and comments. Remember, privacy is a cooperative project. Even if you're not the intended victim of an attack using data broker data, anything you can do to protect your info is going to limit the amount of training that surveillance AI can do, which will help keep other people safer.

0. Use the web

The reason that so many privacy tips are about the web is not that the web is especially bad for privacy, it's that the web is a medium where you still have enough control to make a difference. Companies don't try to get you to click it's better in the app because the app is better, they want to be able to use a communications medium where tracking is easier and privacy tools are harder. Please don't let the existence of web privacy tools and web privacy tips scare you away from the web.

Step zero is to remove the Meta apps-Facebook, Instagram, and Whatsapp-if you can. Researchers recently spotted Meta doing a horribly complex surveillance trick called "Localhost tracking" to bypass security protections on Android phones. Although they stopped doing this particular technique, as long as the Meta apps are on your phone it's just a matter of time until they figure out the next one.

1. Delete browsing data

This is out of date: If you don't want personalized ads based on past website visits, you can delete cookies within your browser and clear your search and browsing history. A lot of web tracking now uses unintended identification techniques that are harder to manage than cookies. Personally I skip this step. Clearing cookies will still have some effect, but the workarounds are too widely deployed by now.

2. Customize your privacy settings.

The FTC site linked to here is out of date (as you might expect, given the political situation). I have what should be current info for some of the browsers.

3. Review privacy notices and tracker settings

Reading privacy policies is a waste of time. A company's privacy policy is just a list of whatever creepy stuff their lawyer's other clients got caught doing. You can click the Do not sell or share my personal information link at the bottom of a page, but a lot of the time it's not hooked up to all of the data processing the company does, or the software that handles it is broken. (The state of California is catching some of these but it's a long process.) A time-saving approach is Global Privacy Control (see step 6). No more reliable than manually clicking do not sell but way more impact for the time spent.

4. Opt out of audience-matched advertising

This is a good one and can have real impact. (It will even make you buy better stuff and be happier.) Here's how to fix the Google and Meta personalized ad settings.

5. Consider privacy-centric plug-ins or privacy-focused browsers using an ad blocker

This is a tricky tip to do for a public sector site. The FBI recommends an ad blocker, too, but it looks like the government can't link to a specific tool. The problem is that the ad blocker scene is a wretched hive of scum and villainy. Many of the ad blockers you will find by searching the online reviews or browser extension directories are malware, adware, or have a paid allow-listing scheme. Installing a random ad blocker would likely make you worse off, privacy-wise.

A known honest ad blocker is uBlock Origin. It will handle the ads in Google Search, which are the FBI's concern. If you visit legit ad-supported sites, you can turn it off for just those sites while staying protected from trackers elsewhere.

6. Enable an opt-out preference signal on your browser

Another good tip, currently easier to do on some browsers than others. My Firefox instructions under step 2 already have this one.

Related

The web is pretty good, privacy-wise. Other places, not so much. Here are some effective privacy tips that also cover tools and actions for other places.

Bonus links

Zelle needs to fix 'significant scams and fraud,' lawmakers say by Emma Roth. In an attempt to protect its customers, Chase began blocking Zelle payments over social media, where scams often show up, last February. (One more reason to delete those Meta apps, if you need one.)

Nearly 30 % of All Bullsh-t Online Is Health Related by John Battelle. I've been skeptical of the claims made by the tech and AI industry as LLMs and chatbots begin to take over nearly every aspect of the Internet as we've known it. My conversation with Brill and Crovitz only deepened my skepticism. (This problem is only going to get worse as legit sites do more to try to keep their content out of LLM training sets and disinfo sites do more to try to get their content in)

One of the Biggest Obstacles to Building New CA Housing Has Now Vanished by Ben Christopher. With the passage of a state budget-related housing bill, the California Environmental Quality Act will be a non-issue for a decisive swath of urban residential development in California.

Burner Phone 101 at the Brooklyn Public Library Burner phones are low-cost, prepaid devices used to preserve privacy in temporary situations. They're not just for activists. More and more people are using them to avoid surveillance, unplug, and compartmentalize their lives.

Eroding America from within: Marketing data threatens military cohesion by By Maj. Jessica Dawson and Lt. Col. Todd Arnold. The troves of intricately detailed information collected by online and social media companies were used to target disinformation campaigns (a.k.a., story weapons), and yet, much of the broader national defense strategy fails to acknowledge this actively exploited force protection vulnerability. There are currently no provisions in law or force structure to actively assess this vulnerability, nor to defend against it.

04 Jul 2025 12:00am GMT

03 Jul 2025

feedPlanet Mozilla

The Rust Programming Language Blog: Stabilizing naked functions

Rust 1.88.0 stabilizes the #[unsafe(naked)] attribute and the naked_asm! macro which are used to define naked functions.

A naked function is marked with the #[unsafe(naked)] attribute, and its body consists of a single naked_asm! call. For example:

/// SAFETY: Respects the 64-bit System-V ABI.
#[unsafe(naked)]
pub extern "sysv64" fn wrapping_add(a: u64, b: u64) -> u64 {
    // Equivalent to `a.wrapping_add(b)`.
    core::arch::naked_asm!(
        "lea rax, [rdi + rsi]",
        "ret"
    );
}

What makes naked functions special - and gives them their name - is that the handwritten assembly block defines the entire function body. Unlike non-naked functions, the compiler does not add any special handling for arguments or return values.

This feature is a more ergonomic alternative to defining functions using global_asm!. Naked functions are used in low-level settings like Rust's compiler-builtins, operating systems, and embedded applications.

Why use naked functions?

But wait, if naked functions are just syntactic sugar for global_asm!, why add them in the first place?

To see the benefits, let's rewrite the wrapping_add example from the introduction using global_asm!:

// SAFETY: `wrapping_add` is defined in this module,
// and expects the 64-bit System-V ABI.
unsafe extern "sysv64" {
    safe fn wrapping_add(a: u64, b: u64) -> u64
}

core::arch::global_asm!(
    r#"
        // Platform-specific directives that set up a function.
        .section .text.wrapping_add,"ax",@progbits
        .p2align 2
        .globl wrapping_add
        .type wrapping_add,@function

wrapping_add:
        lea rax, [rdi + rsi]
        ret

.Ltmp0:
        .size wrapping_add, .Ltmp0-wrapping_add
    "#
);

The assembly block starts and ends with the directives (.section, .p2align, etc.) that are required to define a function. These directives are mechanical, but they are different between object file formats. A naked function will automatically emit the right directives.

Next, the wrapping_add name is hardcoded, and will not participate in Rust's name mangling. That makes it harder to write cross-platform code, because different targets have different name mangling schemes (e.g. x86_64 macOS prefixes symbols with _, but Linux does not). The unmangled symbol is also globally visible - so that the extern block can find it - which can cause symbol resolution conflicts. A naked function's name does participate in name mangling and won't run into these issues.

A further limitation that this example does not show is that functions defined using global assembly cannot use generics. Especially const generics are useful in combination with assembly.

Finally, having just one definition provides a consistent place for (safety) documentation and attributes, with less risk of them getting out of date. Proper safety comments are essential for naked functions. The naked attribute is unsafe because the ABI (sysv64 in our example), the signature, and the implementation have to be consistent.

How did we get here?

Naked functions have been in the works for a long time.

The original RFC for naked functions is from 2015. That RFC was superseded by RFC 2972 in 2020. Inline assembly in Rust had changed substantially at that point, and the new RFC limited the body of naked functions to a single asm! call with some additional constraints. And now, 10 years after the initial proposal, naked functions are stable.

Two additional notable changes helped prepare naked functions for stabilization:

Introduction of the naked_asm! macro

The body of a naked function must be a single naked_asm! call. This macro is a blend between asm! (it is in a function body) and global_asm! (only some operand types are accepted).

The initial implementation of RFC 2972 added lints onto a standard asm! call in a naked function. This approach made it hard to write clear error messages and documentation. With the dedicated naked_asm! macro the behavior is much easier to specify.

Lowering to global_asm!

The initial implementation relied on LLVM to lower functions with the naked attribute for code generation. This approach had two issues:

The implementation that is stabilized now instead converts the naked function into a piece of global assembly. The code generation backends can already emit global assembly, and this strategy guarantees that the whole body of the function is just the instructions that the user wrote.

What's next for assembly?

We're working on further assembly ergonomics improvements. If naked functions are something you are excited about and (may) use, we'd appreciate you testing these new features and providing feedback on their designs.

extern "custom" functions

Naked functions usually get the extern "C" calling convention. But often that calling convention is a lie. In many cases, naked functions don't implement an ABI that Rust knows about. Instead they use some custom calling convention that is specific to that function.

The abi_custom feature adds extern "custom" functions and blocks, which allows us to correctly write code like this example from compiler-builtins:

#![feature(abi_custom)]

/// Division and modulo of two numbers using Arm's nonstandard ABI.
///
/// ```c
/// typedef struct { int quot; int rem; } idiv_return;
///  __value_in_regs idiv_return __aeabi_idivmod(int num, int denom);
/// ```
// SAFETY: The assembly implements the expected ABI, and "custom"
// ensures this function cannot be called directly.
#[unsafe(naked)]
pub unsafe extern "custom" fn __aeabi_idivmod() {
    core::arch::naked_asm!(
        "push {{r0, r1, r4, lr}}", // Back up clobbers.
        "bl {trampoline}",         // Call an `extern "C"` function for a / b.
        "pop {{r1, r2}}",
        "muls r2, r2, r0",         // Perform the modulo.
        "subs r1, r1, r2",
        "pop {{r4, pc}}",          // Restore clobbers, implicit return by setting `pc`.
        trampoline = sym crate::arm::__aeabi_idiv,
    );
}

A consequence of using a custom calling convention is that such functions cannot be called using a Rust call expression; the compiler simply does not know how to generate correct code for such a call. Instead the compiler will error when the program does try to call an extern "custom" function, and the only way to execute the function is using inline assembly.

cfg on lines of inline assembly

The cfg_asm feature adds the ability to annotate individual lines of an assembly block with #[cfg(...)] or #[cfg_attr(..., ...)]. Configuring specific sections of assembly is useful to make assembly depend on, for instance, the target, target features, or feature flags. For example:

#![feature(cfg_asm)]

global_asm!(
    // ...

    // If enabled, initialise the SP. This is normally
    // initialised by the CPU itself or by a bootloader, but
    // some debuggers fail to set it when resetting the
    // target, leading to stack corruptions.
    #[cfg(feature = "set-sp")]
    "ldr r0, =_stack_start
     msr msp, r0",

     // ...
)

This example is from the cortex-m crate that currently has to use a custom macro that duplicates the whole assembly block for every use of #[cfg(...)]. With cfg_asm, that will no longer be necessary.

03 Jul 2025 12:00am GMT