[HN Gopher] New fuzzing tool finds USB bugs in Linux, Windows, m...
       ___________________________________________________________________
        
       New fuzzing tool finds USB bugs in Linux, Windows, macOS, and
       FreeBSD
        
       Author : doener
       Score  : 161 points
       Date   : 2020-05-28 09:04 UTC (13 hours ago)
        
 (HTM) web link (www.zdnet.com)
 (TXT) w3m dump (www.zdnet.com)
        
       | pmarreck wrote:
       | Do Bluetooth next! :)
        
         | ComputerGuru wrote:
         | The FreeBSD vuln was in the drivers for a usb Bluetooth dongle,
         | so there is apparently _some_ coverage.
        
       | hannob wrote:
       | I think this needs some important context, because otherwise it
       | may be read as "Linux is so insecure compared to the other OSes".
       | 
       | From the screenshot it seems all of the bugs were found with
       | KASAN and most of them were overread bugs. Likely for the other
       | OSes they were only looking for crashes and probably often missed
       | these classes of bugs that KASAN can uncover.
       | 
       | This essentially means they found more bugs in Linux because
       | Linux has better tools to uncover subtle memory safety bugs.
        
         | muststopmyths wrote:
         | >This essentially means they found more bugs in Linux because
         | Linux has better tools to uncover subtle memory safety bugs.
         | 
         | Driver verifier has been part of Windows for 20+ years and
         | detects memory overflows, underflows, use after free and whole
         | bunch of other bad driver behavior specific to the Windows
         | driver model.
         | 
         | I don't see any evidence in the paper that the authors knew
         | about it, so it's possible more bugs can be found that way in
         | Windows using their fuzzing tools
        
         | frank2 wrote:
         | KASAN is a kernel address sanitizer. Is your claim that the
         | other OSes, as tested, do not do address sanitization?
        
           | johnnyapol wrote:
           | I think their claim is the researchers can run a Linux
           | install with KASAN and see the results but they are unable to
           | use an equivalent of that on MacOSX, Windows as Apple,
           | Microsoft do not allow an end-user to perform that kind of
           | instrumentation on their own device.
        
             | frank2 wrote:
             | You and the person I replied to above are essentially
             | correct:
             | 
             | >Fuzzing drivers on [FreeBSD, MacOS, and Windows] is more
             | challenging than the Linux kernel due to the lack of
             | support infrastructure. These OSes support neither KASAN,
             | other sanitizers, nor coverage-based collection of
             | executions. The lack of a memory-based sanitizer means our
             | fuzzer only discovers bugs that trigger exceptions, and
             | misses all bugs that silently corrupt memory. Because we
             | cannot collect coverage information, our fuzzer cannot
             | detect seeds that trigger new inputs.
             | 
             | (https://nebelwelt.net/files/20SEC3.pdf)
             | 
             | The researchers employed a partial workaround for the
             | problem, but it is pretty obvious to me that the partial
             | workaround does not level the playing field:
             | 
             | >To alleviate the second concern, the lack of coverage-
             | guided optimization, we experiment with cross-pollination.
             | To seed our dumb fuzzer, we reuse the inputs generated
             | during our Linux kernel fuzzing campaign.
        
               | my123 wrote:
               | XNU definitely supports kasan on macOS, since quite some
               | years. (however, kasan kernels aren't shipped by default,
               | you can build from source though)
               | 
               | However, no idea if Kernel Debug Kit ships with prebuilt
               | kasan kernel and drivers.
        
               | saagarjha wrote:
               | I see a kernel.kasan inside the latest KDK. Doubt this
               | extends to drivers, as all I can find for those are debug
               | symbols.
        
               | zxombie wrote:
               | They are only partially correct about FreeBSD. In FreeBSD
               | 12 there is no coverage sanitizer as it was added to 13
               | and never merged to 12.
               | 
               | Support for KASAN, and the other sanitizers is in
               | development, however I'm currently too busy working on
               | other things to have time to finish it.
        
         | jmeyer2k wrote:
         | Instrumentation is huge too...
         | 
         | I had a bug with the webcam on my Razer Blade which I was able
         | to fix on Linux because it was open-source. It was a pretty
         | simple patch and I submitted it as a patch to Linux.
         | 
         | I had a bug with USB devices on my Mac and I had to go back and
         | forth with Apple support for 2 weeks and ended up returning the
         | device.
        
       | lloeki wrote:
       | (Honest, naive question, I lack awareness of the Linux versioning
       | scheme) Isn't Linux way into 5.x land for quite some time? Is the
       | testing of 4.20-rc2 some kind of proxy to test there were no
       | backports of the very latest mainline?
       | 
       | ----
       | 
       | Researchers said they tested USBFuzz on:
       | 
       | 9 recent versions of the Linux kernel: v4.14.81, v4.15,v4.16,
       | v4.17, v4.18.19, v4.19, v4.19.1, v4.19.2, and v4.20-rc2 (the
       | latest version at the time of evaluation) FreeBSD 12 (the latest
       | release) MacOS 10.15 Catalina (the latest release) Windows (both
       | version 8 and 10, with most recent security updates installed)
        
         | cmeacham98 wrote:
         | The linux kernel has several LTS releases for people who want
         | to stay on the same version for stability reasons but also need
         | security updates. I suspect from a security perspective testing
         | whatever the latest 4.19.X version is would be roughly
         | equivalent to 5.X.
         | 
         | (Except, perhaps, for any USB-related features introduced in
         | 5.X)
        
         | codys wrote:
         | Since v3.0, Linux has treated the first _2_ numbers of it's
         | version as something that is incremented sequentially (in the
         | v2.6 era, the _3_rd number was used, prior to v2.6 there was a
         | even/odd stable/unstable split)
         | 
         | For example, we have normal releases v4.19 then v4.20 then v5.0
         | then v5.1. There will never be a v4.21.
         | 
         | Stable releases use the third number. v4.14.81 is a stable
         | release of v4.14.0.
         | 
         | So the v4.20-rc2 statement just dates the work:
         | $ git show v4.20-rc2         tag v4.20-rc2         Tagger:
         | Linus Torvalds <torvalds@linux-foundation.org>         Date:
         | Sun Nov 11 17:12:54 2018 -0600
        
           | gpm wrote:
           | Woah, so they did this a year and a half ago despite
           | releasing this year (note that the paper has a 2020 reference
           | in it). Weird!
           | 
           | I guess responsible disclosure timelines on this sort of work
           | must really suck.
        
             | 0xffff2 wrote:
             | I don't know about computer security, but I've published
             | peer reviewed research papers in other fields and a year
             | and a half from data collection to publication doesn't seem
             | unusual to me. If anything it's pretty fast.
        
       | pjmlp wrote:
       | And the winners are:
       | 
       | - 2x double-free
       | 
       | - 8x NULL pointer dereference
       | 
       | - 6x general protection
       | 
       | - 6x slab-out-of-bounds access
       | 
       | - 14x use-after-free access
       | 
       | Naturally it was only due to the current shortage of those
       | mythical C developers that never make memory corruption mistakes.
        
         | tinus_hn wrote:
         | I think part of the problem is the attitude that if your
         | hardware is compromised so is the software, so you don't need
         | to account for the more insane inputs. After all, at least it
         | doesn't make much sense to have a device send special packets
         | to cause DOS when it can for instance just blow up the system
         | by causing electrical overload.
         | 
         | Still better to have these issues fixed.
        
         | rlpb wrote:
         | > Naturally it was only due to the current shortage of those
         | mythical C developers that never make memory corruption
         | mistakes.
         | 
         | Ah - you'd prefer to use the that mythical equivalent kernel
         | written in Rust instead?
        
         | sanxiyn wrote:
         | Naturally. Where are they? They should be the ones developing
         | operating systems, not these charlatans.
        
         | nsajko wrote:
         | You have no proof that writing a Linux-like kernel in Rust
         | would result in fewer bugs, or even that it is feasible at all
         | (what with writing even linked lists being difficult).
        
           | jabedude wrote:
           | >or even that it is feasible at all (what with writing even
           | linked lists being difficult).
           | 
           | You're right, a Rust OS kernel probably wouldn't use linked
           | lists but I'm not sure why that is a barrier to making a
           | kernel. The redox[0] kernel is written entirely in Rust.
           | 
           | [0] https://www.redox-os.org/
        
             | nsajko wrote:
             | That is why I said "Linux-like". Redox has a microkernel
             | design, which presumably makes writing the drivers in Rust
             | much easier at the expense of some throughput and latency.
        
           | monocasa wrote:
           | Linked lists are difficult, but can be abstracted behind a
           | library.
           | 
           | Here's a no_std intrusive linked list library I've used in
           | kernel environments. https://docs.rs/intrusive-
           | collections/0.9.0/intrusive_collec...
           | 
           | It's not like you reimplement linked lists in every driver in
           | the Linux kernel either; you include linux/list.h like
           | everyone else.
        
           | black_puppydog wrote:
           | But "use rust" seems to be obvious enough as a solution that
           | you simply assumed that's the direction GP is going? :)
           | 
           | Honest question though: shouldn't it be possible to only
           | write single kernel _modules_ (like drivers) in rust, without
           | switching out the entire OS at once?
        
             | black_puppydog wrote:
             | Answering myself here: _of course_ someone else already did
             | that. :)
             | 
             | https://github.com/fishinabarrel/linux-kernel-module-rust
        
           | pjmlp wrote:
           | No I don't, but there are surely proofs in Ada, PL/I, PL/S,
           | NEWP.
        
             | AnimalMuppet wrote:
             | Well... I'm going to guess that the largest kernel written
             | in PL/I was at least one order of magnitude smaller than
             | Linux, and probably two orders of magnitude smaller. I'm
             | also going to guess that it was never subject to a 2020
             | state-of-the-art fuzzer. (I'm even going to guess that it
             | never had USB support.) So, while you may have a point,
             | your comparison is hardly apples-to-apples.
        
           | Someone1234 wrote:
           | I mean it is obviously possible. Rust can do anything that C
           | can do, literally.
           | 
           | Your question is mixing safe and unsafe Rust as if they're
           | one and the same. What I think you meant to ask is "Can Linux
           | be implemented in safe Rust?" And my answer would be "likely
           | not, but the goal is to limit the number/size of unsafe
           | sections, so that they can be QA-ed harder and bugs
           | discovered."
           | 
           | When you write C/C++, 100% of that codebase is unsafe. When
           | you write Rust, even a kernel, should be 80/20 safe/unsafe or
           | less. That's where the improvements come from.
        
             | pml1 wrote:
             | > When you write C/C++, 100% of that codebase is unsafe.
             | 
             | Don't you think that statement is a bit over-the-top ?
             | Large parts of C/C++ codebases are just as safe as the
             | equivalent Rust code, as it doesn't do any pointer/memory
             | manipulation.
             | 
             | For example, how is making a os system call in Rust any
             | safer than the equivalent call in C ?
        
               | gpm wrote:
               | If you mean literally writing                   asm!("
               | mov eax,1  ; system call number (sys_exit)
               | int 0x80  ; call kernel         ")
               | 
               | Obviously both are equally unsafe, also obviously both
               | are extremely rare and not "large parts" of any program
               | whatsoever (unless you're writing your program directly
               | in assembly).
               | 
               | If you mean using the wrapper libraries that typically
               | wrap system calls. Rust removes all sorts of possible
               | fuckups. For instance in C one might write
               | ssize_t bytes = read(some_file, buf, nbyte);
               | 
               | and if buf is null or a dangling pointer or nbyte is
               | greater than the size of the allocation of buf you get
               | undefined behavior. Or if afterwards you write
               | printf("%s", buf);
               | 
               | and you forgot that read doesn't necessarily return a
               | null terminated string you get undefined behavior. And so
               | on and so forth.
               | 
               | In rust you would write something like
               | let mut buf = [0; nbyte];         let bytes =
               | some_file.read(&mut buf)?;
               | 
               | and buf can't possibly be null or dangling and you can't
               | possibly have messed up the length of the array because
               | the abstractions checked that for you.
               | 
               | Afterwards if we were to write
               | println!("{}", buf);
               | 
               | Well it will fail to compile... because buf isn't a
               | string... and doesn't otherwise implement Display. But if
               | we were to try to match the C code exactly and write one
               | of                   stdout().write_all(buf)?;
               | println!("{}", str::from_utf(&buf)?);
               | 
               | the second one would return an error if it wasn't a utf8
               | string, but neither would ever result in undefined
               | behavior/security vulnerabilities.
               | 
               | (And yes, both of those are probably bugs in most
               | programs, since you probably want to print buf[.. bytes]
               | not buf. But bugs aren't security vulnerabilities. Also
               | in real code I expect you would use read_to_string() if
               | you were going to print it, which eliminates this
               | potential bug too)
        
             | nsajko wrote:
             | You are oversimplifying. Both of the languages being
             | Turing-complete does not imply Rust being as good a choice
             | for talking to hardware as C is. What I am getting at is:
             | the imaginary Rust replacement for Linux may have ten times
             | as much code as Linux does and be unmaintainable.
             | 
             | Rust's safe mode eliminates the possibility for some
             | classes of bugs, but this still does not imply the
             | hypothetical Rust kernel would be more reliable than Linux.
             | What I am getting at is: Rust is a quite different language
             | than C, and the hypothetical Linux replacement in Rust
             | _could_ be buggier than Linux.
             | 
             | Regarding the above, my message is not that I know that
             | Rust is worse than C for some applications; but rather that
             | Rust fans and C haters are not even addresing those points.
             | pjmlp deftly avoided saying anything explicitly, but still
             | he should for the sake of the discussion and decency at
             | least try to address those points while making such
             | distasteful comments as "Naturally it was only due to the
             | current shortage of those mythical C developers that never
             | make memory corruption mistakes.".
        
         | iforgotpassword wrote:
         | That would be me, unfortunately I don't have time currently to
         | work on the kernel.
        
         | bluescarni wrote:
         | It's worth noting that many of these issues likely wouldn't
         | have been possible with the use of RAII semantics.
        
           | Someone1234 wrote:
           | So you're saying if the code was higher quality it would have
           | fewer bugs? I mean, well, yeah.
           | 
           | The problem with solutions like RAII is that it doubles down
           | on programmer infallibility, from "good programmers don't
           | write bugs" to "good programmers correctly use RAII."
           | 
           | You haven't really solved the actual problem unless you have
           | tooling available that won't let non-RAII be checked in at
           | all. Does that exist?
        
         | MaxBarraclough wrote:
         | Hypothesis: the more fuzzing tools we develop, the fewer
         | infallible C programmers remain.
        
           | Gravityloss wrote:
           | I'm reminded of this apocryphal story of a revered machinist
           | from Tampere. The city is on an isthmus between two lakes.
           | Their shop was right next to the rapids between the lakes.
           | They were famous, having never made any mistakes.
           | 
           | During some construction event, the city closed off the
           | rapids and no water was flowing there, it was completely dry.
           | There was a massive amount of partially machined objects on
           | the bottom. The machinist had been tossing them out of the
           | window into the water, every time when they made a mistake.
        
             | MaxBarraclough wrote:
             | So the machinist had been using rigorous testing, catching
             | all defects prior to release, rather than using a correct-
             | by-construction methodology. Either approach seems fine.
        
               | monadic2 wrote:
               | Well, apparently it didn't catch the defect that
               | mattered. Typical engineer trying to justify an
               | engineering mistake!
        
               | bluGill wrote:
               | Neither is perfect. Tests are only as good as your
               | imagination of what to test. Proof by construction is
               | only as good as your ability to have the right axioms
        
               | MaxBarraclough wrote:
               | > Tests are only as good as your imagination of what to
               | test.
               | 
               | A lot of work has been done on code-coverage, boundary-
               | analysis, etc. Testing can never be complete, though.
               | 
               | > Proof by construction is only as good as your ability
               | to have the right axioms
               | 
               | That's not a good summary of the challenges that formal
               | methods face with respect to correctness. Defects can
               | creep in at various points.
               | 
               | See p. 46 of the PDF linked from
               | https://www.adacore.com/tokeneer
        
               | hawski wrote:
               | He never had problem with use-after-free, because he was
               | leaking memory.
        
         | gsnedders wrote:
         | In many ways I'm most interested in the Windows bugs: Windows
         | 8+ has a model-checked USB stack written in P
         | (https://github.com/p-org/P). Or maybe that's just the USB 3.0
         | stack? Either way, would be interested in whether they're in
         | the integration code or bugs in the P compiler.
        
           | [deleted]
        
         | melling wrote:
         | I'm not a Rust programmer but usually one interjects to say
         | that Rust would have prevented [some of] these issues.
         | 
         | Does Rust in fact prevent most of these at compile time? Any
         | that it does not?
        
           | smallstepforman wrote:
           | Rust didnt exist when these kernels were written. A mature
           | kernel written in Rust still doesn't exist.
           | 
           | Modern toolchains can effectively warn about nemory/pointer
           | issues. I cant wait for a C++2x proposal to add Rust like
           | memory semantics to the language - primarily to shut Rust
           | fanboys up. Also, Rust does not warn about threading race
           | conditions, you'd need a reference capabilities like language
           | (Pony without ORCA) for that.
        
             | teknopaul wrote:
             | Rust does warn about threading race conditions. Kinda magic
             | but it does. It prevents them.
        
               | 0xffff2 wrote:
               | Could you elaborate? AFAIK, Rust entirely prevents data
               | races between threads, but it doesn't do anything special
               | at all for other kinds of race conditions.
        
           | eeZah7Ux wrote:
           | RIIR spam is not useful. People on HN are already aware of
           | Rust.
           | 
           | Some are aware that many other langs are memory safe and yet
           | that's not a reason enough to rewrite a kernel.
        
             | gpm wrote:
             | You're the first one in this thread to bring up the idea of
             | rewriting the linux kernel in rust... the rest of us are
             | just having a productive discussion on the degree to which
             | a language solves a problem.
        
           | elwes5 wrote:
           | I would argue that Rust removes a class of bugs. Not because
           | the language is better, but because the compiler just does
           | not allow it. It will not let you build your executable if
           | that type of bug exists. For example you could still do
           | something like a SQL injection attack using something
           | compiled with Rust. The C compilers should be doing the same
           | as Rust (some are, but usually at the warn level). Static
           | analysis is not a new thing.
           | 
           | Usually the best thing any C/C++ developer can do is crank
           | the warn levels as high as they can go. Then set the project
           | to error out on warn. A good code smell for a project is when
           | you see one that has turned off warnings. Usually the reason
           | is 'too noisy'. I always tell my junior devs the same thing
           | 'the compiler is trying to tell you something all you have to
           | do is listen'.
        
             | nitrogen wrote:
             | The next level after fixing all compiler warnings is
             | running under Valgrind's different modes to catch many more
             | memory and threading bugs.
        
           | sanxiyn wrote:
           | Yes it does. Not most of these, but all of them.
        
             | cesarb wrote:
             | No, that's untrue. For instance, Rust doesn't prevent an
             | out-of-bounds access at compile time; it just converts an
             | out-of-bounds access into a panic at run time. That is, it
             | reliably aborts the program (or the thread), instead of
             | reading or writing out of the bounds of the object.
             | 
             | The same for "NULL pointer dereference"; the Rust
             | equivalent (without using raw pointers, which require
             | "unsafe") is calling .unwrap() on an Option<T> which has a
             | None, which once again is not prevented at compile time,
             | only converted into a panic at run time.
             | 
             | Edit: note, however, that idiomatic Rust can help prevent
             | these bugs, by using iterators instead of indexed access,
             | and match/if-let statements instead of unwrap/expect.
        
               | jjnoakes wrote:
               | There's quite a huge difference between undefined
               | behavior (dereferencing NULL or indexing out of bounds)
               | which can lead to remote code execution and other super
               | nasty bugs, and runtime checks which panic and abort the
               | process reliably and in a well-defined way.
        
             | pml1 wrote:
             | really ? You've checked all the code in question and you
             | are a 100% sure that you would have required _zero_ unsafe
             | code ?
             | 
             | Drivers by their very nature require a lot of unsafe
             | pointer passing...Having worked on a lot of embedded Linux
             | driver code, I'm not convinced that you could do without a
             | ton of unsafe code...which basically negates all of Rust's
             | safety guarantees...The current architecture just doesn't
             | lend itself well to Rust (in my opinion), so you would have
             | to basically rewrite very large parts of the plumbing,
             | which by its very nature would introduce a ton of new
             | bugs...
        
               | Tobu wrote:
               | Rust has the concept of "interior unsafe".
               | 
               | The idea is that you build an abstraction and wrap away
               | the unsafety. That abstraction has to be built
               | defensively, which is enabled by the type system
               | enforcing very powerful invariants across the program.
               | You can safely encode the way your structures may or may
               | not be used across threads, enforce exclusive vs shared
               | access, control mutability.
               | 
               | Unsafe is not a "do whatever" card, you use it with the
               | rest of the language as one more tool that helps build
               | safe programs.
        
               | gpm wrote:
               | For the most part rust handles pointer chasing in safe
               | code just fine.
               | 
               | Drivers are a fundamentally unsafe concept, like an ffi
               | call, you're talking to hardware the compiler doesn't
               | understand and assuming it's going to do what you want.
               | So there will of course be some unsafe. In a well
               | implemented driver it will also be very limited in scope
               | and relatively easy to check.
               | 
               | I can't vouch for the code quality (I just don't know how
               | good it is, I had no hand in writing it, and it's not
               | used in a production system), but I believe you can find
               | a usb driver implementation written in rust here:
               | https://gitlab.redox-os.org/redox-
               | os/drivers/-/tree/master/x...
        
               | pml1 wrote:
               | >So there will of course be some unsafe. In a well
               | implemented driver it will also be very limited in scope
               | and relatively easy to check.
               | 
               | I'm sure that is what the C developer thought as
               | well...I'm not trying to be snarky, but that same
               | arguments that are made against C code holds equally true
               | for unsafe code...
               | 
               | I don't think it is a reasonable position to suggest that
               | unsafe Rust code is somehow safer than C code...
        
               | gpm wrote:
               | The point isn't that unsafe rust code is safer than C
               | code, but that there is many orders of magnitude less
               | unsafe rust code than c code in a driver of the same
               | size.
        
               | teknopaul wrote:
               | Unsafe rust is safer than C for two reasons.
               | 
               | You can limit what comes in from safe rust.
               | 
               | Unsafe rust still has more compiler checks than C. Unsafe
               | rust is not as permissive as C. Its rust still, with
               | certain things permitted.
               | 
               | Its unsafe{} not nosafe{}
        
           | gpm wrote:
           | - 2x double-free
           | 
           | Yes, it would be very weird to manage to do this in rust. It
           | would require screwing up badly in unsafe code. I guess the
           | most likely way to fuck up unsafe code in this way would be
           | to screw up a custom datastructure like a custom reference
           | counted pointer (but the obvious solution is to just use the
           | standard ones).
           | 
           | - 8x NULL pointer dereference
           | 
           | Yes, rust tells you when pointers might be Null (which is
           | represented by saying the pointer is Option<PointerType>
           | instead of just PointerType), and doesn't let you use the
           | pointer in a way that implicitly assumes it isn't null.
           | 
           | - 6x general protection
           | 
           | These are generally memory errors, and are certainly
           | undefined behavior, so yes.
           | 
           | - 6x slab-out-of-bounds access
           | 
           | "Yes" with a small caveat, depending on how you are using the
           | slab it is likely that Rust doesn't force you to explicitly
           | think about the out of bounds case and turns just silently
           | turns the security vulnerability into a runtime error, which
           | might be handled farther up the stack or might cause the
           | kernel to halt.
           | 
           | - 14x use-after-free access
           | 
           | Yes, like double frees. The range of possible fuckups in
           | unsafe code that cause this is probably slightly larger than
           | the equivalent range for double frees.
        
             | _pmf_ wrote:
             | > These are generally memory errors, and are certainly
             | undefined behavior, so yes.
             | 
             | USB registers might be in DMA buffers or another memory
             | location that might get mapped/unmapped at any point. Not
             | everything fits a simplistic linear memory model.
        
               | asveikau wrote:
               | This is an interesting point. Rust's borrow checker or
               | bounds checks probably also can't know about a page table
               | change happening underneath it. Anyone want to correct me
               | on that?
        
               | gpm wrote:
               | There's no fundamental reason why you couldn't write an
               | abstraction around the page table that the rust borrow
               | checker understands.
               | 
               | The rust borrow checker works on the principle of
               | ensuring that if you have a unique pointer (&mut) to
               | something, nothing else can access it. If you have a
               | shared pointer (&) to something, nothing else is mutating
               | it except where internal mutability is explicitly marked
               | (UnsafeCell, and abstractions using UnsafeCell such as
               | Cell, RefCell, Mutex, RwLock, and so on).
               | 
               | To mutate a page table entry you would need an &mut
               | reference to it, to access a page you would need an &
               | reference to the page table entry (from the
               | &PageTableEntry you would get a &[u8] pointing to the
               | data which the borrow checker would guarantee you drop
               | before you drop the &PageTableEntry before anything
               | mutates the PageTableEntry).
        
               | steveklabnik wrote:
               | This isn't exactly what you're asking about, but I really
               | really love https://os.phil-opp.com/paging-
               | implementation/
               | 
               | Shows you how you might implement paging, and how much
               | unsafe you need to do so.
        
               | monocasa wrote:
               | It's pretty easy to wrap those constructs in RAII
               | wrappers to replace or augment the normal reference
               | counting that C code would be using to keep those buffers
               | mapped, along with associating the lifetime of the
               | relevant buffers with that refcnt.
               | 
               | So it won't be perfect, but you can add safety versus
               | what you get in C. You can even add safety versus what
               | you'd get in C++ because of the lifetimes you can
               | associate.
        
               | asveikau wrote:
               | I know it's possible to reference count a page table
               | mapping, in any language. My question is has anybody
               | really attempted it in a rust kernel to make the sort of
               | automatic safety measures we know rust for mean anything
               | at all. It seems like if you really want correctness,
               | every allocation must bump such a recount, which is very
               | expensive.
        
               | gpm wrote:
               | So the general trick with reference counted pointers in
               | rust, is that you don't have to touch the allocation
               | count when creating a new pointer as long as you already
               | have a pointer that you know lives for longer than your
               | new pointer, and the rust type system will check that you
               | didn't make a mistake when you thought you did.
               | 
               | I.e. say I have a `x: Rc<[u8]>`, that is a ref counted
               | pointer to some memory, and a length of that memory. I
               | can do `let y: &[u8] = &x;`. `y` is now a not-ref counted
               | pointer to the same memory (with the same length), that's
               | guaranteed to be dropped before `x` is so the memory
               | won't be freed from under it. I can also do `let z: &u8 =
               | &x[5]`. `z` is now a pointer to a byte in `x`. Like `y`
               | it's not ref counted and the compiler will force us to
               | drop it before we drop `x`.
               | 
               | You can make a whole allocator in this fashion (people
               | have, even in the standard library I believe). If you get
               | really clever you can probably even make an allocator in
               | this fashion where the _allocator_ doesn 't use any
               | unsafe code, you can easily make one where the users of
               | the allocator don't need any unsafe code.
        
             | pml1 wrote:
             | So the same argument that is made against the "mythical C
             | programmer that never makes memory corruption mistakes" is
             | also valid for the mythical Rust developer that never makes
             | mistakes in unsafe code... It's two sides of the same coin.
        
               | monocasa wrote:
               | Except unsafe blocks are rare and heavily marked as "this
               | is where the unsafeness is".
        
               | pml1 wrote:
               | It won't be rare in driver code.
        
               | ComputerGuru wrote:
               | I've written bare metal code for rust that does
               | networking and had only a handful of `unsafe` usages, and
               | none after startup/init was completed. It's actually
               | really incredible how far "simple" shared-read-vs-
               | exclusive-write bound checking and a very strict (but
               | capable/likely Turing complete) type system can take you.
        
               | monocasa wrote:
               | It absolutely will, particularly in USB code. USB devices
               | other than host controllers don't have memory mapped
               | registers for instance, it's basically a network
               | protocol.
        
               | samsari wrote:
               | Except in rust unsafe code is very much not the norm, and
               | much easier keep an eye on. Anyone writing rust worth
               | their salt should be paying 5 times as close attention to
               | every line of unsafe code for exactly this reason.
        
               | spieglt wrote:
               | But overall the two situations aren't nearly equivalent.
               | Writing C, you're constantly at risk of making these
               | mistakes. Writing Rust, you can keep the vast majority of
               | your code safe and more closely examine the smaller
               | unsafe area for memory errors. (In driver development,
               | you may have to use more "unsafe" than for application
               | development, but this doesn't negate the benefits. Also
               | the compiler output is much more helpful.)
        
               | pml1 wrote:
               | > Writing C, you're constantly at risk of making these
               | mistakes. Writing Rust, you can keep the vast majority of
               | your code safe and more closely examine the smaller
               | unsafe area for memory errors.
               | 
               | I think this is a fallacy...The majority of C code
               | doesn't manipulate pointers either. The point is, the
               | moment that you have _any_ unsafe code (C or Rust), it's
               | a question of time before you will have some bugs,
               | especially if you have a very large number of people
               | working on the same code base...you may be extra careful,
               | maybe the next guy is not...Rust is not going to
               | magically solve these problems for unsafe code...
        
               | toyg wrote:
               | I think you guys are debating whether perfect is the
               | enemy of the good.
               | 
               | Rust will not make your code magically bugfree (this is
               | basically impossible by definition), but it will
               | undoubtedly reduce the number of bugs in a very
               | significant way and nudge you towards better code.
        
               | spieglt wrote:
               | Exactly, it's a difference in degree, not in kind. Rust
               | isn't perfect with regard to memory errors, it's just
               | massively better than C. I don't think pml1 will be
               | convinced, but I've been working on a C project lately
               | and I've never appreciated Rust's memory virtues so much
               | as when using valgrind to debug my string and hashmap
               | implementations. Chased a memory leak for two evenings
               | that was just having free() a few lines off in a
               | function. Stupidly simple error, but my eyes just glazed
               | over the code from having read it so many times. In Rust,
               | it never would've happened because the borrow checker
               | would've dropped the memory at the proper time.
        
             | josephcsible wrote:
             | I don't think Rust really makes NULL dereferences any
             | better. In practice, a NULL dereference in C is almost
             | always "just" a crash that can't be turned into something
             | worse (unlike the rest of these kinds of bugs), and Rust
             | makes it really easy to call "unwrap", which if your Option
             | is None... crashes.
        
               | gpm wrote:
               | Explicit `unwrap` (rust) is really orders of magnitude
               | better than implicit `unwrap` (c dereference if you're
               | lucky and the compiler hasn't optimized based on the
               | assumption that the pointer is non-null). There aren't
               | actually many explicit unwrap's in practical code, and
               | they're something you notice when auditing or reviewing
               | the code. The change in type means both the caller and
               | the callee almost always agree on whether or not the
               | contract is that "this pointer can be null" or "this
               | pointer isn't null".
        
               | cesarb wrote:
               | > In practice, a NULL dereference in C is almost always
               | "just" a crash that can't be turned into something worse
               | 
               | No, in C a NULL pointer dereference is not a crash, it's
               | _undefined behavior_ (which yes, can manifest as a
               | crash), which is much more unpredictable.
        
               | Tobu wrote:
               | Indeed.
               | 
               | For anyone still believing a NULL dereference (or any of
               | the other UB that is in the C spec) is just a segfault,
               | "What Every C Programmer Should Know About Undefined
               | Behavior" is still required reading:
               | 
               | http://blog.llvm.org/2011/05/what-every-c-programmer-
               | should-...
               | 
               | Here's how triggering UB ends up as a vulnerability:
               | 
               | https://lwn.net/Articles/342330/
        
               | suyjuris wrote:
               | > Here's how triggering UB ends up as a vulnerability
               | 
               | To be fair, dereferencing NULL ended up as a
               | vulnerability due to
               | 
               | 1. the optimiser removing the subsequent NULL check, and
               | 
               | 2. the zero page being mapped.
               | 
               | While 1. may happen, depending on how sophisticated the
               | compiler is, 2. was already a security issue and is
               | 'almost always' not the case.
        
       | izacus wrote:
       | I wonder if any USB device actually relies on these bugs being
       | there to operate correctly.
        
         | jeffbee wrote:
         | Hard to imagine a device that relies upon use-after-free
         | defects for its correct functioning.
        
           | VRay wrote:
           | Me: _laughs in firmware engineer_
        
           | not2b wrote:
           | Obligatory xkcd: https://xkcd.com/1172/
        
           | saagarjha wrote:
           | Not sure about hardware devices, but I have encountered
           | software that has relied on using freed memory to function as
           | intended.
        
       | fsflover wrote:
       | I am glad I am using Qubes OS, which isolates usb devices from
       | the rest of the system.
        
         | cerberusss wrote:
         | macOS is also moving into this direction:
         | https://developer.apple.com/system-extensions/
         | 
         | "DriverKit provides a fully modernized replacement for IOKit to
         | create device drivers. System extensions and drivers built with
         | DriverKit run in user space, where they can't compromise the
         | security or stability of macOS."
        
           | saagarjha wrote:
           | Sadly, DriverKit doesn't actually address all the reasons why
           | you'd want a kernel extension.
        
             | monadic2 wrote:
             | Do you have an example?
        
         | brundolf wrote:
         | I always assume plugging in an untrusted USB to be security-
         | suicide. At least on Windows it can run arbitrary code, _by
         | design_. Given that, these bugs don 't really affect my threat
         | model at all.
        
           | nsajko wrote:
           | It's not just about software security, a simple USB device
           | can fry its host (your computer).
           | 
           | https://en.wikipedia.org/wiki/USB_Killer
           | 
           | https://hackaday.com/2015/03/11/killer-usb-drive-is-
           | designed...
           | 
           | https://hackaday.com/2015/10/10/the-usb-killer-version-2-0/
        
           | teknopaul wrote:
           | I'm pretty sure I dont have an evil maid.
           | 
           | I do wince as my mate, who works as a binman, tests found
           | devices on a Windows laptop.
           | 
           | So far he has got is about a terrabyte of free storage and no
           | problems.
        
             | jfk13 wrote:
             | > and no problems
             | 
             | ...that he knows about.
        
         | blaser-waffle wrote:
         | How is Qubes? Was thinking about a Purism laptop w/ Qubes as a
         | way of indulging my paranoia.
         | 
         | It's a cool idea and I've been lookin at it for a while, but it
         | seems onerous to isolate everything.
        
           | fsflover wrote:
           | Librem 15 is exactly what I am using with Qubes. It is my
           | daily driver. Isolation not only helps against threats but
           | also helps to organize my work and life. Unbelievably easy
           | backups help too.
        
         | lokedhs wrote:
         | Me too. However, I can't run it on one of my computers because
         | I need to do development on it which requires the GPU.
         | 
         | I really wish there was a reasonable solution for using the GPU
         | with Qubes. If that existed I wouldn't have to use any other
         | distribution, ever.
        
           | NullPrefix wrote:
           | Have you tried GPU passthrough? Will need two GPUs for that
           | though.
        
             | AnIdiotOnTheNet wrote:
             | Seems like a pretty ridiculous hoop to have to jump
             | through.
        
               | [deleted]
        
               | NullPrefix wrote:
               | What do you mean? The two GPUs or the part where you need
               | to give the VM a GPU if you want that VM to have a GPU ?
        
       | jokoon wrote:
       | Pretty sure the NSA has been using similar tools for at least 10
       | years now.
        
       | peter_d_sherman wrote:
       | >"At its core, USBFuzz uses a _software-emulated USB device_ to
       | provide random device data to drivers (when they perform IO
       | operations), " the researchers said."
       | 
       | The key to sniffing out all of these "bugs" (AKA, "security
       | concerns") is to be able to _emulate_ , _emulate_ , _emulate_ ,
       | everything as plug-in modules -- even down to hardware itself.
       | 
       | Virtual machine software does this -- but bugs (AKA, "security
       | concerns") have been found in Virtual Machines too, so a "welded
       | together at the seams" Virtual Machine is not the answer -- but
       | rather, a modular, plug-and-play, open interface one is -- where
       | the data moving into and out of interfaces can be monitored,
       | logged, recorded, played back, analyzed, and modified easily to
       | implment a test condition or conditions, as need be.
       | 
       | A _software emulated USB device_ -- is a good step towards this
       | vision.
       | 
       | It's sort of like if we rebuilt a virtual machine from the ground
       | up, starting with the CPU emulation, and then said, OK, do I want
       | to emulate this piece of hardware in the virtual machine software
       | itself, or do I want to proxy it out, maybe via a serial path,
       | ethernet/socket/ tcp/ip connection, or shared memory proxy to
       | another plug-and-playable (and separately testable) module...
       | 
       | I think we need to rethink virtual machines as they exist today.
       | Coding an interface in C for an existing virtual machine and
       | saying that the job is done is not enough; virtual machines must
       | become vastly more modular/proxyable than they are today. The bus
       | of such a machine must become virtual and proxyable as well, such
       | that 3rd party software, modular plug-ins, could observe it in
       | realtime, as should memory, emulated VGA card, etc... any point
       | there's a connection to hardware, real or virtual is a proxy
       | point that must be modular and auditable by 3rd party plug-in
       | programs...
       | 
       |  _THAT 's_ how you write the virtual machines/systems of the
       | future.
       | 
       | Which also become the debugging systems of the future...
       | 
       | In fact, such a "modular virtual machine" -- could be used by AI
       | driven software to run unit tests, but run them with different
       | combinations of VGA cards, emulated CPU's, emulated BIOS'ses,
       | buses, controller chips, what-have-you...
       | 
       | Oh... and there should be a way to interface the VM with actual
       | hardware chips... in other words, I have a hardware chip that is
       | in question... emulate the entire rest of the system, but proxy a
       | physical connection to that chip on a breakout board... etc.
        
         | sitkack wrote:
         | And the underlying hardware should be designed to virtualize
         | its PCIe registers, many accelerators do this, but it should be
         | transparent to both plumb the virtualized register sets into a
         | guest but also interpose those register sets to build a dynamic
         | out of band firewall to same said hardware.
        
         | jfkebwjsbx wrote:
         | Such a system wouldn't be a VM but an emulator. They already
         | exist and are routinely used. There are also specialized low
         | level emulators, too, and even logic analyzers at the
         | electronics level.
         | 
         | But all that does not really help fuzz a kernel quickly, which
         | is much better done with a normal VM plus an emulated device,
         | as the researchers did.
        
       | conistonwater wrote:
       | The paper itself: https://nebelwelt.net/files/20SEC3.pdf
        
       | Koshkin wrote:
       | http://www.usbmadesimple.co.uk/
       | 
       | (tl;dr: USB is anything but simple.)
        
       | aspenmayer wrote:
       | None of this is directed at OP.
       | 
       | Not to be _that guy_ , but I posted this many hours ago.[1] I
       | don't care about the karma, but this is a repost.
       | 
       | @dang, can anything be done to help HN not work like this in the
       | future? Why have karma for posts but then allow reposts like
       | this? It disincentivises first posts in favor of gaming the
       | viewers of HN while trying not to get scooped. It sucks. None of
       | this is directed at OP.
       | 
       | [1] https://news.ycombinator.com/item?id=23329790
        
         | kick wrote:
         | He's expressed interest in the past about fixing this; he's not
         | sure how to handle it yet:
         | 
         | https://hn.algolia.com/?dateRange=all&page=0&prefix=true&que...
         | 
         | That said, two things:
         | 
         | You should send a message to hn@ycombinator.com if you have
         | something to say to moderation. They're very responsive, and
         | you'll get a better response rate than posting in random HN
         | threads that might not even be seen. It also breaks the
         | Guidelines:
         | 
         |  _Please don 't post on HN to ask or tell us something. Send it
         | to hn@ycombinator.com._
         | 
         | https://news.ycombinator.com/newsguidelines.html
         | 
         | You also shouldn't take this personally. The poster likely
         | didn't see your post, _very_ likely wasn 't 'gaming' anything
         | (they actually have some really interesting articles in their
         | submission history that don't seem to have been posted before,
         | and they're a journalist; it was likely they just read it and
         | posted it), and it wouldn't be practical to 'ban reposts': HN
         | already has a feature that upvotes a previous submission if you
         | post within a given range from it.
         | 
         | I know it's not a great feeling to post something that you
         | think is interesting and to see it get to the front page later
         | via someone else (I can point to a bunch of my own posts where
         | this happened), but it getting to the front page at all is
         | something positive. It's not a race, so incentivizing quick-
         | draw on articles from popular outlets (like zdnet, which has
         | millions of readers) above all else probably wouldn't be
         | useful, either.
        
           | aspenmayer wrote:
           | I don't care to do that. It's a problem with basic
           | functionality. There is site behavior which disallows
           | reposts, but only sometimes. The sometimes part is the bug,
           | from my point of view. I honestly don't care enough to do
           | anything but say it shouldn't happen when it happens to me,
           | as long as it happens to me. Bug reports should be public for
           | non-security related bugs.
           | 
           | This is a bug. This thread is my report. I can be reached on
           | this thread.
           | 
           | Edit: I have emailed and asked that replies are in-thread or
           | linked to in this thread. I hope we can get some clarity into
           | whether this is a "won't fix" situation or more of a
           | subjective call on a per-case basis, or something else
           | entirely.
           | 
           | I don't want to make waves, just trying to surf.
        
             | dang wrote:
             | Take a look at the past explanations at https://hn.algolia.
             | com/?dateRange=all&page=0&prefix=true&que... and if you
             | still have a question I haven't answered there, let me know
             | what it is. Examples:
             | 
             | https://news.ycombinator.com/item?id=22042481
             | 
             | https://news.ycombinator.com/item?id=21457217
             | 
             | https://news.ycombinator.com/item?id=20206120
             | 
             | https://news.ycombinator.com/item?id=18156460
             | 
             | https://hn.algolia.com/?query=by:dang%20reposts%20mitigate&
             | s...
             | 
             | https://hn.algolia.com/?query=by:dang%20reposts%20cracks&so
             | r...
        
               | aspenmayer wrote:
               | I do have one unanswered question: Why did this
               | particular repost get posted instead of upvoting my post?
        
               | dang wrote:
               | Because your post fell below the bar for 'significant
               | attention' as explained in the comments I linked to.
        
               | aspenmayer wrote:
               | Maybe if I had gotten some of the karma from the repost
               | it would have cleared the bar. This argument is circular,
               | and I know you have to make a judgment call, but this
               | feels like the wrong way to go about a fair, transparent
               | system. Perhaps that is not a goal of HN, but from my few
               | interactions with you on this site, I think you probably
               | care a whole lot more about HN than I do, and I care too!
               | Thanks for all you do.
               | 
               | Edit:
               | 
               | Why not do it like a lottery with more than one winning
               | ticket sold? Share the karma pool among the OP and the
               | reposters. Just an idea.
               | 
               | Or, let the reposter keep the karma, but put a byline
               | saying something like 'first posted by user123 on jan 2,
               | 1969' with a link? I care far more about attribution than
               | karma. I care about making good posts, but if someone
               | else gets the credit, why would I bother? If no one will
               | see it, the intrinsic value to me is something I already
               | had. To share is to be seen. If a tree falls in the
               | forest with no one around to hear it and all that.
        
       | drewg123 wrote:
       | The interesting bit to me is that the FreeBSD bug took 2 weeks of
       | fuzzing to find, but the Mac/Windows bugs were found in one day.
       | 
       |  _USBFuzz found three bugs (two resulting unplanned restart and
       | one resulting system freeze) on MacOS, and two bugs on Windows
       | (resulting in a Blue Screen of Death, confirmed on both Window 8
       | and Windows 10) during the first day of evaluation. Additionally,
       | one bug was found in a USB Bluetooth dongle driver on FreeBSD in
       | two weeks._
        
         | [deleted]
        
         | blablabla123 wrote:
         | FreeBSD is definitely the system that will make it through the
         | apocalypse. A friend once told me he had a damaged RAM module,
         | trying to install Windows, various Linux distributions, nothing
         | worked. But it was possible to install FreeBSD and it just
         | worked...
        
           | asveikau wrote:
           | Still probably should get that RAM replaced though.
        
       ___________________________________________________________________
       (page generated 2020-05-28 23:00 UTC)