Earlier quoted context omitted.
Yeah, that is frustrating since there are no platforms where that would fail today, and it's hard to imagine why we would ever want one with 256bit pointers. We don't even use full 64bit pointers today on x64.
The Ethereum virtual machine addresses it's storage with 256 bits, so there's one wild example. Although in this case you'd probably not want to use usize directly to represent storage.
size_t-to-int vulnerability in Linux’s filesystem layer
121–130 of 280 posts
Re: size_t-to-int vulnerability in Linux’s filesystem layer
#122This kind of issue is the reason why some more modern languages like Rust or Go do not have implicit narrowing conversions. For instance, on Rust, trying to simply pass an usize (Rust's equivalent of size_t) to a function which expects an i32 (Rust's equivalent of int) will not compile; the programmer has to write "size as i32" (Rust's equivalent of "(int) size"), which makes it explicit that it might truncate the va…
Add Java to that list.
Re: size_t-to-int vulnerability in Linux’s filesystem layer
#123I love the little nugget in the mitigations section. You can plug the hole for a normal filesystem, but then FUSE filesystems have an additional problem: "if an attacker FUSE-mounts a long directory (longer than 8MB), then systemd exhausts its stack, crashes, and therefore crashes the entire operating system (a kernel panic)." If there's one place other than the kernel where truly defensive programming should be appl…
Wait how does a user space daemon exhausting its stack lead to a kernel panic?
Re: size_t-to-int vulnerability in Linux’s filesystem layer
#124Re: size_t-to-int vulnerability in Linux’s filesystem layer
#125Earlier quoted context omitted.
This wouldn't be a problem if "int" was defined as the same size as size_t. The solution is probably to change all those functions to take a parameter of size_t instead of int. IMHO one should always be using C99 types instead of int, but Linux predates that. Also, shouldn't that implicit conversion cause a compiler warning?
> IMHO one should always be using C99 types instead of int, but Linux predates that. "Always" is a strong way of putting it, there are often times where it makes sense to use the platform's "natural" word sizes (which is the entire point of having `int` `long` `long long` etc.)
In those cases we probably don't care about the full range of the larger types, so it doesn't hurt to use the smallest type for a range of expected values. If it does make a difference, the program will behave differently when compiled on a different arch or even a different compiler.
But maybe "generally" instead of "always". OTOH even I am guilty of using an int to loop over an array.
Re: size_t-to-int vulnerability in Linux’s filesystem layer
#126Earlier quoted context omitted.
into() does not work from size. It's rather frustrating in practice. https://stackoverflow.com/questions/62832438/why-is-rusts-us...
> It's rather frustrating in practice. All explicit conversions, more so fallible, are "frustrating in practice" especially when coming from a language without those foibles. But given the semantics of usize/isize, it is perfectly reasonable, nay, a good thing, that they're considered neither widenings nor narrowings of other numeric types.
As it is I'm just writing `as u64` which is clearly worse.
Re: size_t-to-int vulnerability in Linux’s filesystem layer
#127This kind of issue is the reason why some more modern languages like Rust or Go do not have implicit narrowing conversions. For instance, on Rust, trying to simply pass an usize (Rust's equivalent of size_t) to a function which expects an i32 (Rust's equivalent of int) will not compile; the programmer has to write "size as i32" (Rust's equivalent of "(int) size"), which makes it explicit that it might truncate the va…
The compiler can issue warnings for this. This os why in C it is a good practice to enable all compiler warnings and to have the compiler treat warnings as errors.
If you write for C compiler Foo 8, there's a decent chance Foo 9 will raise a warning which didn't exist before. Now you have to handle "why doesn't this compile" issues and distributions have to patch your sources to do future releases. And that's ignoring bugs like GCC in the past where in some versions you could not satisfy specific warnings.
Re: size_t-to-int vulnerability in Linux’s filesystem layer
#128Earlier quoted context omitted.
This wouldn't be a problem if "int" was defined as the same size as size_t. The solution is probably to change all those functions to take a parameter of size_t instead of int. IMHO one should always be using C99 types instead of int, but Linux predates that. Also, shouldn't that implicit conversion cause a compiler warning?
Linux apparently provides a similarly named set of sized integer types to Rust, ie: s8 u8 s16 u16 s32 u32 s64 u64 But of course getting C programmers to use these integer types rather than the ones they grew up with isn't easy.
Re: size_t-to-int vulnerability in Linux’s filesystem layer
#129That's over 9MB, running in supervisor mode.
2021, and people are still surprised every time a kernel bug with security implications is found.
Maybe it is time to look at different OS designs. Large companies such as Google (Fuchsia) or Huawei (HarmonyOS) have begun to pick up on this.
Re: size_t-to-int vulnerability in Linux’s filesystem layer
#130Earlier quoted context omitted.
-Wall -Wextra -Wpedantic does not enable all diagnostics. This is GNU's idea of "all". Contrast to Clang's -Weverything, which will.
The reason for this decision is so that compiler upgrades with -Wall and -Werror don't break builds. I can see the reason behind it, but I feel that this behavior is something you opt into when you use -Werror.
It feels like the "right thing" here would instead be for the compiler to allow build scripts to reference a specific point-in-time semantics for -Wall.
For example, `-Wall=9.3.0` could be used to mean "all the error checks that GCC v9.3.0 knew how to run".
Or better yet (for portability), a date, e.g. `-Wall=20210720` to mean "all the error checks built into the compiler as of builds up-to-and-including [date]."
To implement this, compilers would just need to know what version/date each of their error checks was first introduced. Errors newer than the user's specifier, could then be filtered out of -Wall, before -Wall is applied.
With such a flag, you could "lock" your CI buildscript to a specific snapshot of warnings, just like you "lock" dependencies to a specific set of resolved versions.
And just like dependency locking, if you have some time on your hands one day, you could "unlock" the error-check-suite snapshot, resolve all the new error-checks introduced, and then re-lock to the new error-check-suite timestamp.