News for hackers. Stuff that matters.
Re:size_t-to-int vulnerability in Linux’s filesystem layer by mnw21cam on Tuesday July 20, 2021 @11:17AM (#27894800)
I 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 applied, it is systemd.

Re:size_t-to-int vulnerability in Linux’s filesystem layer by josefx on Tuesday July 20, 2021 @04:34PM (#27898929)
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?
Re:size_t-to-int vulnerability in Linux’s filesystem layer by megous on Tuesday July 20, 2021 @04:44PM (#27899055)
Probably unbounded alloca() as always.
Re:size_t-to-int vulnerability in Linux’s filesystem layer by megous on Tuesday July 20, 2021 @04:46PM (#27899094)
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 by stjohnswarts on Tuesday July 20, 2021 @05:04PM (#27899310)
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.
Re:size_t-to-int vulnerability in Linux’s filesystem layer by thayne on Tuesday July 20, 2021 @11:20PM (#27901988)
The fact that c doesn't have a native concept of an array with length and strings usually use a null byte to determine the end is, IMO c's biggest failing, and it's worst legacy on the wider software world.
Re:size_t-to-int vulnerability in Linux’s filesystem layer by nextaccountic on Wednesday July 21, 2021 @12:47PM (#27908673)
This and having any pointer implicitly be nullable
Re:size_t-to-int vulnerability in Linux’s filesystem layer by GoblinSlayer on Wednesday July 21, 2021 @05:47AM (#27904196)
Do they even C? It's official ideology: a good programmer compensates shortcomings of the language.
Re:size_t-to-int vulnerability in Linux’s filesystem layer by stjohnswarts on Wednesday July 21, 2021 @01:06PM (#27908968)
They seem to be all about the conciseness :) . We have gigabytes of memory, a size parameter isn't going to make a difference haha. The allow me my little idiosyncrasies though so I can't complain.
Re:size_t-to-int vulnerability in Linux’s filesystem layer by sinsterizme on Tuesday July 20, 2021 @07:20PM (#27900488)
Shouldn't this PR also use `free` on the duped string before returning? (I never use C so probably missing something but just based on the docs of strdupa...)
Re:size_t-to-int vulnerability in Linux’s filesystem layer by rtldg on Tuesday July 20, 2021 @07:40PM (#27900601)
The variable p is now declared with "_cleanup_free_" which is using some compiler cleanup/destructor attribute stuff to run free
Re:size_t-to-int vulnerability in Linux’s filesystem layer by sinsterizme on Tuesday July 20, 2021 @08:16PM (#27900837)
ah okay, thank you :)
Re:size_t-to-int vulnerability in Linux’s filesystem layer by alerighi on Tuesday July 20, 2021 @07:33PM (#27900547)
This fix to me reduces the performance for nothing. In Linux (or most general on any UNIX system that I saw) a path should not be longer (total) than PATH_MAX, that is typically defined to 4096 bytes. What is the point on allocating something statically at this point?

And yes, I know that really that is only a limit of the system call path lenght, and in theory you can work with longer paths (by changing the current directory to a path and then opening a file from there), because filesystems does (stupidly in my opinion) support it.

But in reality, how many applications will break? Does it make sense to support them?

Also the code in question seems to be dealing with a filename more than a path. A file name shouldn't be longer than NAME_MAX, and that is an hard limit of many (possibly all?) filesystems, as far as I know. So why?

It would be simpler and more optimized to just truncate the name at PATH_MAX. Avoid the overflow and the crash but give an error. Why hard limits are considered that bad? We waste time supporting edge cases that no one would really use in a real system (no way someone needs a path longer than 4096 bytes...), for what? In Windows the limit is 260 characters, and nobody seems to be bothered by that, only in Windows 10 you can increase that.

Re:size_t-to-int vulnerability in Linux’s filesystem layer by wahern on Tuesday July 20, 2021 @07:41PM (#27900607)
The Linux kernel doesn't have an actual path limit. Nor does Solaris. PATH_MAX is 4096 in glibc and musl libc because setting to it to something like INT_MAX or ULONG_MAX would break a lot of existing code that uses PATH_MAX to size buffers. (Though Solaris does define it as INT_MAX, IIRC.) OTOH, because of the lack of a hard limit there's also code that relies (if accidentally) on paths longer than PATH_MAX.
Re:size_t-to-int vulnerability in Linux’s filesystem layer by jwilk on Wednesday July 21, 2021 @05:21AM (#27904067)
Linux does have a limit, at least for some system calls:

  $ strace -e trace=file perl -e 'open(FH, "<", "/" x 4096)'
  …
  openat(AT_FDCWD, "//////////…"..., O_RDONLY|O_LARGEFILE|O_CLOEXEC) = -1 ENAMETOOLONG (File name too long)
  +++ exited with 0 +++
Re:size_t-to-int vulnerability in Linux’s filesystem layer by wahern on Wednesday July 21, 2021 @06:53AM (#27904602)
I stand corrected. It seems that Linux copies the entire path into a kernel-allocated buffer (see getname and getname_flags in fs/namei.c as called by various syscalls in fs/open.c), rejecting paths longer than PATH_MAX.

EDIT: And on Solaris PATH_MAX is 1024 and (AFAICT) Solaris also copies paths into kernel space. It seems I was confusing things with NL_TEXTMAX, which is INT_MAX on glibc (but not Solaris).

Re:size_t-to-int vulnerability in Linux’s filesystem layer by yencabulator on Sunday July 25, 2021 @07:09PM (#27953797)
There's a limit to what path string you can make the kernel interpret. That does not limit total path length. Keep looping on mkdirat/openat and you can make very very deep trees. As opposed to your syscall that is relative to an arbitrary directory, /proc/self/mountinfo has to contain the whole absolute path to be useful.
Re:size_t-to-int vulnerability in Linux’s filesystem layer by yrro on Wednesday July 21, 2021 @07:00AM (#27904663)
https://eklitzke.org/path-max-is-tricky

The Linux kernel defines upper limits for NAME_MAX (255) and PATH_MAX (4096).

The glibc doesn't enforce this limit because it was originally written to run on GNU HURD which I guess doesn't have these limits.

But systemd only runs on glibc on Linux. So I don't see why it doesn't at least sanity check the length of absolute paths with PATH_MAX...

Re:size_t-to-int vulnerability in Linux’s filesystem layer by ohazi on Tuesday July 20, 2021 @08:32PM (#27900931)
> reduces the performance for nothing

Does the code in question ever run in a tight loop (e.g. on file operations after the filesystem is mounted), or just at mount time?

If it's just at mount time, "reducing performance" by one malloc vs a stack adjustment doesn't seem to me like it should be a primary concern.

Re:size_t-to-int vulnerability in Linux’s filesystem layer by alerighi on Sunday July 25, 2021 @02:34PM (#27951663)
We are talking about systemd, that is a core software. I would like systemd to do as few memory allocations as possible. The reason is that memory can run out, especially on embedded devices where you have for example 32Mb of RAM, and you have to properly manage the case that you run out of memory. Most programmers don't, and the program does crash in case you don't have memory available. That is bad for PID 1, because that would mean a kernel panic, that you don't want.

If PID 1 does need to do that kind of stuff (as it seems), I would prefer it to fork a process and do the memory allocation in that, so if that process crashes because you are out of memory the kernel doesn't panic.

Re:size_t-to-int vulnerability in Linux’s filesystem layer by josefx on Wednesday July 21, 2021 @01:52AM (#27902769)
> In Linux (or most general on any UNIX system that I saw) a path should not be longer (total) than PATH_MAX, that is typically defined to 4096 bytes.

That almost sounds like the 260 character windows path limit constant used by some ancient APIs. I would assume that any API limited to that path length is dated and probably unreliable in various contexts as the wikipedia article on filesystems explicitly gives the limit as not defined for various Linux filesystems. Also given the recent talk about in kernel support for NTFS (path limit ~2^16) I assume that any historic code still relying on PATH_MAX needs to be fixed.

Re:size_t-to-int vulnerability in Linux’s filesystem layer by alerighi on Sunday July 25, 2021 @02:40PM (#27951730)
The filesystem can support path length even infinite (simple, make a symlink of a directory inside that directory, you have an infinite path).

PATH_MAX is a limit of a path that you can pass to the various path manipulating functions, open(), unlink(), etc, or returned by getcwd() (that gives an error if path is longer than PATH_MAX, and yes there are non standard system call to go around this limit but... why?)

You can however use paths longer by PATH_MAX, how? Simply chdir() PATH_MAX, then you can chdir() another PATH_MAX, then count how many software breaks...

Imposing a limit on paths makes sense and should be done. 4096 bytes seems reasonable to me. Also, in that example, it wasn't even a matter of a path! They are parsing it seems only the file name, and that is defined to be NAME_MAX, that is 255 bytes, on every system and every filesystem!

Re:size_t-to-int vulnerability in Linux’s filesystem layer by merb on Tuesday July 20, 2021 @05:27PM (#27899604)
was that a guess? wtf... btw. it would probably be hard to make the same mistake in rust. unless you write your own code for strings or use strdupa, too via libc.

I also do never understand why some libraries use "faster" methods everywhere, unless safer ones. it's not like all interfaces to systemd would need to be fast. but they should be secure.

Re:size_t-to-int vulnerability in Linux’s filesystem layer by megous on Tuesday July 20, 2021 @06:20PM (#27900080)
Yes. It happened before, so it was not exactly hard to guess.

https://capsule8.com/blog/exploiting-systemd-journald-part-1...

Re:size_t-to-int vulnerability in Linux’s filesystem layer by alerighi on Tuesday July 20, 2021 @07:23PM (#27900497)
It's not a mistake. Allocating that string on the stack it is not a bad idea. Most of the time the string will be short, and thus an allocation on the stack is faster.

Consider that in Linux a path is defined to be a maximum length of PATH_MAX, that is defined to 4096 bytes, and a filename (and directory name) shouldn't be longer than FILE_MAX that is 255 bytes. This limits are defined in the headers and I use them always in writing my C programs (if it crashes... you are doing something really wrong!).

So how the hell do you have a directory that is more than 8Mb? You shouldn't! The filesystem doesn't support it. It's a matter of the filesystem driver that should reject a path that long in my opinion.

Systemd should be fast. It's at the base of the operating system. Also it should consume little memory. You can say, who cares about allocating dynamically a string, or allocating a static buffer of 16Mb, yes we should care, I use Linux computer with 16Mb of RAM, total. Of course they don't run systemd nowadays since it's too big, but in my opinion systemd is good, and I would like to see it more in the embedded world.

Re:size_t-to-int vulnerability in Linux’s filesystem layer by ehvatum on Wednesday July 21, 2021 @01:30AM (#27902659)
> The filesystem doesn't support it.

Remember that Linux supports hierarchical mounts! You can mount anything at any depth of directory nesting. Even if it were true that MAX_PATH were an FS limitation, you could still nest mounts and encounter absolute paths exceeding MAX_PATH. MAX_PATH is simply the length in bytes of the longest string you should expect system calls to accept as a path parameter.

> I use Linux computer with 16Mb of RAM, total. Of course they don't run systemd nowadays since it's too big, but in my opinion systemd is good, and I would like to see it more in the embedded world.

It sounds like using systemd is a terrible idea for memory-constrained devices, so you really don’t want to see it in the embedded world.

Re:size_t-to-int vulnerability in Linux’s filesystem layer by WGH_ on Wednesday July 21, 2021 @04:16AM (#27903700)
> It sounds like using systemd is a terrible idea for memory-constrained devices, so you really don’t want to see it in the embedded world.

On the other hand, proper event-driven init system (instead of horrible shell scripts with all sorts of fragile "sleep"s and other hacks) sounds sexy for an embedded system. I sometimes get annoyed how home routers, NAS, etc. are slow to boot up

Though the embedded systems I refer to have much more than 16 MB of RAM, more like 128 and up.

Re:size_t-to-int vulnerability in Linux’s filesystem layer by GoblinSlayer on Wednesday July 21, 2021 @07:28AM (#27904857)
Is there a list of init systems that aren't made of shell scripts? Epoch is the only one I found.
Re:size_t-to-int vulnerability in Linux’s filesystem layer by zaarn on Wednesday July 21, 2021 @02:56AM (#27903127)
Fun fact: PATH_MAX and FILE_MAX are glibc/muslc limitations. The Linux Kernel doesn't have a limit here and will happily let you walk into a directory with a 2GB pathname.

ext4 doesn't limit directory depth; only filename length. A filename can be 255 bytes in ext4. How deep that lies in the filesystem isn't limited.

btrfs has the same filename limit, no underlying limit on directory depth.

And I would most likely guess most filesystems don't because the obvious ways to implement directories don't place limits on that depth.

Re:size_t-to-int vulnerability in Linux’s filesystem layer by thayne on Tuesday July 20, 2021 @11:39PM (#27902092)
In rust you can't currently dynamically allocate on the stack, although that's probably something that will be added in the future. And as others have pointed out, allocating on the stack is a fairly reasonable optimization here.

I don't think you could even call strdupa through libc in rust. I would guess that strdupa is either a macro that uses the alloca compiler intrinsic or is itself a compiler intrinsic. Even if it isn't, it will break assumptions the rust compiler makes about the size of the stack frame.

Re:size_t-to-int vulnerability in Linux’s filesystem layer by unmole on Tuesday July 20, 2021 @01:08PM (#27896380)
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 by comex on Tuesday July 20, 2021 @01:20PM (#27896520)
Because the kernel intentionally panics [1] if the init process would otherwise exit in any way – whether because it called exit(), it was killed, or, in this case, it crashed.

This is likely because Unix semantics treat the init process specially: any process whose parent dies is re-parented to the init process. It's not clear what should happen to these processes if the init process itself went away, so the kernel just gives up.

[1] https://elixir.bootlin.com/linux/latest/source/kernel/exit.c...

Re:size_t-to-int vulnerability in Linux’s filesystem layer by Denvercoder9 on Tuesday July 20, 2021 @04:29PM (#27898878)
I wonder if just restarting PID1 could be viable alternative?
Re:size_t-to-int vulnerability in Linux’s filesystem layer by jerf on Tuesday July 20, 2021 @04:33PM (#27898921)
It's generally dangerous to restart PID1 in an enviroment where, by definition, something happened to PID1 that it wasn't expecting. The state of the system is now unreliable, and it's exactly the sort of unreliable in exactly the right place that tends to lead to whopping security issues. Far too easy to end up with "Crash PID1 with 'blah blah blah', then when it restarts it ends up doing bad things X & Y".
Re:size_t-to-int vulnerability in Linux’s filesystem layer by cameronh90 on Tuesday July 20, 2021 @05:59PM (#27899919)
Perhaps a distinction here can be made between running as a server OS and a desktop OS.

In a server I generally want a crash immediately. But on a desktop I'd rather it limp along and give me a chance to finish writing my Hackernews post.

Re:size_t-to-int vulnerability in Linux’s filesystem layer by bigiain on Tuesday July 20, 2021 @08:15PM (#27900826)
I'd rather push the other way on that. We should treat desktops with as much security paranoia at servers.

I'd much rather _not_ have my desktop "limp along" in a poorly understood and probably exploitable fashion while the malware gets a chance to finish encrypting all my files...

If that costs the world the "benefit" of my shared wisdom in a half written Hackernews post, I'm good with that.

Re:size_t-to-int vulnerability in Linux’s filesystem layer by lanstin on Tuesday July 20, 2021 @09:35PM (#27901318)
I run a a lot more untrusted code on my laptop than on my cloud servers. Likewise for work, even more so as I don’t myself trust the spyware/malware they jam on the laptops.
Re:size_t-to-int vulnerability in Linux’s filesystem layer by jerf on Wednesday July 21, 2021 @09:16AM (#27905804)
Basically, there's no solution at this level of granularity. One can also argue that the desktop is where the most important stuff is that we least want hacked, e.g., your family photos, documents, other stuff with a high priority of not being backed up, so we must treat security even higher than a server at this point.

I call these the "already lost" situations. You've already lost, we're just arguing about how to distribute the lossage. While those discussions aren't completely pointless, it is important to keep it clear in our head we're arguing about how to pick up the bodies at a crash site and not how to prevent the crash in the first place; it's a different mindset.

Despite some moderately-justified mockery in the other messages in this thread, the answer really is "just don't crash and have secure code here", which is to say, "don't lose". It's exceeding hard to write and it's a very high bar, but at the same time, it's very difficult to imagine how to secure a single system when you can't even stipulate a core of trusted software exists. If you don't even have a foundation, you're not going to build a secure structure. In this case, by "secure" I don't just mean security, but also, functionality and everything else.

Re:size_t-to-int vulnerability in Linux’s filesystem layer by londons_explore on Tuesday July 20, 2021 @06:36PM (#27900191)
On a server I'd usually want it to limp along too... Better fire an alert but keep happy customers than cause a massive outage just because of someone's overly strict checkfail...

It depends really what your server does, and what the consequences of it doing the wrong thing are.

Re:size_t-to-int vulnerability in Linux’s filesystem layer by bigiain on Tuesday July 20, 2021 @08:23PM (#27900878)
If the consequences of one server wedging itself is a "massive outage" and "unhappy customers", then you probably don't really care about that outage or those customers. If you don't have enough redundancy and alerting and automated disaster recovery to keep your customer facing shit up when one server panics, you're just relying on luck to keep your customers happy.

Fire an alert, remove that server from the load balancer, and fix the problem without your customers even noticing.

Or make sure if you're running a hobby-project architected platform that your customer expectations and SLAs are clear up front, and let it go down until Monday morning when you'll get around to fixing it.

Re:size_t-to-int vulnerability in Linux’s filesystem layer by michaelmrose on Tuesday July 20, 2021 @07:36PM (#27900566)
Or just don't put stuff that crashes in pid1
Re:size_t-to-int vulnerability in Linux’s filesystem layer by modshatereality on Tuesday July 20, 2021 @10:31PM (#27901718)
seriously, if you're doing allocations in pid1 you fucked up.
Re:size_t-to-int vulnerability in Linux’s filesystem layer by afc on Tuesday July 20, 2021 @08:52PM (#27901054)
Yeah, great idea: rather than worry about how to deal with software bugs, just never have bugs...
Re:size_t-to-int vulnerability in Linux’s filesystem layer by a1369209993 on Wednesday July 21, 2021 @01:36AM (#27902688)
Exactly. This is why systemd is a terrible design. The fastest and most secure code, that never crashes and never needs patching, is code that doesn't exist.
Re:size_t-to-int vulnerability in Linux’s filesystem layer by michaelmrose on Tuesday July 20, 2021 @09:07PM (#27901147)
runit.c is 330 lines of code

Keeping it small and simple to minimize bugs is perfectly viable and reasonable.

Re:size_t-to-int vulnerability in Linux’s filesystem layer by dirkt on Wednesday July 21, 2021 @12:26AM (#27902323)
A better alternative would be to keep PID1 as simple as possible, and do anything more complex in a subprocess.

Systemd of course goes in the opposite direction: It assimilates as much functionality as possible from the OS into systemd (though to be fair, not all into PID1).

Re:size_t-to-int vulnerability in Linux’s filesystem layer by monocasa on Tuesday July 20, 2021 @01:17PM (#27896491)
PID 1 is special in Unix systems. As the parent of all other processes (and child to none) it's not clear to the kernel what should happen when it exits.
Re:size_t-to-int vulnerability in Linux’s filesystem layer by mjevans on Tuesday July 20, 2021 @06:45PM (#27900254)
Poorly designed security architecture and division of labor. A more idealized init / systemd would have all of the execution flow of PID 1 mathematically provably correct, and correspondingly have as small a footprint as possible there. All additional functions would run under one or more child processes (where the bulk of systemd would execute).
Re:size_t-to-int vulnerability in Linux’s filesystem layer by bigiain on Tuesday July 20, 2021 @08:30PM (#27900921)
"Lets put the graphics drivers in ring 0, for better performance!" -- Windows NT architects, 1996

"Ummm, lets not do that, it's not such a great idea..." -- Windows Vista team, 2006

Re:size_t-to-int vulnerability in Linux’s filesystem layer by fomine3 on Wednesday July 21, 2021 @12:15AM (#27902261)
Initial Windows NT uses user mode graphic driver, then NT 4.0 move it kernel mode.

https://docs.microsoft.com/en-us/previous-versions//cc750820...

Re:size_t-to-int vulnerability in Linux’s filesystem layer by bigiain on Wednesday July 21, 2021 @01:41AM (#27902712)
Yep. In about '96.

(Well, it came out late '96, so I suppose a bunch of that was actually done in '95.)

Re:size_t-to-int vulnerability in Linux’s filesystem layer by Spivak on Tuesday July 20, 2021 @10:43PM (#27901791)
Different trade offs for different eras and different constraints.
Re:size_t-to-int vulnerability in Linux’s filesystem layer by failwhaleshark on Wednesday July 21, 2021 @12:06AM (#27902219)
Systemd is a swiss-army-kitchen-sink-knife monolith of brittle complexity.

A proper init system similar to runit or s6 would be written in something safer (minimum unsafe) like Rust, be modular, simpler, follow UNIX philosophy, and not try to do everything in one process. Microkernel-style.

Re:size_t-to-int vulnerability in Linux’s filesystem layer by paulddraper on Tuesday July 20, 2021 @03:16PM (#27897947)
Because it's PID 1.
Re:size_t-to-int vulnerability in Linux’s filesystem layer by CrazyPyroLinux on Tuesday July 20, 2021 @11:27AM (#27894922)
systemd? More like systemK! But seriously, are non-systemd systems not vulnerable to the FUSE portion of this? (CVE-2021-33910)
Re:size_t-to-int vulnerability in Linux’s filesystem layer by saurik on Tuesday July 20, 2021 @11:34AM (#27895007)
FWIW, I feel like your comment is responding to an implicit critique of systemd, but even if one was warranted I didn't read that comment as implying such (as the premise would just be that systemd is a key place in the stack where you would need to be super careful, not that it is somehow less careful than other projects... even if I might claim as such for at least logging ;P); it could be that I am misinterpreting your comment, though?
Re:size_t-to-int vulnerability in Linux’s filesystem layer by CrazyPyroLinux on Wednesday July 21, 2021 @03:19PM (#27910801)
Yeah, I think you and a lot of other people misinterpreted my comment, since it was oddly one of my most-downvoted-ever.

My "systemK" joke was indeed implying what you said, that systemd is "a key place in the stack where you would need to be super careful." (Almost Kernel-like.)

And my question was legitimate, although poorly-researched. Answering myself: CVE-2021-33910 only affects systemd, not all FUSE in general.