Earlier quoted context omitted.
Right, this is a small infelicity in Rust, it is easier to write let x = size as i32; ... even if what you meant was closer to let x: i32 = size.try_into().expect("We are 100% sure size is small enough to fit into x"); But at least it isn't C or C++ where you might accidentally write x = size; ... and the compiler doesn't even warn you that size is bigger than x and you need to think about what you intended. It's rea…
> and the compiler doesn't even warn you that size is bigger than x That's not true tho, compiler with reasonable flags set will definitely warn you and if you really don't like this kind of code you can force compiler to issue an error instead
size_t-to-int vulnerability in Linux’s filesystem layer
81–90 of 280 posts
Re: size_t-to-int vulnerability in Linux’s filesystem layer
#82Earlier quoted context omitted.
> and the compiler doesn't even warn you that size is bigger than x That's not true tho, compiler with reasonable flags set will definitely warn you and if you really don't like this kind of code you can force compiler to issue an error instead
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; }
This is GNU's idea of "all".
Contrast to Clang's -Weverything, which will.
Re: size_t-to-int vulnerability in Linux’s filesystem layer
#83This 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…
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?
Re: size_t-to-int vulnerability in Linux’s filesystem layer
#84Earlier quoted context omitted.
> and the compiler doesn't even warn you that size is bigger than x That's not true tho, compiler with reasonable flags set will definitely warn you and if you really don't like this kind of code you can force compiler to issue an error instead
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; }
Re: size_t-to-int vulnerability in Linux’s filesystem layer
#85Earlier quoted context omitted.
Rust doesn't allow them either: https://play.rust-lang.org/?version=stable&mode=debug&editio... Adding .into() works though, which is the recommended method if the conversion can be statically guaranteed (otherwise try_into should be used, which will become easier in the 2021 edition as the TryInto trait will become part of the prelude).
into() does not work from size. It's rather frustrating in practice. https://stackoverflow.com/questions/62832438/why-is-rusts-us...
We don't even use full 64bit pointers today on x64.
Re: size_t-to-int vulnerability in Linux’s filesystem layer
#86Re: size_t-to-int vulnerability in Linux’s filesystem layer
#87This 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…
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?
Re: size_t-to-int vulnerability in Linux’s filesystem layer
#88Earlier quoted context omitted.
As a interesting side note: The "as" operator is often considered to have been a mistake. Both because of unchecked casts and because of "doing to much". So I wouldn't be surprised if in the (very) long term there will be a rust edition deprecating `as` casts (after we have alternatives to all cast done with `as`, which are: Pointer casts, dyn casts/explicit coercion and truncating integer casts, for some we already…
I would prefer not to see that happen, I'm fine with as and the safer options as they are currently. It would be a big job to update all the code in the wild when you want to move to the newer edition.
Re: size_t-to-int vulnerability in Linux’s filesystem layer
#89> Unfortunately, this size_t is also passed to functions whose size argument is an int (a signed 32-bit integer), not a size_t. Is this the type of things that could be caught by a linter or strict compilation rules? This seems to be to be a failure of the type system.
https://clang.llvm.org/extra/clang-tidy/checks/cppcoreguidel...
But strict compilation rules (eg, clang's -Weverything) mainly only work if you treat them as errors (so -Werror), and then some of those strict are then also questionable at best, and just outright annoyingly wrong at worst. For example, unused parameter warnings on virtual methods are a waste of time to deal with. It's not a symptom of a bug most of the time, so it being an error just generates workaround churn or you end up just disabling the warning and then maybe that bites you the few times it would have pointed out an actual issue.
Beyond the blanket ones like clang's -Weverything, it can otherwise be a job to keep up with compiler upgrades and the vast number of warning options they have.
Re: size_t-to-int vulnerability in Linux’s filesystem layer
#90Earlier quoted context omitted.
Haha, yeah JS integers "can grow". Kind of. And then they bite you in the worst way possible. Especially when combined with cryptography (e.g. nonces). Try this: >> const x = 288230376151711740; >> x == x + 1 true Or this: >> 2\*1024 Infinity JS doesn't even have integers. It only has floats. JS is by far the worst language I know of when it comes to integer support. If you want a better example of arbitrary precisio…
Neat trick. Math.pow(2, 53) == Math.pow(2, 53) + 1 This is a bit clearer I think. The addition just barely overflows the 53 mantissa bits of the IEEE 754 double precision floating point number. By the way, JS has BigInts these days, which are supported by all major browsers: https://caniuse.com/bigint >> const x = 288230376151711740n; >> x == x + 1n false
2**53 == 2**53+1
^^ even more clear.That's why Number.isSafeInteger(a) exists.
Integers up to +/- 9007199254740991 (Number.MAX_SAFE_INTEGER) are fine.