Live data from Hacker News

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

openwall.com

131–140 of 280 posts

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

#131
post #118
post #9

Can we not have one integer type in c that can grow like in js as required and become bigint if too big?

We don't need arbitrary-sized integers; we need exceptions on overflow (or underflow, but I'll stick to overflow for the rest of this post) to be the default, or similar language features as appropriate. I for one am tired of the chicken & egg issue of "CPUs don't support efficient overflow checking because nobody uses it, so it's slow" and "Overflow checking is slow because the CPU doesn't support it, so nobody uses…

CPU would raise a signal just as null pointer exception? And it seems a lot of code (for eg, safeintadd metioned below) assumes no exception. Would not all that code get messed up?

Would it be possible to just silently replace with arbitrary sized integer and not break any code like safeintadd?

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

#132
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 for Windows' traditional 260-char limit, I personally haven't run into it as a developer except by accident (e.g. runaway recursion) and it's very comforting to know that the limit is there so code will fail before it consumes the disk or memory entirely.

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

#133
post #78

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

Isn't this something that could be done automatically by rustfix?

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

#134
post #9

Can we not have one integer type in c that can grow like in js as required and become bigint if too big?

Yes, arbitrary precision integers could theoretically become a C language/library feature. But let's say that it gets proposed and accepted and it's integrated into popular compiler toolchains. The kernel wouldn't leverage it here or likely anywhere else because of its cost. A newly designed OS kernel could perhaps take on this kind of feature. This would be the kind of OS that could be formally verified and would be…

Perhaps such type of things have been put in Kernel before.

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

#135
post #118

Earlier quoted context omitted.

We don't need arbitrary-sized integers; we need exceptions on overflow (or underflow, but I'll stick to overflow for the rest of this post) to be the default, or similar language features as appropriate. I for one am tired of the chicken & egg issue of "CPUs don't support efficient overflow checking because nobody uses it, so it's slow" and "Overflow checking is slow because the CPU doesn't support it, so nobody uses…

CPU would raise a signal just as null pointer exception? And it seems a lot of code (for eg, safeintadd metioned below) assumes no exception. Would not all that code get messed up? Would it be possible to just silently replace with arbitrary sized integer and not break any code like safeintadd?

CPUs don't raise exceptions, that is a software concept. CPUs do have traps, like for division by zero, but those are not exceptions in the way you think.

Null pointers are also handled by the kernel, not the CPU. Its called a segmentation fault because you are trying to access a memory segment that the OS doesn't want you to.

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

#136

Earlier quoted context omitted.

We can do this in software because there's virtually no limit to the abstractions people make, but hardware doesn't work like that. At some point in the software stack we need to draw a line and say this is a 64-bit signed integer that hardware can understand.

But should it be everywhere including the fs/virtual fs layer? Could we limit it only to device drivers? Not a kernel expert here and would love to hear thoughts.

This doesn't have anything to do with filesystems or kernels.

The x86 assembly uses fixed width immediates. CPU registers are a fixed width. For any code to compile and run, it needs to make decisions about how large stack frames need to be, and how much heap memory to allocate.

This was the parent's point about abstractions. You can make a library that pretends to be a variable sized integer, but to implement such a library you need to make a decision about how much space to allocate and the width of variables in order to compile. There is no getting away from how the hardware works.

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

#138
post #85

Earlier quoted context omitted.

into() does not work from size. It's rather frustrating in practice. https://stackoverflow.com/questions/62832438/why-is-rusts-us...

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.

When 16 bit computers went to 32 bit, people probably thought that one wouldn't ever need 64 bit computers either. That being said, by the time 128 bit run out we have probably boiled earths oceans :).

You could think of checked memory models where half of the 256 bit address is a 128 bit random key needed to access some allocation, or maybe even a decryption key. Similar things are done with the extra space of x64 as well.

Also, 128 bit numbers are still quite uncommon in Rust. Easy conversion of usize to them wouldn't be that useful if conversions of the other number types don't work.

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

#139
post #121

Earlier quoted context omitted.

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.

I'm not familiar with the Ethereum virtual machine, are these really memory pointers? Surely it's represented differently?

EVM is a stack machine, and it has durable storage which is addressed using 256 bit "pointers". So you can do something like

    push x // 256 bit constant
    LOAD
    // top of stack now contains storage[x]

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

#140
I honestly think all the automatic type promotion and conversion rules of the C family should be officially classified as "cute", namely an example of a childish simplification of a serious issue. I'm a C++ programmer of 20+ years experience and I have never, NEVER, caught myself thinking "gee, I'm glad I don't need to cast this." You ALWAYS think it, you just don't TYPE it, and that is the utterly wrong metric to optimise for. My 2c anyway.
Post reply on HN