Live data from Hacker News

size_t-to-int vulnerability in Linux’s filesystem layer

openwall.com

161–170 of 280 posts

Re: size_t-to-int vulnerability in Linux’s filesystem layer

#161
post #159
post #154

Earlier quoted context omitted.

What the hell is systemd doing that a 8MB long file path can exhaust its stack? Is it doing some recursive parsing or is it just doing something plain stupid like using a VLA to store user provided data?

Probably unbounded alloca() as always.

Yep: https://github.com/systemd/systemd/commit/b34a4f0e6729de292c...

strdupa(input) without any length check

Fix is to replace it with unbounded malloc() instead of checking for sane length first.

Re: size_t-to-int vulnerability in Linux’s filesystem layer

#162
post #156

Earlier 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.

It seems though that the point is made, right? Even 'good' approaches miss on what should be a clear 'whoa, are you sure?' type warning. There are a lot of footguns wandering around in C/C++ land.

No, the point was you want don't get a warning and it will silently wrap. You can scroll up if you've forgotten.

And it is false. My default configuration C++ project created in Clion shows it very clearly, and even pesters to use int32/int64 over int/long.

But as usual the default fallback when you're wrong about C++ is "uh yeah but lotta footguns amirite"

As if there aren't enough that we need to start making them up...

Re: size_t-to-int vulnerability in Linux’s filesystem layer

#163
post #72

Earlier quoted context omitted.

What flags you have in mind? Because this code doesn't generate any warning with GCC 11.1.0 with -Wall -Wextra: int main(void) { int some_int = 1234567; char c = some_int; return c; }

-Wall -Wextra -Wpedantic does not enable all diagnostics. This is GNU's idea of "all". Contrast to Clang's -Weverything, which will.

> This is GNU's idea of "all".

Unfortunately, over the years people baked the semantics of -Wall into their builds so new diagnostics could not be added to that flag.

And clang’s -Weverything shows how the opposite can fail as well

Re: size_t-to-int vulnerability in Linux’s filesystem layer

#164
post #75

Earlier quoted context omitted.

I assume they meant throwing an exception like divisions by zero usually do, i.e. a hardware trap. I always thought that overflows should be checked in hardware, I suppose it's not a stretch to extend that to truncation. It's controversial though, and obviously mostly a thought experiment anyway unless we manage to convince some CPU manufacturer to extend their ISA that way. MIPS does have (optional) trapping overflo…

Swift checks all arithmetic by default: https://swift.godbolt.org/z/rW614G5aq It seems obvious that future Apple CPUs will have hardware support for this, if they don't already.

I don’t see this happening unless it makes it into the ARM ISA.

Re: size_t-to-int vulnerability in Linux’s filesystem layer

#165

Earlier 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?

> This wouldn't be a problem if "int" was defined as the same size as size_t. ILP64 causes a lot of problems, most notably needlessly-increased memory usage and, in C, the inconvenience of requesting a 32-bit type when int is 64-bit. It's rather uncommon to actually need the extra 64-bit range except when describing pointer addresses and memory/disk sizes, both of which benefit from an explicit intptr_t/size_t type f…

ILP64 also solves a lot of problems if you don’t define overflow to be UB.

Re: size_t-to-int vulnerability in Linux’s filesystem layer

#166
post #32

Earlier quoted context omitted.

> Some Rust developers argue that even "size as i32" should be avoided, and "size.try_into()" should be used instead, since it forces the programmer to treat an overflow explicitly at runtime, instead of silently wrapping. It's important to still have the option for efficient truncating semantics, though; some software (e.g. emulators) needs to chunk large integers into 2/4/8 smaller ones, and rotation + truncating a…

> are there any low-level/systems languages where a demoting cast with a generated runtime check gets the simple/clean syntax-sugared semantics (to encourage/favor its use), while truncating demotion requires a clumsier syntax (to discourage its use)? Not exactly the same thing, but in a related area C++ does this a bit. In C++ you can always still do a c-style cast `(int) some_var` (and the implicit casts obviously)…

You can have your compiler warm about c-style casts

Re: size_t-to-int vulnerability in Linux’s filesystem layer

#167
post #7

This 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.

It can catch people by surprise that Java's narrowing conversions may not preserve the sign. For example, the following is broken:

class TimestampedObject implements Comparable { long timestamp; int compareTo(TimestampedObject other) { return (int)(timestamp - other.timestamp); } ... }

ErrorProne catches this: https://errorprone.info/bugpattern/BadComparable

Re: size_t-to-int vulnerability in Linux’s filesystem layer

#168

Our exploit requires approximately 5GB of memory and 1M inodes ...so basically 32-bit systems are totally unaffected (and I believe size_t and int are the same size there anyway), but I think bugs like this are easily prevented by simply imposing sane limits --- there is zero reason to even consider allowing a path more than a few K in length, and IMHO even that is overly generous. While I know there's a lot of hate…

> I think bugs like this are easily prevented by simply imposing sane limits

In general, no. Attackers are clever and can usually find their way around arbitrary limits when a bug exists. Sometimes such a restriction might stop them, but more often than not they’ll bypass it some other way.

Re: size_t-to-int vulnerability in Linux’s filesystem layer

#169

Earlier quoted context omitted.

Swift checks all arithmetic by default: https://swift.godbolt.org/z/rW614G5aq It seems obvious that future Apple CPUs will have hardware support for this, if they don't already.

I don’t see this happening unless it makes it into the ARM ISA.

I don’t know the terms of Apple’s license with ARM, do you? I’m quite interested.

Given that Apple was one of the original founders of ARM it’s quite possible that their license allows much more latitude anyone else’s.

Re: size_t-to-int vulnerability in Linux’s filesystem layer

#170
post #161
post #159

Earlier quoted context omitted.

Probably unbounded alloca() as always.

Yep: https://github.com/systemd/systemd/commit/b34a4f0e6729de292c... strdupa(input) without any length check Fix is to replace it with unbounded malloc() instead of checking for sane length first.

Good find thanks for sharing. And everyone at work gripes about me carrying the size around with a lot of my variables in the form of a struct. It's strictly a reminder to always be checking the size since I'm juggling with shotguns.
Post reply on HN