Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enforce that layout size fits in isize in Layout #95295

Merged
merged 4 commits into from
Jul 10, 2022

Conversation

CAD97
Copy link
Contributor

@CAD97 CAD97 commented Mar 25, 2022

As it turns out, enforcing this in APIs that already enforce usize overflow is fairly trivial. Layout::from_size_align_unchecked continues to "allow" sizes which (when rounded up) would overflow isize, but these are now declared as library UB for Layout, meaning that consumers of Layout no longer have to check this before making an allocation.

(Note that this is "immediate library UB;" IOW it is valid for a future release to make this immediate "language UB," and there is an extant patch to do so, to allow Miri to catch this misuse.)

See also #95252, Zulip discussion.
Fixes #95334

Some relevant quotes:

@eddyb, #95252 (comment)

[B]ecause of the non-trivial presence of both of these among code published on e.g. crates.io:

  1. Layout "producers" / GlobalAlloc "users": smart pointers (including alloc::rc copies with small tweaks), collections, etc.
  2. Layout "consumers" / GlobalAlloc "providers": perhaps fewer of these, but anything built on top of OS APIs like mmap will expose > isize::MAX allocations (on 32-bit hosts) if they lack extra checks

IMO the only responsible option is to enforce the isize::MAX limit in Layout, which:

  • makes Layout sound in terms of only ever allowing allocations where (alloc_base_ptr: *mut u8).offset(size) is never UB
  • frees both "producers" and "consumers" of Layout from manually reimplementing the checks
    • manual checks can be risky, e.g. if the final size passed to the allocator isn't the one being checked
    • this applies retroactively, fixing the overall soundness of existing code with zero transition period or any changes required from users (as long as going through Layout is mandatory, making a "choke point")

Feel free to quote this comment onto any relevant issue, I might not be able to keep track of developments.

@Gankra, #95252 (comment)

As someone who spent way too much time optimizing libcollections checks for this stuff and tried to splatter docs about it everywhere on the belief that it was a reasonable thing for people to manually take care of: I concede the point, it is not reasonable. I am wholy spiritually defeated by the fact that liballoc of all places is getting this stuff wrong. This isn't throwing shade at the folks who implemented these Rc features, but rather a statement of how impractical it is to expect anyone out in the wider ecosystem to enforce them if some of the most audited rust code in the library that defines the very notion of allocating memory can't even reliably do it.

We need the nuclear option of Layout enforcing this rule. Code that breaks this rule is deeply broken and any "regressions" from changing Layout's contract is a correctness fix. Anyone who disagrees and is sufficiently motivated can go around our backs but the standard library should 100% refuse to enable them.

cc also @RalfJung @rust-lang/wg-allocators. Even though this technically supersedes #95252, those potential failure points should almost certainly still get nicer panics than just "unwrap failed" (which they would get by this PR).

It might additionally be worth recommending to users of the Layout API that they should ideally use .and_then/? to complete the entire layout calculation, and then panic! from a single location at the end of Layout manipulation, to reduce the overhead of the checks and optimizations preserving the exact location of each panic which are conceptually just one failure: allocation too big.

Probably deserves a T-lang and/or T-libs-api FCP (this technically solidifies the objects must be no larger than isize::MAX rule further, and the UCG document says this hasn't been RFCd) and a crater run. Ideally, no code exists that will start failing with this addition; if it does, it was likely (but not certainly) causing UB.

Changes the raw_vec allocation path, thus deserves a perf run as well.

I suggest hiding whitespace-only changes in the diff view.

@rust-highfive
Copy link
Collaborator

r? @joshtriplett

(rust-highfive has picked a reviewer for you, use r? to override)

@rust-highfive rust-highfive added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Mar 25, 2022
@CAD97
Copy link
Contributor Author

CAD97 commented Mar 25, 2022

Let's see if I remember how to do this...

@rustbot label: +A-allocators +A-layout +needs-fcp +T-lang +T-libs-api

(I think those are all relevant, feel free to fix up)

@rustbot rustbot added A-allocators Area: Custom and system allocators A-layout Area: Memory layout of types needs-fcp This change is insta-stable, so needs a completed FCP to proceed. T-lang Relevant to the language team, which will review and decide on the PR/issue. T-libs-api Relevant to the library API team, which will review and decide on the PR/issue. labels Mar 25, 2022
@rust-log-analyzer

This comment has been minimized.

@eddyb
Copy link
Member

eddyb commented Mar 25, 2022

Ideally, no code exists that will start failing with this addition;

Sadly, I don't think we can spot this on crater, isn't it x86_64-only?
(I first suspected something like this on 32-bit targets, but I could never come up with an exploit)

@CAD97
Copy link
Contributor Author

CAD97 commented Mar 25, 2022

So... we currently don't enforce the isize::MAX limit in raw_vec for 64+ bit platforms, and instead just rely on the platform allocator failing:

// On 16/32-bit, we check that allocations don't exceed isize::MAX,
// on 64-bit, we assume the OS will give an OOM for such a ridiculous size.
// Any platform that succeeds for these requests is technically broken with
// ptr::offset because LLVM is the worst.

// We need to guarantee the following:
// * We don't ever allocate `> isize::MAX` byte-size objects.
// * We don't overflow `usize::MAX` and actually allocate too little.
//
// On 64-bit we just need to check for overflow since trying to allocate
// `> isize::MAX` bytes will surely fail. On 32-bit and 16-bit we need to add
// an extra guard for this in case we're running on a platform which can use
// all 4GB in user-space, e.g., PAE or x32.
#[inline]
fn alloc_guard(alloc_size: usize) -> Result<(), TryReserveError> {
if usize::BITS < 64 && alloc_size > isize::MAX as usize {
Err(CapacityOverflow.into())
} else {
Ok(())
}
}

This PR would replace alloc_guard by having already caught > isize::MAX sizes (on all platforms) when Layout::array::<T>() was called (in the generic path)... I think. I'm unsure of the exact behavior reading the raw_alloc code right now.

@CAD97
Copy link
Contributor Author

CAD97 commented Mar 25, 2022

This changes the allocation path in raw_vec, so is thus perf-sensitive. Notably, alloc_guard skipped the isize::MAX check on 64+ bit platforms (see above), and this is now not only done, but done in the generic path.

@bors rollup=never

@bors
Copy link
Contributor

bors commented Mar 25, 2022

@CAD97: 🔑 Insufficient privileges: not in try users

@CAD97
Copy link
Contributor Author

CAD97 commented Mar 25, 2022

I'm done tweaking this for the time being, but if this does turn out to be a perf impact, this can possibly be improved by changing

let new_layout = Layout::array::<T>(cap);
finish_grow(new_layout, self.current_memory(), &mut self.alloc);

to

let t_layout = Layout::<T>::new();
finish_grow(t_layout, cap, self.current_memory(), &mut self.alloc);

and doing Layout::repeat inside finish_grow, to move all of the dynamic alloc size checks inside the non-generic path.

@CAD97
Copy link
Contributor Author

CAD97 commented Mar 25, 2022

(Also noting this here, not just in the Zulip: GlobalAlloc::realloc and alloc::realloc do not put an isize maximum on new_size. All other allocation APIs go through Layout and inherit it's requirements. I also don't see an explicit requirement that sizes are padded to alignment anywhere.)

@eddyb
Copy link
Member

eddyb commented Mar 25, 2022

Noticed this comment in the snippets above:

// ... On 32-bit and 16-bit we need to add 
// an extra guard for this in case we're running on a platform which can use 
// all 4GB in user-space, e.g., PAE or x32.

AFAIK this is a bit off, these are the distinctions I'm aware of:

  • x86_32 kernel
    • x86_32 userspace
    • PAE: increases the amount of physical memory the whole system can address
      • without it, there is less than 4GiB of total RAM (as some physical addresses are MMIO)
      • maybe some kernels do not give userspace more than 2GiB unless PAE is available? not sure
  • x86_64 kernel
    • x86_32 userspace
      • Linux: userspace gets nearly 4GiB, AFAICT (easier to see with musl than glibc)
        • experimentally, with musl, you only lose ~256MiB:
          • lowest ~128MiB: static executable mapped at 0x08000000 (can probably lower that?)
          • highest ~128MiB: vDSO and the main thread's stack are mapped there
        • with fragmentation you can use more of the gaps, but a contiguous allocation is going to cap out at around ~3.75GiB (and closer to ~2.5GiB for glibc but that's mostly the ASLR worsening fragmentation AFAICT, so it's more of a gamble)
      • Windows: according to the 4GT ("4GiB Tuning") docs:

        On 64-bit editions of Windows, 32-bit applications marked with the IMAGE_FILE_LARGE_ADDRESS_AWARE flag have 4 GB of address space available.

    • x86_64 userspace
      • by default, you get 64-bit address space
        • however, for a long time the hardware was limited to 48-bit, and some (most?) kernels split that into two halves, leaving 47-bit for userspace
      • "x32" is a Linux x86_64 ABI that uses the bottom 4GiB of the 64-bit address space, relying on x86 addressing modes to enjoy the smaller pointers
        (I wonder if you could go as low as 16-bit addresses while still having 64-bit registers, heh)
        • compilers support this as an ABI with 32-bit pointers "by default" (think "near" pointers)
        • Linux x86_64 syscalls have a bit (in the syscall number) indicating whether the kernel should account for x32 variations, like smaller struct sizes/fields offsets, not returning pointers above 4GiB (e.g. from mmap), etc.
        • x86_64 syscalls and 64-bit pointers can be used simultaneously with x32 if enough care is taken (either through FFI, or a compiler that allows specifying "far" pointers in x32 mode)

So AFAICT, PAE isn't really relevant and x32 is more of a "pointer compression trick" than a "fundamentally" 32-bit userspace.
(efficiency and lack of OS support are the only things stopping someone from making up a pseudo-Harvard ABI, on any platform, with smaller (even as small as 8-bit) data pointers, that only need to address statics, maybe some heap, and the stack)

Taking into account that "can use all 4GB" should be "can use more than 2GiB", I think we can just say that:

  • 32-bit (userspace) programs would mainly be kept away from 2GiB by available memory in the system
  • 64-bit (userspace) programs, on the other hand, will likely never have more than 63 bits for each of the kernel and userspace, even if 64-bit virtual addresses finally get implemented in hardware (because that's the most convenient way to split the two, AFAIK)

That leaves bare-metal/kernel 64-bit code on some future CPU (that could still be targeted just fine by an existing Rust version!), unaccounted for. And probably only bare-metal without an userspace, because you wouldn't have an allocation crossing the kernel/userspace split even if you could see the entire 64-bit address space at once.

I guess that could justify skipping the checks in those cases, but I would feel more comfortable with something like cfg!(any(unix, windows)) to rule out long-term-plausible weird configurations.

@Gankra
Copy link
Contributor

Gankra commented Mar 25, 2022

fwiw all the fiddly shit in RawVec is largely an aesthetic vanity project of my own making because the entire premise of saving an add/comparison is ridiculous when entering RawVec's code implies you are about to do a dynamic call to the allocator and do O(n) work.

(Hot paths are largely guarded by if self.len == self.cap { in Vec itself.)

@RalfJung
Copy link
Member

@bors rollup=never

@RalfJung
Copy link
Member

Relatedly, we also have wording like this in our offset methods:

Most platforms fundamentally can’t even construct such an allocation [meaning one that exceeds isize::MAX]. For instance, no known 64-bit platform can ever serve a request for 2^63 bytes due to page-table limitations or splitting the address space. However, some 32-bit and 16-bit platforms may successfully serve a request for more than isize::MAX bytes with things like Physical Address Extension. As such, memory acquired directly from allocators or memory mapped files may be too large to handle with this function.

Not sure if that will be affected by this change though. Does LLVM consider it okay to (somehow) have a larger-than-isize::MAX allocation and use wrapping_offset to move more than isize::MAX inside it?

@Gankra
Copy link
Contributor

Gankra commented Mar 25, 2022

C has a rule that you can't stride such an allocation in one step, and instead have to do it in two steps. Presumably llvm supports this semantic. As I understand it, there was also vaguely a period where C tried to insist that there should actually be a 1-bit difference between some of the integer types to accommodate the issue with signed offsets, which was completely wild and no implementation actually did.

Long ago before even like 1.0 we all agreed "that's all a fucking nightmare" (and I seriously doubt almost any C/C++ code actually supports detecting and handling any of that) and concluded that the only sound solution (in the sense that all code wouldn't have subtle UB) was to mandate everything be restricted to isize::MAX. I believe modern versions of glibc and jemalloc also actually just silently enforce this because again, anything else is completely broken.

(I am told that gcc also hardcodes this limitation, and it's not just an llvm thing)

@RalfJung
Copy link
Member

(I am told that gcc also hardcodes this limitation, and it's not just an llvm thing)

That is very surprising. To me the entire thing looks wholly unnecessary and motivated entirely by the fact that LLVM's getelementptr is a really odd API that interprets the total effective offset as signed. If LLVM had proper unsigned offsetting, and if we used that for field and array accesses and so on, there would be no issue. (Negative offsets are exceedingly rare and could be delegated to special methods.)

Why does GCC have a similar limitation?

@Gankra
Copy link
Contributor

Gankra commented Mar 25, 2022

Because it's a C limitation and they're both riddled with C semantics.

@tavianator
Copy link
Contributor

Here's some pointers for GCC:

@Gankra
Copy link
Contributor

Gankra commented Mar 25, 2022

So yeah basically this is a defacto restriction that all programming languages must conform to (if only for C interop), and which doesn't actually matter on 64-bit because it's unobservable. Anyone who wants to Be Clever on 32/16-bit gets to reach for mmap and go around the language's back and be very careful / hope they don't get miscompiled.

@RalfJung
Copy link
Member

Wow computers truly are terrible. :'-(

@RalfJung
Copy link
Member

GlobalAlloc::realloc and alloc_realloc do not put an isize maximum on new_size

So what's the plan for those two? Impose a requirement on GlobalAlloc implementations that reallocation MUST fail if new_size > isize::MAX? It is an unsafe trait, so implementation requirements are possible, but this is technically a breaking change.

@Lokathor
Copy link
Contributor

It's technically breaking, but it's also for soundness.

bors added a commit to rust-lang/hashbrown that referenced this pull request Sep 18, 2022
 Check that layout size fits in isize in Layout

Since [rust-lang/rust#95295](rust-lang/rust#95295) we need check that Layout `size`, when rounded up to the nearest multiple of `align`, must not overflow isize (i.e., the rounded value must be less than or equal to `isize::MAX`)
bors pushed a commit to rust-lang-ci/rust that referenced this pull request Sep 19, 2022
bors added a commit to rust-lang-ci/rust that referenced this pull request Sep 19, 2022
[stable] Prepare 1.64.0 release

This PR prepares the 1.64.0 stable release builds.

In addition to bumping the channel and including the latest release notes changes, this PR also backports the following PRs:

*  rust-lang#100852
*  rust-lang#101366
*  rust-lang#101468
*  rust-lang#101922

This PR also reverts the following PRs, as decided in rust-lang#101899 (comment):

* rust-lang#95295
* rust-lang#99136 (followup to the previous PR)

r? `@ghost`
cc `@rust-lang/release`
@Amanieu Amanieu added the relnotes Marks issues that should be documented in the release notes of the next release. label Oct 18, 2022
@Amanieu Amanieu modified the milestones: 1.64.0, 1.65.0 Oct 18, 2022
glandium added a commit to glandium/fallible_collections that referenced this pull request Nov 4, 2022
More precisely, size when rounded up to the nearest multiple of align.
See rust-lang/rust#95295.
RustEnthusiast added a commit to RustEnthusiast/nstd that referenced this pull request Nov 6, 2022
wip-sync pushed a commit to NetBSD/pkgsrc-wip that referenced this pull request Nov 27, 2022
Pkgsrc changes:
 * We now manage to build for mipsel-unknown-netbsd, but despite the
   target spec saying cpu = "mips3", the compiler manages to emit 64-bit
   instructions which cause "illegal instruction" error.  Will need more
   work.  The mipsel-unknown-netbsd entry is commentd out since there
   is no 1.64.0 bootstrap.
 * Managed to retain the build of aarch64_be, llvm needed a patch to
   avoid use of neon instructions in the BE case (llvm doesn't support
   use of neon in BE mode).  Ref. patch to
   src/llvm-project/llvm/lib/Support/BLAKE3/blake3_impl.h.
 * The minimum gcc version is now 7.x, and that includes the cross-compiler
   for the targets.  For i386 this also needs to /usr/include/gcc-7 include
   files in the target root, because immintrin.h from gcc 5 is not
   compatible with gcc 7.x.  This applies for the targets where we build
   against a root from netbsd-8 (sparc64, powerpc, i386), and files/gcc-wrap
   gets a hack for this.
 * Pick up tweak for -latomic inclusion from
   rust-lang/rust#104220
   and
   rust-lang/rust#104572
 * Retain ability to do 32-bit NetBSD, by changing from 64 to 32 bit
   types in library/std/src/sys/unix/thread_parker/netbsd.rs.
 * I've struggled a bit to get the "openssl-src" build with -latomic
   where it's needed.  I introduce "NetBSD-generic32" system type and
   use it for the NetBSD mipsel target.  There is another attempt to
   do the same in the patch to vendor/openssl-sys/build/main.rs.
 * Bump bootstraps to 1.64.0, checksum updates.

Upstream changes:

Version 1.65.0 (2022-11-03)
==========================

Language
--------
- [Error on `as` casts of enums with `#[non_exhaustive]` variants]
  (rust-lang/rust#92744)
- [Stabilize `let else`](rust-lang/rust#93628)
- [Stabilize generic associated types (GATs)]
  (rust-lang/rust#96709)
- [Add lints `let_underscore_drop`, `let_underscore_lock`, and
  `let_underscore_must_use` from Clippy]
  (rust-lang/rust#97739)
- [Stabilize `break`ing from arbitrary labeled blocks ("label-break-value")]
  (rust-lang/rust#99332)
- [Uninitialized integers, floats, and raw pointers are now considered
  immediate UB](rust-lang/rust#98919).
  Usage of `MaybeUninit` is the correct way to work with uninitialized
  memory.
- [Stabilize raw-dylib for Windows x86_64, aarch64, and thumbv7a]
  (rust-lang/rust#99916)
- [Do not allow `Drop` impl on foreign ADTs]
  (rust-lang/rust#99576)

Compiler
--------
- [Stabilize -Csplit-debuginfo on Linux]
  (rust-lang/rust#98051)
- [Use niche-filling optimization even when multiple variants have
  data] (rust-lang/rust#94075)
- [Associated type projections are now verified to be well-formed
  prior to resolving the underlying type]
  (rust-lang/rust#99217)
- [Stringify non-shorthand visibility correctly]
  (rust-lang/rust#100350)
- [Normalize struct field types when unsizing]
  (rust-lang/rust#101831)
- [Update to LLVM 15](rust-lang/rust#99464)
- [Fix aarch64 call abi to correctly zeroext when needed]
  (rust-lang/rust#97800)
- [debuginfo: Generalize C++-like encoding for enums]
  (rust-lang/rust#98393)
- [Add `special_module_name` lint]
  (rust-lang/rust#94467)
- [Add support for generating unique profraw files by default when
  using `-C instrument-coverage`]
  (rust-lang/rust#100384)
- [Allow dynamic linking for iOS/tvOS targets]
  (rust-lang/rust#100636)

New targets:
- [Add armv4t-none-eabi as a tier 3 target]
  (rust-lang/rust#100244)
- [Add powerpc64-unknown-openbsd and riscv64-unknown-openbsd as tier 3 targets]
  (rust-lang/rust#101025)
- Refer to Rust's [platform support page][platform-support-doc] for more
  information on Rust's tiered platform support.

Libraries
---------
- [Don't generate `PartialEq::ne` in derive(PartialEq)]
  (rust-lang/rust#98655)
- [Windows RNG: Use `BCRYPT_RNG_ALG_HANDLE` by default]
  (rust-lang/rust#101325)
- [Forbid mixing `System` with direct system allocator calls]
  (rust-lang/rust#101394)
- [Document no support for writing to non-blocking stdio/stderr]
  (rust-lang/rust#101416)
- [`std::layout::Layout` size must not overflow `isize::MAX` when
  rounded up to `align`](rust-lang/rust#95295)
  This also changes the safety conditions on
  `Layout::from_size_align_unchecked`.

Stabilized APIs
---------------
- [`std::backtrace::Backtrace`]
  (https://doc.rust-lang.org/stable/std/backtrace/struct.Backtrace.html)
- [`Bound::as_ref`]
  (https://doc.rust-lang.org/stable/std/ops/enum.Bound.html#method.as_ref)
- [`std::io::read_to_string`]
  (https://doc.rust-lang.org/stable/std/io/fn.read_to_string.html)
- [`<*const T>::cast_mut`]
  (https://doc.rust-lang.org/stable/std/primitive.pointer.html#method.cast_mut)
- [`<*mut T>::cast_const`]
  (https://doc.rust-lang.org/stable/std/primitive.pointer.html#method.cast_const)

These APIs are now stable in const contexts:
- [`<*const T>::offset_from`]
  (https://doc.rust-lang.org/stable/std/primitive.pointer.html#method.offset_from)
- [`<*mut T>::offset_from`]
  (https://doc.rust-lang.org/stable/std/primitive.pointer.html#method.offset_from)

Cargo
-----
- [Apply GitHub fast path even for partial hashes]
  (rust-lang/cargo#10807)
- [Do not add home bin path to PATH if it's already there]
  (rust-lang/cargo#11023)
- [Take priority into account within the pending queue]
  (rust-lang/cargo#11032).
  This slightly optimizes job scheduling by Cargo, with typically
  small improvements on larger crate graph builds.

Compatibility Notes
-------------------
- [`std::layout::Layout` size must not overflow `isize::MAX` when
  rounded up to `align`] (rust-lang/rust#95295).
  This also changes the safety conditions on
  `Layout::from_size_align_unchecked`.
- [`PollFn` now only implements `Unpin` if the closure is `Unpin`]
  (rust-lang/rust#102737).
  This is a possible breaking change if users were relying on the
  blanket unpin implementation.  See discussion on the PR for
  details of why this change was made.
- [Drop ExactSizeIterator impl from std::char::EscapeAscii]
  (rust-lang/rust#99880)
  This is a backwards-incompatible change to the standard library's
  surface area, but is unlikely to affect real world usage.
- [Do not consider a single repeated lifetime eligible for elision
  in the return type] (rust-lang/rust#103450)
  This behavior was unintentionally changed in 1.64.0, and this
  release reverts that change by making this an error again.
- [Reenable disabled early syntax gates as future-incompatibility
  lints] (rust-lang/rust#99935)
- [Update the minimum external LLVM to 13]
  (rust-lang/rust#100460)
- [Don't duplicate file descriptors into stdio fds]
  (rust-lang/rust#101426)
- [Sunset RLS](rust-lang/rust#100863)
- [Deny usage of `#![cfg_attr(..., crate_type = ...)]` to set the
  crate type] (rust-lang/rust#99784)
  This strengthens the forward compatibility lint
  deprecated_cfg_attr_crate_type_name to deny.
- [`llvm-has-rust-patches` allows setting the build system to treat
  the LLVM as having Rust-specific patches]
  (rust-lang/rust#101072)
  This option may need to be set for distributions that are building
  Rust with a patched LLVM via `llvm-config`, not the built-in
  LLVM.

Internal Changes
----------------

These changes do not affect any public interfaces of Rust, but they represent
significant improvements to the performance or internals of rustc and related
tools.

- [Add `x.sh` and `x.ps1` shell scripts]
  (rust-lang/rust#99992)
- [compiletest: use target cfg instead of hard-coded tables]
  (rust-lang/rust#100260)
- [Use object instead of LLVM for reading bitcode from rlibs]
  (rust-lang/rust#98100)
- [Enable MIR inlining for optimized compilations]
  (rust-lang/rust#91743)
  This provides a 3-10% improvement in compiletimes for real world
  crates. See [perf results]
  (https://perf.rust-lang.org/compare.html?start=aedf78e56b2279cc869962feac5153b6ba7001ed&end=0075bb4fad68e64b6d1be06bf2db366c30bc75e1&stat=instructions:u).
netbsd-srcmastr pushed a commit to NetBSD/pkgsrc that referenced this pull request Jan 23, 2023
Pkgsrc changes:
 * pkglint cleanups, bump bootstrap kits to 1.65.0.
 * New target: mipsel-unknown-netbsd, for cpu=mips32 with soft-float.
 * Managed to retain the build of aarch64_be, llvm needed a patch to
   avoid use of neon instructions in the BE case (llvm doesn't support
   use of neon in BE mode).  Ref. patch to
   src/llvm-project/llvm/lib/Support/BLAKE3/blake3_impl.h.
   Also submitted upstream of LLVM to the BLAKE3 maintainers.
 * The minimum gcc version is now 7.x, and that includes the
   cross-compiler for the targets.  For i386 this also needs to
   /usr/include/gcc-7 include files in the target root, because
   immintrin.h from gcc 5 is not compatible with gcc 7.x.  This
   applies for the targets where we build against a root from netbsd-8
   (sparc64, powerpc, i386), and files/gcc-wrap gets a hack for this.
 * Pick up tweak for -latomic inclusion from
   rust-lang/rust#104220
   and
   rust-lang/rust#104572
 * Retain ability to do 32-bit NetBSD, by changing from 64 to 32 bit
   types in library/std/src/sys/unix/thread_parker/netbsd.rs.
 * I've tried to get the "openssl-src" build with -latomic where it's
   needed.  I've introduced the "NetBSD-generic32" system type and use
   it for the NetBSD mipsel target.  There is another attempt to do
   the same in the patch to vendor/openssl-sys/build/main.rs.


Upstream changes:

Version 1.66.1 (2023-01-10)
===========================

- Added validation of SSH host keys for git URLs in Cargo
  ([CVE-2022-46176](https://www.cve.org/CVERecord?id=CVE-2022-46176))


Version 1.66.0 (2022-12-15)
===========================

Language
--------
- [Permit specifying explicit discriminants on all `repr(Int)`
  enums](rust-lang/rust#95710)
  ```rust
  #[repr(u8)]
  enum Foo {
      A(u8) = 0,
      B(i8) = 1,
      C(bool) = 42,
  }
  ```
- [Allow transmutes between the same type differing only in
  lifetimes](rust-lang/rust#101520)
- [Change constant evaluation errors from a deny-by-default lint to a
  hard error](rust-lang/rust#102091)
- [Trigger `must_use` on `impl Trait` for
  supertraits](rust-lang/rust#102287) This
  makes `impl ExactSizeIterator` respect the existing `#[must_use]`
  annotation on `Iterator`.
- [Allow `..X` and `..=X` in
  patterns](rust-lang/rust#102275)
- [Uplift `clippy::for_loops_over_fallibles` lint into
  rustc](rust-lang/rust#99696)
- [Stabilize `sym` operands in inline
  assembly](rust-lang/rust#103168)
- [Update to Unicode 15](rust-lang/rust#101912)
- [Opaque types no longer imply lifetime
  bounds](rust-lang/rust#95474) This is a
  soundness fix which may break code that was erroneously relying on this
  behavior.

Compiler
--------
- [Add armv5te-none-eabi and thumbv5te-none-eabi tier 3
  targets](rust-lang/rust#101329)
  - Refer to Rust's [platform support page][platform-support-doc] for
    more information on Rust's tiered platform support.
- [Add support for linking against macOS universal
  libraries](rust-lang/rust#98736)

Libraries
---------
- [Fix `#[derive(Default)]` on a generic `#[default]` enum adding
  unnecessary `Default`
  bounds](rust-lang/rust#101040)
- [Update to Unicode 15](rust-lang/rust#101821)

Stabilized APIs
---------------
- [`proc_macro::Span::source_text`](https://doc.rust-lang.org/stable/proc_macro/struct.Span.html#method.source_text)
- [`uX::{checked_add_signed, overflowing_add_signed,
  saturating_add_signed,
  wrapping_add_signed}`](https://doc.rust-lang.org/stable/std/primitive.u8.html#method.checked_add_signed)
- [`iX::{checked_add_unsigned, overflowing_add_unsigned,
  saturating_add_unsigned,
  wrapping_add_unsigned}`](https://doc.rust-lang.org/stable/std/primitive.i8.html#method.checked_add_unsigned)
- [`iX::{checked_sub_unsigned, overflowing_sub_unsigned,
  saturating_sub_unsigned,
  wrapping_sub_unsigned}`](https://doc.rust-lang.org/stable/std/primitive.i8.html#method.checked_sub_unsigned)
- [`BTreeSet::{first, last, pop_first,
  pop_last}`](https://doc.rust-lang.org/stable/std/collections/struct.BTreeSet.html#method.first)
- [`BTreeMap::{first_key_value, last_key_value, first_entry, last_entry,
  pop_first,
  pop_last}`](https://doc.rust-lang.org/stable/std/collections/struct.BTreeMap.html#method.first_key_value)
- [Add `AsFd` implementations for stdio lock types on
  WASI.](rust-lang/rust#101768)
- [`impl TryFrom<Vec<T>> for Box<[T;
  N]>`](https://doc.rust-lang.org/stable/std/boxed/struct.Box.html#impl-TryFrom%3CVec%3CT%2C%20Global%3E%3E-for-Box%3C%5BT%3B%20N%5D%2C%20Global%3E)
- [`core::hint::black_box`](https://doc.rust-lang.org/stable/std/hint/fn.black_box.html)
- [`Duration::try_from_secs_{f32,f64}`](https://doc.rust-lang.org/stable/std/time/struct.Duration.html#method.try_from_secs_f32)
- [`Option::unzip`](https://doc.rust-lang.org/stable/std/option/enum.Option.html#method.unzip)
- [`std::os::fd`](https://doc.rust-lang.org/stable/std/os/fd/index.html)

Rustdoc
-------
- [Add Rustdoc warning for invalid HTML tags in the
  documentation](rust-lang/rust#101720)

Cargo
-----
- [Added `cargo remove` to remove dependencies from
  Cargo.toml](https://doc.rust-lang.org/nightly/cargo/commands/cargo-remove.html)
- [`cargo publish` now waits for the new version to be downloadable
  before exiting](rust-lang/cargo#11062)

See [detailed release notes](https://github.com/rust-lang/cargo/blob/master/CHANGELOG.md#cargo-166-2022-12-15) for more.

Compatibility Notes
-------------------
- [Only apply `ProceduralMasquerade` hack to older versions of
  `rental`](rust-lang/rust#94063)
- [Don't export `__heap_base` and `__data_end` on
  wasm32-wasi.](rust-lang/rust#102385)
- [Don't export `__wasm_init_memory` on
  WebAssembly.](rust-lang/rust#102426)
- [Only export `__tls_*` on
  wasm32-unknown-unknown.](rust-lang/rust#102440)
- [Don't link to `libresolv` in libstd on
  Darwin](rust-lang/rust#102766)
- [Update libstd's libc to 0.2.135 (to make `libstd` no longer pull in
  `libiconv.dylib` on
  Darwin)](rust-lang/rust#103277)
- [Opaque types no longer imply lifetime
  bounds](rust-lang/rust#95474)
  This is a soundness fix which may break code that was erroneously
  relying on this behavior.
- [Make `order_dependent_trait_objects` show up in future-breakage
  reports](rust-lang/rust#102635)
- [Change std::process::Command spawning to default to inheriting the
  parent's signal mask](rust-lang/rust#101077)

Internal Changes
----------------

These changes do not affect any public interfaces of Rust, but they
represent significant improvements to the performance or internals of
rustc and related tools.

- [Enable BOLT for LLVM
  compilation](rust-lang/rust#94381)
- [Enable LTO for
  rustc_driver.so](rust-lang/rust#101403)


Version 1.65.0 (2022-11-03)
==========================

Language
--------
- [Error on `as` casts of enums with `#[non_exhaustive]` variants]
  (rust-lang/rust#92744)
- [Stabilize `let else`](rust-lang/rust#93628)
- [Stabilize generic associated types (GATs)]
  (rust-lang/rust#96709)
- [Add lints `let_underscore_drop`, `let_underscore_lock`, and
  `let_underscore_must_use` from Clippy]
  (rust-lang/rust#97739)
- [Stabilize `break`ing from arbitrary labeled blocks ("label-break-value")]
  (rust-lang/rust#99332)
- [Uninitialized integers, floats, and raw pointers are now considered
  immediate UB](rust-lang/rust#98919).
  Usage of `MaybeUninit` is the correct way to work with uninitialized
  memory.
- [Stabilize raw-dylib for Windows x86_64, aarch64, and thumbv7a]
  (rust-lang/rust#99916)
- [Do not allow `Drop` impl on foreign ADTs]
  (rust-lang/rust#99576)

Compiler
--------
- [Stabilize -Csplit-debuginfo on Linux]
  (rust-lang/rust#98051)
- [Use niche-filling optimization even when multiple variants have
  data] (rust-lang/rust#94075)
- [Associated type projections are now verified to be well-formed
  prior to resolving the underlying type]
  (rust-lang/rust#99217)
- [Stringify non-shorthand visibility correctly]
  (rust-lang/rust#100350)
- [Normalize struct field types when unsizing]
  (rust-lang/rust#101831)
- [Update to LLVM 15](rust-lang/rust#99464)
- [Fix aarch64 call abi to correctly zeroext when needed]
  (rust-lang/rust#97800)
- [debuginfo: Generalize C++-like encoding for enums]
  (rust-lang/rust#98393)
- [Add `special_module_name` lint]
  (rust-lang/rust#94467)
- [Add support for generating unique profraw files by default when
  using `-C instrument-coverage`]
  (rust-lang/rust#100384)
- [Allow dynamic linking for iOS/tvOS targets]
  (rust-lang/rust#100636)

New targets:
- [Add armv4t-none-eabi as a tier 3 target]
  (rust-lang/rust#100244)
- [Add powerpc64-unknown-openbsd and riscv64-unknown-openbsd as tier 3 targets]
  (rust-lang/rust#101025)
- Refer to Rust's [platform support page][platform-support-doc] for more
  information on Rust's tiered platform support.

Libraries
---------
- [Don't generate `PartialEq::ne` in derive(PartialEq)]
  (rust-lang/rust#98655)
- [Windows RNG: Use `BCRYPT_RNG_ALG_HANDLE` by default]
  (rust-lang/rust#101325)
- [Forbid mixing `System` with direct system allocator calls]
  (rust-lang/rust#101394)
- [Document no support for writing to non-blocking stdio/stderr]
  (rust-lang/rust#101416)
- [`std::layout::Layout` size must not overflow `isize::MAX` when
  rounded up to `align`](rust-lang/rust#95295)
  This also changes the safety conditions on
  `Layout::from_size_align_unchecked`.

Stabilized APIs
---------------
- [`std::backtrace::Backtrace`]
  (https://doc.rust-lang.org/stable/std/backtrace/struct.Backtrace.html)
- [`Bound::as_ref`]
  (https://doc.rust-lang.org/stable/std/ops/enum.Bound.html#method.as_ref)
- [`std::io::read_to_string`]
  (https://doc.rust-lang.org/stable/std/io/fn.read_to_string.html)
- [`<*const T>::cast_mut`]
  (https://doc.rust-lang.org/stable/std/primitive.pointer.html#method.cast_mut)
- [`<*mut T>::cast_const`]
  (https://doc.rust-lang.org/stable/std/primitive.pointer.html#method.cast_const)

These APIs are now stable in const contexts:
- [`<*const T>::offset_from`]
  (https://doc.rust-lang.org/stable/std/primitive.pointer.html#method.offset_from)
- [`<*mut T>::offset_from`]
  (https://doc.rust-lang.org/stable/std/primitive.pointer.html#method.offset_from)

Cargo
-----
- [Apply GitHub fast path even for partial hashes]
  (rust-lang/cargo#10807)
- [Do not add home bin path to PATH if it's already there]
  (rust-lang/cargo#11023)
- [Take priority into account within the pending queue]
  (rust-lang/cargo#11032).
  This slightly optimizes job scheduling by Cargo, with typically
  small improvements on larger crate graph builds.

Compatibility Notes
-------------------
- [`std::layout::Layout` size must not overflow `isize::MAX` when
  rounded up to `align`] (rust-lang/rust#95295).
  This also changes the safety conditions on
  `Layout::from_size_align_unchecked`.
- [`PollFn` now only implements `Unpin` if the closure is `Unpin`]
  (rust-lang/rust#102737).
  This is a possible breaking change if users were relying on the
  blanket unpin implementation.  See discussion on the PR for
  details of why this change was made.
- [Drop ExactSizeIterator impl from std::char::EscapeAscii]
  (rust-lang/rust#99880)
  This is a backwards-incompatible change to the standard library's
  surface area, but is unlikely to affect real world usage.
- [Do not consider a single repeated lifetime eligible for elision
  in the return type] (rust-lang/rust#103450)
  This behavior was unintentionally changed in 1.64.0, and this
  release reverts that change by making this an error again.
- [Reenable disabled early syntax gates as future-incompatibility
  lints] (rust-lang/rust#99935)
- [Update the minimum external LLVM to 13]
  (rust-lang/rust#100460)
- [Don't duplicate file descriptors into stdio fds]
  (rust-lang/rust#101426)
- [Sunset RLS](rust-lang/rust#100863)
- [Deny usage of `#![cfg_attr(..., crate_type = ...)]` to set the
  crate type] (rust-lang/rust#99784)
  This strengthens the forward compatibility lint
  deprecated_cfg_attr_crate_type_name to deny.
- [`llvm-has-rust-patches` allows setting the build system to treat
  the LLVM as having Rust-specific patches]
  (rust-lang/rust#101072)
  This option may need to be set for distributions that are building
  Rust with a patched LLVM via `llvm-config`, not the built-in
  LLVM.

Internal Changes
----------------

These changes do not affect any public interfaces of Rust, but they represent
significant improvements to the performance or internals of rustc and related
tools.

- [Add `x.sh` and `x.ps1` shell scripts]
  (rust-lang/rust#99992)
- [compiletest: use target cfg instead of hard-coded tables]
  (rust-lang/rust#100260)
- [Use object instead of LLVM for reading bitcode from rlibs]
  (rust-lang/rust#98100)
- [Enable MIR inlining for optimized compilations]
  (rust-lang/rust#91743)
  This provides a 3-10% improvement in compiletimes for real world
  crates. See [perf results]
  (https://perf.rust-lang.org/compare.html?start=aedf78e56b2279cc869962feac5153b6ba7001ed&end=0075bb4fad68e64b6d1be06bf2db366c30bc75e1&stat=instructions:u).
yvt added a commit to yvt/rlsf that referenced this pull request Feb 17, 2023
This reverts commit 77b0c40.

Constructing such bug `Layout`s is now refused by `Layout::
from_size_align` as of [rust-lang/rust#95295][1].

[1]: rust-lang/rust#95295
fmease added a commit to fmease/rust that referenced this pull request Apr 23, 2024
alloc::Layout: explicitly document size invariant on the type level

rust-lang#95295 added this to the constructor, but it seems worth documenting the type invariant at the type level.
rust-timer added a commit to rust-lang-ci/rust that referenced this pull request Apr 23, 2024
Rollup merge of rust-lang#123048 - RalfJung:layout, r=dtolnay

alloc::Layout: explicitly document size invariant on the type level

rust-lang#95295 added this to the constructor, but it seems worth documenting the type invariant at the type level.
bors added a commit to rust-lang-ci/rust that referenced this pull request Sep 1, 2024
Take more advantage of the `isize::MAX` limit in `Layout`

Things like `padding_needed_for` are current implemented being super careful to handle things like `Layout::size` potentially being `usize::MAX`.

But now that rust-lang#95295 has happened, that's no longer a concern.  It's possible to add two `Layout::size`s together without risking overflow now.

So this PR adds a wrapper type to allow doing that kind of thing in safe code while still telling LLVM it can't overflow.
bors added a commit to rust-lang-ci/rust that referenced this pull request Sep 1, 2024
Take more advantage of the `isize::MAX` limit in `Layout`

Things like `padding_needed_for` are current implemented being super careful to handle things like `Layout::size` potentially being `usize::MAX`.

But now that rust-lang#95295 has happened, that's no longer a concern.  It's possible to add two `Layout::size`s together without risking overflow now.

So this PR adds a wrapper type to allow doing that kind of thing in safe code while still telling LLVM it can't overflow.
bors added a commit to rust-lang-ci/rust that referenced this pull request Sep 2, 2024
Take more advantage of the `isize::MAX` limit in `Layout`

Things like `padding_needed_for` are current implemented being super careful to handle things like `Layout::size` potentially being `usize::MAX`.

But now that rust-lang#95295 has happened, that's no longer a concern.  It's possible to add two `Layout::size`s together without risking overflow now.

So take advantage of that to remove a bunch of checked math that's not actually needed.  For example, the round-up-and-add-next-size in `extend` doesn't need any overflow checks at all, just the final check for compatibility with the alignment.

(And while I was doing that I made it all unstably const, because there's nothing in `Layout` that's fundamentally runtime-only.)
bors added a commit to rust-lang-ci/rust that referenced this pull request Sep 18, 2024
Take more advantage of the `isize::MAX` limit in `Layout`

Things like `padding_needed_for` are current implemented being super careful to handle things like `Layout::size` potentially being `usize::MAX`.

But now that rust-lang#95295 has happened, that's no longer a concern.  It's possible to add two `Layout::size`s together without risking overflow now.

So take advantage of that to remove a bunch of checked math that's not actually needed.  For example, the round-up-and-add-next-size in `extend` doesn't need any overflow checks at all, just the final check for compatibility with the alignment.

(And while I was doing that I made it all unstably const, because there's nothing in `Layout` that's fundamentally runtime-only.)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-allocators Area: Custom and system allocators A-layout Area: Memory layout of types disposition-merge This issue / PR is in PFCP or FCP with a disposition to merge it. finished-final-comment-period The final comment period is finished for this PR / Issue. merged-by-bors This PR was explicitly merged by bors. needs-fcp This change is insta-stable, so needs a completed FCP to proceed. perf-regression Performance regression. perf-regression-triaged The performance regression has been triaged. relnotes Marks issues that should be documented in the release notes of the next release. S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. T-libs-api Relevant to the library API team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

{Rc,Arc}::{new_uninit_slice,from_iter} create too large references