Skip to content

Thread names are not always valid UTF-8 #123495

Closed
@joboet

Description

@joboet

Thread (or well Inner) has the following invariant:

name: Option<CString>, // Guaranteed to be UTF-8

and relies on it for soundness:
self.cname().map(|s| unsafe { str::from_utf8_unchecked(s.to_bytes()) })

Starting with #121666, this invariant can be broken, because the native thread names are not required to be UTF-8. So for example, this code is unsound:

use std::mem::MaybeUninit;
use std::ptr;
use std::thread;

extern "C" fn foreign(_arg: *mut libc::c_void) -> *mut libc::c_void {
    unsafe {
        let id = libc::pthread_self();
        let r = libc::pthread_setname_np(id, [0xff, 0].as_ptr().cast());
        assert_eq!(r, 0);
    }

    let current = thread::current();
    println!("{:?}", current.name().unwrap().chars()); // Whoops!

    ptr::null_mut()
}

fn main() {
    unsafe {
        let mut id = MaybeUninit::uninit();
        let r = libc::pthread_create(id.as_mut_ptr(), ptr::null(), foreign, ptr::null_mut());
        assert_eq!(r, 0);
        let id = id.assume_init();
        let r = libc::pthread_join(id, ptr::null_mut());
        assert_eq!(r, 0);
    }
}

(run with miri and --target x86_64-unknown-linux-gnu)

This can even be exploited in entirely safe code. On platforms with key-based thread locals, the Thread handle is initialized with the system thread name when accessed in TLS destructors. On all UNIXes except macOS, the main thread name is the name of the program. So if you spawn a program with a bad name on these platforms (e.g. Illumos), calling thread::current().name() will cause UB.

We can fix this by checking the thread name in Thread::new, and not using it if it is bad. In the long-term, a function like os_name might be nice and perhaps fix some other issues as well.

CC @ChrisDenton

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-threadArea: `std::thread`C-bugCategory: This is a bug.I-unsoundIssue: A soundness hole (worst kind of bug), see: https://en.wikipedia.org/wiki/SoundnessT-libsRelevant to the library team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions