Nobody is contesting that there’s a chain of events that leads to this, but doing this in the kernel is not “foolish” - it’s batshit insane, amateurish and frankly laughable.
Typically these things happen because people want to reuse code. There's some code that parses executables, there's a bit of shell that wants to display information from an executable, and someone joins the two together without understanding the ramifications.
I would argue that the stronger reason is that Windows typically doesn’t enforce, allow, or contains any distinction between kernel code and user-space code. This happens because there is a gigantic gravity well of pre-existing code that predates and/or precludes real separation, and the costs of concretely losing that support was nearly always judged higher than the abstract benefit of adding separation.
One old example: I have an old friend who used to do sysadmin work in the Windows 2k days, and he would often get gigs by speeding up services by 5-15% within a day. His go-to trick was to log into the headless win2k server and disable the screensaver process, then wait.
Windows NT (and as a result win2k, xp, 7, 8, and 10) has always had strict user and kernel space separation. Modern Windows also has separate 'integrity levels' within user space - for example, Chrome and Firefox run most of their functionality at 'Low' integrity to prevent compromised browser code from being used to exploit other processes. I'm not sure what the basis is for the claims you're making about the kernel. The idea that distinguishing between kernel and user code is Not Allowed is very confusing to me, how would you do that without running both user and kernel code at the same privilege level in a shared address space?
The CVE here literally has nothing to do with privilege separation or being unable to distinguish between user mode and kernel mode. It's this simple:
* Someone in user-space wanted to parse an executable to get information on it
* A syscall is exposed to parse an executable
* They used the syscall to parse the executable, and that code path had a bug in it which triggered a BSOD (since the failure was in kernel mode).
In the end, this is just "a syscall had a bug in it that caused a kernel crash, and a user-mode application issued the syscall on mouse-over".
What is foolish about it? The system already has to know how to map executables for execution, which is strictly harder, and that code better not crash.
If we trusted code to be reliable solely on the basis of how bad it would be if the code broke, we'd probably be inundated with CVEs.
I'm not sure what I'd suggest instead, though - this specific case would be nice if we had kept the parser in userspace, but that just turns "hovering triggers kernel-mode crash" into "attempting to execute causes kernel-mode crash", presumably.
[Rant about wanting more trusted codepaths having static analysis and/or managed languages goes here.]
Where should the OS's executable parser/loader be if not in the kernel? Are you proposing some sort of tiered bootstrapping scheme, where there's a baby loader that's used at boot to load an executable containing the Real Executable Loader, and that lives in a long-running single process with root permissions responsible for loading any and every dll or exe file ever touched on the entire system? I assume you'd issue requests to it via RPC or something, and it'd need to run on multiple threads so that loading executables wouldn't bottleneck. To get back info on the .exe file like the name of the author, you'd probably need to fire off an async request to the Executable Loader Service to ask it to load foo.exe, then fire another request to ask it to RPC the author name back to you, then after all that copying and RPC has happened you gotta send another call back over to free the loaded executable handle. Oh and I guess the executable loader broker service also needs to verify that the process asking for an executable to be loaded has permissions to access the file, since the I/O is being done out of process now, can't forget that. And it needs to make sure that it doesn't let handles leak if the client process crashes in the middle of manipulating the .exe information, otherwise the executable loader broker service could run out of memory and take down the whole system. Seems good.
Then you ask the broker to load this corrupt .exe file, and it crashes, and now your system (which hasn't bluescreened! hooray, we win!) can't run executables anymore. Under those circumstances, I would just take the OS down and generate a dump that someone can open up in a kernel debugger instead of letting it stumble along half-broken in a way that makes the problem hard to diagnose.