How Fil-C Works — Transcript
Full transcript
- 0:00If your memory unsafe, that means
- 0:01[music] that an attacker can now use
- 0:04input into your program to just
- 0:05literally edit any bits in your memory.
- 0:07Attackers have shown
- 0:09>> [music]
- 0:09>> throughout the history of the security
- 0:11business that if you give them that
- 0:12power, they can reprogram [music] your
- 0:14computer. And the idea is, what if the
- 0:17thing about C and C++ [music]
- 0:19that's not memory safe isn't the
- 0:21language, but just the way we implement
- 0:23it? So, there for those programs, Emacs,
- 0:26[music] Ruby, and JavaScript core, I
- 0:28just ripped the GC out and replace all
- 0:31of the entry points into the [music]
- 0:32garbage collector with just calls to
- 0:34malloc. I would like to start sort of
- 0:36like top high level, talk a little bit
- 0:38about
- 0:40memory safety in general, PhilC, what is
- 0:42it, how it works, and kind of gradually
- 0:44move towards deeper and deeper
- 0:47depths, and at some point, if uh Phil
- 0:50was going to be, you know what? I should
- 0:52share my screen and just show you how
- 0:54this works, then we can do it as well.
- 0:56Sounds good.
- 0:58>> [snorts]
- 0:59>> So, [clears throat] let's kick this off.
- 1:01Welcome to another special episode of
- 1:04Łukasz podcast. I am Łukasz, your host,
- 1:07and with me is creator of PhilC, Filip
- 1:11Jerzipizlo. Hello.
- 1:13Hi, how's it going?
- 1:16And Casey Muratori, well-known persona
- 1:19in performance-oriented
- 1:22programming now. Hello, Casey.
- 1:25How's it going?
- 1:27We are gathered here today to talk about
- 1:29memory safety, the most sexy topic in
- 1:32programming, as everybody knows this.
- 1:34And
- 1:36we have to start
- 1:38a little bit about
- 1:41just memory safety in general, okay?
- 1:44The concept for me, it's incredible. If
- 1:47people say, "Hey, this is memory safe."
- 1:49It's as if, "Oh, it doesn't have any
- 1:51bugs, you know? It doesn't have like it
- 1:52it it it it it will always work. It's
- 1:54like incredible." So, can we can we say
- 1:59a little bit what is memory safety?
- 2:01What's other feature? Okay? Philip, can
- 2:04you tell me?
- 2:05Yeah. Uh so, here's how I think about
- 2:07it.
- 2:09Um
- 2:10so, first of all, memory safety isn't
- 2:12about the prevention of bugs. If you
- 2:14have a bug in your program, um that
- 2:16might still be a memory safe program. Uh
- 2:19probably the most extreme example of a
- 2:22memory safe catastrophic bug is Log4j,
- 2:27where a memory safe Java program was
- 2:30parsing strings and using those strings
- 2:32to decide what modules to load.
- 2:35And so then, you know, you could go to a
- 2:37website and if you uh type in a message
- 2:40that that log parser parses, all of a
- 2:42sudden the server is executing whatever
- 2:44code you want.
- 2:45So, memory safety isn't about prevention
- 2:47of bugs. It's specifically about the
- 2:49following.
- 2:50It in assembly, C, uh C++, and other
- 2:55languages that are memory unsafe,
- 2:58a bug in one part of your program, like
- 3:00a bug in a parser,
- 3:01or a bug in an event handler, or
- 3:04something,
- 3:06could allow an attacker to take control
- 3:08over all of memory.
- 3:10Uh so, now it's not just that the
- 3:12attacker
- 3:13uh can inject a string that if you had a
- 3:16string parser, you would parse it and do
- 3:18something bad.
- 3:19But,
- 3:20you know, you could have an innocuous
- 3:22parser that's parsing um
- 3:25I don't know, uh
- 3:26ping packets or something, just meant to
- 3:28be completely meaningless and not
- 3:30impactful on the rest of your program.
- 3:32And because you have a thing where you
- 3:34failed to check array bounds,
- 3:37if you're memory unsafe, that means that
- 3:39an attacker can now
- 3:41use input into your program to just
- 3:44literally edit any bits in your memory.
- 3:47Um
- 3:48and
- 3:49uh Uh, attackers have shown throughout
- 3:53the history of the security business
- 3:55that if you give them that power
- 3:57they can reprogram your computer.
- 4:00Hi everyone. Let me take a break to
- 4:02thank members of the show who made this
- 4:04conversation possible. Members get
- 4:06earlier access to videos including
- 4:08longer unedited footage from live
- 4:11streams as well as they're invited to
- 4:13our private Discord server. If you want
- 4:16to support this show, there is no better
- 4:18way than becoming a member on YouTube or
- 4:20Patreon. Thank you so much.
- 4:24Um, so the earliest example of this was
- 4:26like the shellcode where you have a
- 4:28buffer on the stack.
- 4:30Um
- 4:31and you fail to check the bounds of the
- 4:34buffer while reading something.
- 4:36Uh, and then the attacker overwrites the
- 4:38buffer and then keeps writing to
- 4:40overwrite the return address that was on
- 4:43the stack.
- 4:44And then keeps writing to write machine
- 4:46code
- 4:47and makes the return address point at
- 4:49the machine code. This was back in the
- 4:50days when computers didn't have, uh, for
- 4:52example execute protections on the
- 4:55stack. And then and then they can just
- 4:57run whatever whatever machine code
- 4:59snippet they choose on your computer.
- 5:02And then then they have full control.
- 5:03Whatever the process is entitled to do
- 5:06the attacker now gets to do as if they
- 5:08could retype the code of your program.
- 5:11Um, so this is quite a bit different
- 5:12from most other bugs. Like
- 5:15if you have a security bug like that you
- 5:17forgot to do a policy check whether
- 5:19someone is an admin
- 5:21um, then that would let the attacker
- 5:24attack you if they
- 5:26can somehow attack that specific bug
- 5:29and then the capability they get out of
- 5:31that is just whatever that bug gives
- 5:33them. With a memory safety bug, you
- 5:36could have a bug in a part of your
- 5:37program that isn't anything to do with
- 5:40security checks.
- 5:42And if if the attacker finds a bug
- 5:44there, all of a sudden they can do
- 5:45anything your program can do.
- 5:47Now, what's really scary about memory
- 5:49safety issues is that even if you fix
- 5:52that simple case of, "Okay, well, what
- 5:55if we make the stack not executable?
- 5:57What if we randomize memory and make it
- 5:59so that
- 6:01uh
- 6:02the the attacker can't just know where
- 6:04to make the return address point."
- 6:06Um
- 6:08"What if we make it so that every jump
- 6:10that the CPU executes can only jump to
- 6:12preordained locations, right? Like, what
- 6:14if we do these kinds of protection?"
- 6:17It turns out that attackers have
- 6:19established that
- 6:21if you control every bit of memory, then
- 6:24even if they can't change where the
- 6:26branches go,
- 6:27like even if they can't tell the CPU to
- 6:30jump to a specific location,
- 6:33even if the attacker can't inject their
- 6:35own machine code, they can make
- 6:37your program do whatever they want
- 6:40through a technique called weird
- 6:41execution. Weird state, weird execution,
- 6:43those are terms of art that these people
- 6:45use.
- 6:46Where essentially, if if I can control
- 6:48every bit in the memory of your process,
- 6:51then because every branch in your
- 6:52program ultimately is depending on
- 6:55something loaded from memory,
- 6:57the attacker, by controlling every bit
- 6:59in memory, can take your program on
- 7:01whatever journey they want and can
- 7:03effectively achieve the same power as if
- 7:05they could reprogram your program and
- 7:07make it do whatever they want.
- 7:09So, memory safety
- 7:11is the property that an attacker can't
- 7:14use a localized bug like a memory buffer
- 7:17overflow or use-after-free
- 7:19to then pivot to controlling
- 7:22all of your memory or enough of your
- 7:24memory. Cuz with weird execution, since
- 7:26they've proven that they can control
- 7:28your program by controlling all of
- 7:29memory, it kind of probably follows that
- 7:33even if you only gave them control of
- 7:34half of your memory, they could probably
- 7:35do the same thing.
- 7:37So, memory safety is like you have to
- 7:39somehow make it so that if there's a bug
- 7:41in one part of the program,
- 7:43the amount of memory that the attacker
- 7:46now controls is severely limited to just
- 7:49like
- 7:50that object or that something some
- 7:53somewhere in that neighborhood.
- 7:55Um and then
- 7:57there's a lively debate to be had of how
- 7:59far do you have to go, right? Uh if I
- 8:02was uh a Rust evangelist,
- 8:05uh I I would probably be arguing that
- 8:08the protections need to go much further
- 8:10than that and that we need to have
- 8:12thread safety
- 8:13and and super tight type system that
- 8:16checks everything.
- 8:18Um
- 8:19uh if I was putting my JavaScript hat
- 8:22on, I would observe that JavaScript is
- 8:23memory safe just by virtue of the fact
- 8:25that
- 8:26if an attacker finds a bug in my
- 8:28JavaScript code,
- 8:30they might be able to change what field
- 8:32values end up in the fields of whatever
- 8:35objects the program is sitting on at the
- 8:38point of that bug, but that's it. And so
- 8:39therefore, it's memory safe.
- 8:42Um
- 8:43That's easy way out. Memory safe.
- 8:45Easy way out for JavaScript there.
- 8:48Yeah.
- 8:50Casey, do you have anything to add on
- 8:51the general level of memory safety?
- 8:54No, I mean I think that was absolutely
- 8:56fantastic. Uh
- 8:57the I guess the only things I would
- 8:59point out are things that people tend to
- 9:01get confused about. They were all
- 9:03explained in that explanation, but if
- 9:06you know, if depending on where people
- 9:07are coming from,
- 9:09a lot of times there's confusion because
- 9:12people don't understand the difference
- 9:14between checks that are performed at
- 9:16compile time and checks that are
- 9:18performed at run time
- 9:20and which types of things are caught
- 9:23when.
- 9:24And so this causes a lot of confusion
- 9:26online I see with people who don't
- 9:28necessarily have like a deep
- 9:30understanding of what's going on.
- 9:32Sometimes they get confused because they
- 9:34don't realize that for For
- 9:35even in a language designed for
- 9:39certain types of memory checks at
- 9:41compile time, like Rust,
- 9:44there's entire categories of memory
- 9:46safety bugs that are important to
- 9:48prevent that cannot be caught at compile
- 9:50time because we've just we we've sort of
- 9:54proven that
- 9:55unless you have complete formal analysis
- 9:57of a program,
- 9:59there's no way like if it's taking user
- 10:01input, there's no way other than at
- 10:04runtime to ensure that something is
- 10:07memory safe. So, even a a programming
- 10:09language like Rust,
- 10:11it will be doing runtime checks to
- 10:14enforce a bunch of memory safety policy.
- 10:17And so, you
- 10:19there really isn't at the moment, at
- 10:22least as far as I'm aware, there isn't
- 10:23any sort of in mass production
- 10:27sort of large, you know, widely
- 10:28commercialized methodology that involves
- 10:32only compile time.
- 10:33All of the ones that are like currently
- 10:36common that you would see
- 10:38that people would argue about on the
- 10:39internet, they are employing runtime
- 10:41checks. The question is how much is
- 10:43checked at runtime versus how much is
- 10:45checked at compile time. And I just feel
- 10:47like that's important to get out there
- 10:48cuz I see people get confused about this
- 10:50a lot and like a lot a lot of people
- 10:52genuinely think that Rust after the
- 10:54compilation is done with its memory
- 10:56safety. It's like that's not how that
- 10:58works, right? And it's important to
- 11:00establish that at least or that
- 11:01baseline, I would say.
- 11:03Yeah, yeah, yeah, it's a good point. The
- 11:05other uh
- 11:06uh that reminds me the other thing that
- 11:08folks get confused about
- 11:10is
- 11:12um memory safety in the sense of
- 11:14preventing crashes
- 11:17versus memory safety in the sense of
- 11:18preventing weird execution.
- 11:20Good point. Yeah. Yep. Uh
- 11:22for for for for most of us thinking
- 11:25about memory safety,
- 11:27uh I think that includes, for example,
- 11:29the folks at uh CISA who are writing
- 11:31those memos about how everyone should
- 11:33stop using memory unsafe languages, you
- 11:35know, those government directives.
- 11:37For for us,
- 11:39crashing isn't the problem.
- 11:42Like, if the problem with C and C++
- 11:44programs was that
- 11:47um if something bad happens or an
- 11:49attacker attacks you, the program
- 11:50crashes,
- 11:51um
- 11:53then would that be a problem? Yeah,
- 11:55yeah, that's a problem, but it just
- 11:57would not be the problem that would
- 11:58raise to the level of the government
- 12:01needing us needing to tell us how to do
- 12:03things.
- 12:04The thing that causes uh the level of
- 12:07fear and and and terror that that gets
- 12:11the government uh
- 12:13stressed about this
- 12:14is the weird execution. So, it's not
- 12:16that your program crashes,
- 12:19but that the attacker now has has full
- 12:22control over your program, and you don't
- 12:24even know it. So, your program is not
- 12:25doing what you intended anymore, it's
- 12:27doing what the attacker intended. Um and
- 12:30the most extreme examples of this are
- 12:33uh you know, uh
- 12:35some government agency from a government
- 12:38you aren't friendly to installs a
- 12:40surveillance payload on your iPhone. You
- 12:42don't even know this, you're just using
- 12:44your iPhone as normal, but the cameras
- 12:46on your iPhone are always on and
- 12:48streaming everything to the to the
- 12:49government. Your microphone's always on,
- 12:52your location's always tracked. And now
- 12:54all of a sudden
- 12:56you're just you're just
- 12:57you're you're just
- 12:59your device is spying on you for someone
- 13:01that you don't want to be spying on you.
- 13:04That's the thing that's scary. So, like
- 13:07um a lot of the the heated debates uh
- 13:10devolve down into like, "Well, Rust has
- 13:13unwrap."
- 13:15Actually, the fact that Rust has unwrap
- 13:16is not a problem at all. Unwrap is
- 13:18great. Uh if you unwrap something and
- 13:21it's uh there's no value in there, it
- 13:22crashes. Uh that is a memory safe
- 13:25outcome.
- 13:26Uh
- 13:27so, that's great. Uh, no problem with
- 13:29Rust having unwrap. Uh, the problem in
- 13:32Rust is not that it has unwrap, it's
- 13:34that it has unsafe. Uh, and if you use
- 13:37Rust unsafe, then all of a sudden you're
- 13:39in territory where there's neither
- 13:40runtime nor compile time checking that
- 13:43is adequate to prevent weird state.
- 13:47Okay.
- 13:47>> A pithy way to say it also would be that
- 13:49like a fully memory safe language is for
- 13:53the most part about ensuring that the
- 13:55only attack you have is like a denial of
- 13:58service attack.
- 14:00Right? So, it's like all of the types of
- 14:02things that used to be runaway exploits
- 14:04are now going to turn into denial of
- 14:06service attacks. Of course, these are
- 14:07only talking about non-logic bugs cuz if
- 14:11again, if you have something like a
- 14:12parsing bug and this thing is
- 14:15able to run stuff, then you can just
- 14:17have it run your, you know,
- 14:19the stuff that you're
- 14:21fooling it into parsing incorrectly. So,
- 14:22it's never going to get rid of that
- 14:24category, but all the other category of
- 14:26like accidental things that occur
- 14:28because you, you know, you didn't
- 14:29realize that you were going to go off
- 14:31the end of this array for writing or you
- 14:33were using something after you freed it
- 14:34or that stuff. All of those now will
- 14:36turn into at least at worst a denial of
- 14:39service attacks where the program
- 14:40crashes. So, that's not going away in
- 14:43these languages. You can the attacker if
- 14:45all the attacker wants to do is just
- 14:47stop you from executing at all,
- 14:49that's still well within their ability
- 14:51to do when they find one of these
- 14:53exploits. But usually people aren't as
- 14:55paranoid about that. As Philip was
- 14:57saying, it's like
- 14:59that's not the worst that, you know,
- 15:01they're worried about the thing where
- 15:02you can escalate, right? Uh, into
- 15:04actually taking control of things.
- 15:06Okay.
- 15:08So, now we're entering FilC, okay?
- 15:12Well, I'm assuming that with this intro,
- 15:14FilC is targeting memory safety, meaning
- 15:17weird execution, right? The the the
- 15:20category of the problems, not about the
- 15:22crashing of the program and like you run
- 15:24out of memory, but hey, we want to help
- 15:27you build programs that will be safe
- 15:30on using C and C++, you know, right? Can
- 15:34you do an overview of how FielC works
- 15:37and where it can be applied?
- 15:40Yeah. Um
- 15:43So, FielC uh
- 15:45So, I guess just to back up just to
- 15:48give give y'all a framing. FielC started
- 15:51as a project where I had this crazy idea
- 15:56and I was uh more than 50% sure that the
- 16:00idea was so crazy that it couldn't
- 16:02possibly work and I just was like I had
- 16:04to try it to to prove myself wrong to
- 16:06see that it wouldn't work.
- 16:08So, it's like
- 16:10I I I'm still kind of amazed that it
- 16:13works at all. It's one of those things
- 16:14that works just barely. Um
- 16:19And the idea is
- 16:21uh what if
- 16:23uh
- 16:24the thing about C and C++ that's not
- 16:26memory safe isn't the language but just
- 16:30the way we implement it.
- 16:32Um the set of choices that C compiler
- 16:35writers have made over the years when
- 16:38making C what it is.
- 16:41And so, what FielC does is
- 16:44uh just
- 16:46it takes the language that you know
- 16:49um
- 16:50and creates an implementation that is
- 16:52that behaves as if it was that language,
- 16:55but with all the rules changed
- 16:57underneath the hood. So, rather than a
- 16:59pointer being an integer that tells you
- 17:02where in memory you want to write read
- 17:03and write stuff, a pointer is
- 17:07really a capability to a range of memory
- 17:09and there's some tracking to see, okay,
- 17:12which range of memory does this pointer
- 17:14get to access?
- 17:16The pointer still has what I call the
- 17:18int val, the integer component of it. Uh
- 17:20you get to see that, play with it, make
- 17:22its value be whatever you want. But if
- 17:24the int val ends up out of range of the
- 17:26capability,
- 17:28then you have a pointer that's in a
- 17:29state where if you try to load or store
- 17:31to it, it'll it'll panic immediately
- 17:33upon load or store.
- 17:36Additionally,
- 17:37>> worth mentioning there that like
- 17:38capability is sort of a term typically
- 17:41used in this space to refer to that
- 17:43idea.
- 17:44That instead of just locations in
- 17:45memory, capability means a memory range
- 17:49and what are you allowed to do to it.
- 17:52Exactly. Just to unpack that, sorry. I'm
- 17:54just jumping in for I'm trying to jump
- 17:55in for beginners, basically. That's a
- 17:57really great point because I'm not the
- 17:59first one to use capabilities. Um
- 18:01the uh
- 18:03if if you if you have an FPGA
- 18:06uh and know what you're doing, you can
- 18:08download uh Cherry and put it on the
- 18:11FPGA. Cherry is a CPU architecture that
- 18:14has capabilities at the hardware level
- 18:16instead of pointers.
- 18:18Um and then like there's some amount of
- 18:20C programs you can run on Cherry. Um uh
- 18:23there's other capability architectures
- 18:25out there. There's a Russian thing
- 18:27called Elbrus.
- 18:28Uh and I think some IBM mainframes also
- 18:30have capabilities. So, capabilities are
- 18:32actually common in the hardware space.
- 18:36Okay. Where FillC uh differs from those
- 18:39is that it's it's all software. So, you
- 18:41can run it on your Intel box.
- 18:44But then FillC goes uh
- 18:47a couple of steps further than I think
- 18:48others have gone.
- 18:50Uh and it goes a couple of steps further
- 18:52because I'm going I'm really aiming for
- 18:55like the kind of comprehensive memory
- 18:57safety that I would expect to get from a
- 19:00Java virtual machine or a JavaScript
- 19:02implementation. Where there's I call it
- 19:04gimso, uh garbage in, memory safety out.
- 19:08There's no sequence of bytes you can
- 19:10give to the compiler that will result in
- 19:12the compiler producing a binary that
- 19:14then violates the memory safety rules.
- 19:17So, how do I do that? The next thing
- 19:19that I have to do is worry about use
- 19:20after free.
- 19:22So, the way that use after free is
- 19:23handled is you can't write your own
- 19:25malloc and free anymore. You can call
- 19:27malloc and free,
- 19:28but malloc is a garbage collection
- 19:30allocation,
- 19:32and free just tells the garbage
- 19:34collector um this object is henceforth
- 19:37dead.
- 19:38Uh but it so it which causes the
- 19:41capability to become disabled in place.
- 19:44>> [snorts]
- 19:44>> All subsequent accesses to that object
- 19:47will fail.
- 19:48Um and the garbage collector knows that
- 19:51the next time that it runs, it can
- 19:54replace all pointers to that dead
- 19:56capability with pointers to a dead
- 19:58singleton. So, that freeing an object
- 20:00does free it just with a delay. You have
- 20:03to wait until the next time the GC runs.
- 20:06Um
- 20:09and then on top of that, there's what do
- 20:11you do about
- 20:14representing pointers themselves?
- 20:15Because as I said in Fil-C, pointers are
- 20:18this integer value that you get to see
- 20:20that's what you would think of the
- 20:22pointer being if you're a C programmer.
- 20:24It's just an integer that tells you an
- 20:26address in memory. And then there's the
- 20:28capability. So, how do you
- 20:30carry that around? Um and the probably
- 20:33the
- 20:34the wackiest insight in Fil-C is what
- 20:38I'm calling invisible capabilities and
- 20:39visicaps, where
- 20:41if you store a pointer into memory,
- 20:45then within the address that's visible
- 20:48to you, the only thing that got stored
- 20:49is the pointer's integer value. So, if
- 20:52you store pointer to into memory and
- 20:54then uh read it back out as bytes or
- 20:57integers, you're going to see the
- 20:59pointer's integer value exactly the way
- 21:01you would in normal C.
- 21:03But every single object in memory has a
- 21:06hidden side location where I could store
- 21:09the capabilities that correspond to the
- 21:12pointers stored into that object.
- 21:14So, what this does is it gives you a
- 21:17programming model where the size of
- 21:19pointer, size of void star,
- 21:22>> [snorts]
- 21:22>> is the same as it would have been
- 21:24normally. So, if you're on a 64-bit
- 21:26system, size of void star is 8 bytes.
- 21:30And it means that you can do things like
- 21:33um
- 21:34uh type punning and unions. Uh you can
- 21:37even violate things that the spec says
- 21:40you can't do like uh according to the C
- 21:42spec, if you store a pointer into a
- 21:44union and then read it back as integers,
- 21:46then that's undefined behavior. In FilC,
- 21:48that's perfectly defined behavior. You
- 21:50store a pointer into a union, read it
- 21:51back as an integer, you're going to get
- 21:53the pointer's integer value.
- 21:54If you store an integer into the union
- 21:56and read it back as a pointer,
- 21:58you're going to get a pointer that has
- 21:59an integer value that is going to be
- 22:01most likely out of range of the
- 22:03capability. And if if it is in range of
- 22:04the capability, then no problem. That's
- 22:06a capability you're
- 22:08allowed to be accessing cuz it's a
- 22:10capability you already had.
- 22:12Um so, FilC
- 22:15uh is
- 22:19the remarkable thing about it is that I
- 22:21I think it achieves exactly what memory
- 22:23safety is according to that definition
- 22:25that we gave earlier.
- 22:28Um while giving you
- 22:31such a level of compatibility with C and
- 22:33C++,
- 22:35that you can like boot Linux or you
- 22:38Well, kernel doesn't work like that, but
- 22:40you can boot the Linux userland with it.
- 22:42Um and like Emacs works, Python works,
- 22:45Ruby works, Ninja, make, CMake, all of
- 22:48it just work. These are C++ programs
- 22:51that were never written with the
- 22:52intention to be compiled with a
- 22:54memory-safe compiler. Or they were not
- 22:56written with the thinking that C was a
- 22:58memory-safe language. But all of the
- 23:01stuff that they do, even the crazy stuff
- 23:03that they do, just works in Filigree.
- 23:06And from the user point of view,
- 23:10how Filigree works, right? Like you,
- 23:12because if you go to Filigree website,
- 23:14you have a download button, you need to
- 23:16download a compiler, and then like what
- 23:19would happen if I were to use Filigree?
- 23:21Like how would the steps look like?
- 23:25Yeah, this is a
- 23:28This is a good question.
- 23:30One of the the caveats with Filigree is
- 23:32that it is not binary compatible with
- 23:36normal C. That is,
- 23:38you can't compile a shared library with
- 23:41normal C,
- 23:42and then have your Filigree program link
- 23:43to it or vice versa.
- 23:46So, there are three currently three ways
- 23:48that I distribute Filigree. One is just
- 23:51like a little local environment. Uh you
- 23:53download a relatively small tarball, you
- 23:55get a compiler and a lib C and a lib
- 23:57C++.
- 23:59Um and you just install it in some local
- 24:01directory on your Linux box. Uh and then
- 24:04you can you can write C C++ programs and
- 24:07compile it. With that, uh the library
- 24:10the C library that you get is a is uh
- 24:12muscle.
- 24:13So, you get kind of some of the
- 24:15limitations that you would get if you
- 24:17were using muscle as your lib C. The lib
- 24:19C++ is just the LLVM lib C++, so it's a
- 24:22full-featured
- 24:24lib C++.
- 24:25And the compiler is a surgically
- 24:28modified clang uh 20.1.8. So, you get
- 24:31all of the modern C C++ features, uh
- 24:35including clang and GCC extensions.
- 24:38Um a lot of people use that distribution
- 24:40cuz it's very easy to install, small
- 24:42tarball, uh don't have to be root to
- 24:44install it.
- 24:47Second version of it that you can
- 24:49install, which is sort of my preferred
- 24:50way to do it,
- 24:52um [clears throat]
- 24:54is the opt Filigree distribution. So,
- 24:56this you install as root and it installs
- 24:59a fill C slice, as I call it, in
- 25:02/opt/fill.
- 25:04And then, it comes with uh a whole bunch
- 25:07of libraries in addition to just the lib
- 25:09C.
- 25:10And rather than using muscle as the lib
- 25:12C, it uses glibc 2.40. Uh so, it's a
- 25:15very
- 25:17modern and rich uh lib C with all of the
- 25:20features you would expect uh when
- 25:22programming on Linux.
- 25:24Um and then, it comes the opt fill slice
- 25:27comes with a huge number of libraries,
- 25:29OpenSSL, PAM,
- 25:31um
- 25:32bunch of uh bunch of compression
- 25:35libraries,
- 25:37libreadline, uh just lots of stuff that
- 25:40you would expect if you're writing C C
- 25:42programs on Linux. So, with the opt fill
- 25:44distribution, you can use that as a
- 25:46foundation to build kind of larger
- 25:48software because you you get a lot of
- 25:51shared libraries um that you would that
- 25:54you would expect to have available to
- 25:56you if you're writing a C program on
- 25:58Linux or a C++ program on Linux. That's
- 26:00they were precompiled with fill C, so
- 26:01they will work if you link to them.
- 26:04Okay. Yeah. Um
- 26:06and then, the the the version that I've
- 26:09been experimenting with the most
- 26:11recently is uh I I need a better name
- 26:14for this. I call it Pizlex. It's a Linux
- 26:17distribution uh compiled with fill C. Um
- 26:22uh
- 26:24and uh so, you so so it's it's beyond
- 26:27Linux from scratch 12.2 um compiled with
- 26:31the whole userland compiled with fill C.
- 26:33Um so, you can boot to a graphical user
- 26:36interface.
- 26:38Um
- 26:39you know, there's an SSHD man that's
- 26:40compiled with fill C. There's
- 26:43uh Ruby, Python, Pearl,
- 26:47make, C make, Ninja,
- 26:49um
- 26:51uh and and I'm now getting a web browser
- 26:55to work in it. It's rough rough going,
- 26:58but it's getting there.
- 26:59What's the name of the browser?
- 27:01Oh, it's just
- 27:03Yeah,
- 27:04you'd expect a goofy name, right? But
- 27:05no, it's uh it's uh it's just WebKit.
- 27:09Um so WebKit, which is the browser
- 27:12engine that Safari uses,
- 27:14um comes with a thing called the mini
- 27:17browser, which is just a mini just just
- 27:19a minimalist browser.
- 27:21Um and so right now I'm just
- 27:23running the mini browser. Actually last
- 27:26night I was able to post on Twitter or
- 27:29x.com for the first time from from the
- 27:32memory safe mini browser.
- 27:34Okay.
- 27:35Okay, so there are three
- 27:37Yes. I would say there's there's a
- 27:38couple things to that probably want to
- 27:40be underscored there. Again, just you
- 27:42know, that's sort of hidden in the
- 27:44explanation, but that are important to
- 27:46beginners, I would say, right?
- 27:49Um and that is that A,
- 27:52a lot of memory safe things in the world
- 27:55that are labeled as such,
- 27:58omit the fact that they are running on
- 28:00top of things that are not memory safe.
- 28:02So, for example, if you compile a
- 28:04program
- 28:05uh or you use a virtual machine that is,
- 28:09you know, for a memory safe language,
- 28:11if it's sitting on top of a bunch of
- 28:12libraries that themselves are not memory
- 28:14safe, then it's not really a completely
- 28:18memory safe thing, right? So, when
- 28:22you're talking about PhilC and you're
- 28:23talking about having this nice ability
- 28:25to go because it's you know, it it can
- 28:28compile C, which is the thing that most
- 28:29of these underlying parts are written
- 28:31in,
- 28:32being able to recompile those and have
- 28:34the entire stack be PhilC
- 28:38is actually a very important difference
- 28:41between PhilC and a lot of things which
- 28:43are literally just providing memory
- 28:45safety at a very very top layer of a
- 28:48stack. This is one of the reasons that
- 28:50PhilC is so interesting in my opinion,
- 28:52right? Is because of that ability to now
- 28:56start to recompile underlying pieces of
- 28:58technology, you're no longer talking
- 29:01about just memory safing the very last
- 29:04little bit. So, that's thing one.
- 29:07Um and thing two is that if you think
- 29:11about how
- 29:13uh
- 29:14I guess I'm not sure how to describe
- 29:15this, but if you think about how memory
- 29:18safety is approached or or
- 29:23philosophically
- 29:25the proponents of memory safety
- 29:27how they tend to have to sell it to you,
- 29:30it's always about you have to come and
- 29:33completely redo whatever you were doing
- 29:36in order to get it, right? If you
- 29:38previously were writing in an in a
- 29:39memory unsafe language, then the only
- 29:42way that you're going to get memory
- 29:43safety is we rewrote the entire thing in
- 29:45Rust and anything else that we cared
- 29:47about that it depends on in Rust and so
- 29:49on, right? Or port the whole thing to
- 29:52Java or whatever it is that you want to
- 29:53talk about, that's what had previously
- 29:56been the sales pitch.
- 29:58And one of the reasons it's not super
- 29:59compelling is a lot of times, if you
- 30:02look at these languages, you don't
- 30:03necessarily love the language for any
- 30:05particular reason. Like you look at it's
- 30:06like, well, I'm not getting very much if
- 30:09I rewrite my whole thing in this other
- 30:10language. Like I maybe don't see a lot
- 30:12of benefit to that language.
- 30:13And so now I'm having to take this hit
- 30:15of rewriting this whole thing in this in
- 30:17this new language for very little
- 30:19benefit other than the fact that I
- 30:21really wanted this memory safety, which
- 30:23could have been a very important feature
- 30:26for the, you know, particular domain
- 30:28that you were working in, especially if
- 30:29it's security critical, right?
- 30:32And so another aspect of PhilC there is
- 30:34it's a very different sales pitch
- 30:36because of exactly what was just
- 30:38described. You basically just get a C
- 30:40compiler and really all you're looking
- 30:43at is you will compile your program
- 30:46that you already had without rewriting
- 30:47it at all, and then the compiler will
- 30:49tell you the places where you might need
- 30:51to make changes because you're doing
- 30:53something that inherently can't be made
- 30:55memory safe or something like that. We
- 30:57could I'm sure we'll talk about that in
- 30:58in a minute, like the reason why you
- 30:59can't just recompile everything and have
- 31:01it work. But, it's pretty close to that.
- 31:03Like, you don't have to do huge
- 31:04modifications as evidenced by the fact
- 31:07that Philip Scott so much stuff running
- 31:09already and he's one person, and and
- 31:11very little had to change to have that
- 31:13happen, right? So, so I think those are
- 31:15two really important aspects. All Again,
- 31:16all contained in in everything that was
- 31:19just said, but I just wanted to unpack
- 31:20those cuz they're they're pretty
- 31:21impressive and and actually very
- 31:23interesting. Uh it's one of the reasons
- 31:25PhilC is not just like yet another
- 31:27memory safe thing, right?
- 31:28So.
- 31:30Yeah, there's one other
- 31:32uh
- 31:33curious property of PhilC
- 31:35um to
- 31:37to add to that, which is that with, for
- 31:39example, Rust and Go,
- 31:42the same technologies that grant those
- 31:45languages memory safety
- 31:48also take away from those languages the
- 31:50ability to dynamically link with
- 31:52themselves.
- 31:54So, like, if you write a dynamically
- 31:55dynamic library in in Rust,
- 31:58your options are that either the dynamic
- 32:01library exposes itself as if it was a C
- 32:04library with a C interface that's
- 32:06completely unsafe. So, you'll have Rust
- 32:08code using unsafe statements to call
- 32:10into other Rust code just to get across
- 32:12the dynamic linking boundary.
- 32:14Or, you have to buy into the undefined
- 32:17behavior in Rust of what happens if
- 32:20uh
- 32:21you ship a dynamic library and I use it,
- 32:23and then you breathe on the code and
- 32:25recompile the library. At that point, if
- 32:27the if the interface layer between those
- 32:31between me and you was a Rust API that
- 32:34was safe, the moment you recompile your
- 32:36side, um and we're still dynamically
- 32:39linking, all bets are off.
- 32:42But in PhilC, you actually get
- 32:45ahead-of-time compilation, so you can
- 32:47ship binaries,
- 32:49and you get memory safety across the
- 32:51dynamic link boundary.
- 32:54So if you think about what does it look
- 32:56like to build
- 32:58like a large OS or an application that
- 33:01is large enough that it needs dynamic
- 33:03linking, and you want to build it in a
- 33:05memory-safe way, weirdly, PhilC might be
- 33:08the only game in town right now.
- 33:13About like alternatives, I think like
- 33:16ideally we'll talk about the at the end.
- 33:18I want to give like spotlight now to
- 33:20PhilC, and then like later on as we go
- 33:23through how PhilC works underneath, like
- 33:25we can sort of talk about the
- 33:27alternatives and and compare it. You
- 33:29mentioned
- 33:30Casey mentioned like interesting fact
- 33:32that like
- 33:33Philip, you like seems to be you seem to
- 33:36be every week posting like, "Hey, I got
- 33:38this program to be working in PhilC, and
- 33:40then this, and then this, and then
- 33:41this." And like this is your spare time.
- 33:44So how the process of getting this to
- 33:47compile in PhilC looks like,
- 33:50and also how is it like
- 33:54if something is unsafe, you get a crash
- 33:57or a panic
- 33:59either at the runtime or at the compile
- 34:01time. How does this look like for the
- 34:03process of like getting an existing
- 34:05piece of software and getting it into
- 34:07PhilC?
- 34:08Yeah, so
- 34:10uh for half of the programs that I've
- 34:13ported,
- 34:14I've just made no changes. I just like
- 34:18compile it with PhilC,
- 34:20then I use it, and it works, and
- 34:23[snorts]
- 34:24that's it.
- 34:25So half half of them are in that in that
- 34:27category.
- 34:28Of the remaining half uh that are not in
- 34:32that category,
- 34:35most uh
- 34:39most of the issues are that fil C
- 34:43uh mangles all of the symbols. Um
- 34:47all of the symbols get pre- prepended
- 34:49with pizzlinated underscore.
- 34:52Uh and so uh a huge number of
- 34:55open-source libraries out there have
- 34:57version scripts,
- 34:59um which is this feature in uh in in C
- 35:02where you can say
- 35:04here the the list of symbols that my
- 35:06library exports.
- 35:08And because fil C relies on just the
- 35:10normal linker,
- 35:12uh when those version scripts enumerate
- 35:14symbols without the mangling,
- 35:16um you end up getting link errors
- 35:18because then the linker can't find the
- 35:20symbols cuz the symbols actually have
- 35:22the pizzlinated [music] thing prepended
- 35:23to them.
- 35:24Uh and there's there's a simple hack you
- 35:26can do to fix that. You have to change
- 35:28uh the way that version scripts are
- 35:30passed to the compiler so that they get
- 35:32mangled automatically for you. So, of
- 35:35the half of the programs where I made
- 35:36changes,
- 35:38probably like 3/4 of those are just
- 35:41changes to either the configure script
- 35:44or the meson file or the C make file or
- 35:47whatever to to to change how the version
- 35:50scripts work.
- 35:51Um so like most of the changes are when
- 35:55I have a project that I had to make
- 35:56changes to, it's that.
- 35:58And then it just works.
- 36:00And then there's the small minority of
- 36:01programs that do
- 36:04uh either
- 36:06um
- 36:07uh inline assembly.
- 36:09Um the way that
- 36:12current So,
- 36:13I I come from implementing JavaScript
- 36:15VMs. So, the question about what's
- 36:17caught at compile time, the answer is
- 36:18basically nothing. Um it you get the
- 36:21error [clears throat] at runtime. So, if
- 36:22you have some inline assembly and the
- 36:24inline assembly executes, you get a
- 36:26panic saying executing inline assembly
- 36:28that I couldn't prove safe.
- 36:30Uh the compiler already can prove
- 36:33trivial inline assembly safe in some
- 36:35cases. So, there's some inline assembly
- 36:37that just works.
- 36:38Um but if it if you if it executes some
- 36:41inline assembly if you try to execute
- 36:42some inline assembly that the compiler
- 36:45couldn't prove safe, you get a panic.
- 36:47Um
- 36:49and that's a common thing is then you go
- 36:52and figure out exactly
- 36:54what configure script option or
- 36:57uh macro or whatever has to be flipped
- 36:59to turn off the the usage of inline
- 37:02assembly in that project. So, uh that's
- 37:04pretty common. Uh and in many cases,
- 37:06it's not like just that you disable the
- 37:09use of inline assembly, but in a lot of
- 37:11cases, the inline assembly on a modern
- 37:13compiler could have been an intrinsic.
- 37:15So, that's common replace the inline
- 37:16assembly with an intrinsic.
- 37:19Um
- 37:21and then the final category is uh
- 37:24programs that use
- 37:26integers to carry pointers around.
- 37:30Um
- 37:31a great example of that is GLib. So,
- 37:35GLib is the runtime library that
- 37:38underpins uh
- 37:39Gnome. So, GTK, GDK, GStreamer, all of
- 37:44these things are living on top of GLib.
- 37:46GLib has its own object model. It's kind
- 37:48of it's kind of awesome. Uh if you ever
- 37:51ever have a chance to read it, it's a
- 37:54really quite fascinating piece of code.
- 37:57Um and as part of this object model,
- 37:59there's this thing called GType.
- 38:02And GType is type deft by default in
- 38:05GLib to be a an integer, but uh provided
- 38:09that some bits in the integer are set or
- 38:11whatever, it's actually a a pointer. And
- 38:13so, there's places in GLib where it
- 38:15casts the integer to a pointer and then
- 38:17dereferences it.
- 38:18In PhilC, if you load or store an
- 38:21integer, then you're just loading and
- 38:24storing the integer. There's no
- 38:25capability.
- 38:26So then when you cast that integer to a
- 38:28pointer, you get a pointer that has a
- 38:30null capability. And if you try to
- 38:31access that pointer, you get a panic
- 38:34saying at runtime saying the capability
- 38:36is null.
- 38:37So
- 38:38um
- 38:39for for GLib, that meant that I had to
- 38:41change the type def of GType to be a
- 38:44pointer type so that when you're passing
- 38:46the GType around, you're passing around
- 38:49a pointer.
- 38:50Uh and then I actually had to go and
- 38:52change quite a few compiler errors that
- 38:54happened as a result of
- 38:56uh there's just code all over GLib and
- 39:00things that use GLib that just just
- 39:02assume that GType is an integer and that
- 39:03you can do integer-y things with it. For
- 39:05example, in C you can switch on an
- 39:07integer, but you cannot switch on a
- 39:10pointer.
- 39:11So uh
- 39:13things like that had to had to change.
- 39:16And so in GLib um and projects that rely
- 39:19on GLib, you'll find um
- 39:23uh
- 39:24hundreds of lines or thousands of lines
- 39:26of code that had to had to be changed,
- 39:28but it's really mechanical changes. It's
- 39:30like you run the compiler, you get 100
- 39:33compiler errors. They're all this
- 39:34pattern, either a switch statement over
- 39:36GType or uh performing bitwise
- 39:39arithmetic on the GType. And then you
- 39:41just change that code to do something a
- 39:42little different and and it's fine.
- 39:45So
- 39:46uh
- 39:47that's an example where where things get
- 39:49more involved, but that's rare. Like
- 39:51that was I hit that problem in
- 39:54in GLib and its uh downstream
- 39:57dependencies.
- 39:59Uh I hit that problem in Ruby.
- 40:02So I had to make a huge number of
- 40:03changes in the Ruby VM because the Ruby
- 40:05VM has a value type that just like GType
- 40:09is is was type def'd to integer and it
- 40:12can encode a pointer.
- 40:14Um
- 40:17Um but but most most programs just don't
- 40:20do this. Or if they do it, they do it in
- 40:21such a localized place that it's a
- 40:23one-line change rather than hundreds of
- 40:24lines.
- 40:26Oh, and I guess the other the other
- 40:27thing is what to do if the program has
- 40:30um custom allocators or or uh
- 40:35or its own garbage collector.
- 40:37Um
- 40:38Custom allocators are surprisingly rare
- 40:40in modern software.
- 40:42Um I was expecting to find more of them.
- 40:45Um but they they are really surprisingly
- 40:47rare.
- 40:48Uh
- 40:48we ended up writing patch to the GNU
- 40:51obstack, which is this uh
- 40:54arena allocator that's widespread in GNU
- 40:56software.
- 40:57Um so the obstack now is no longer an
- 41:00arena. It's allocating objects at a
- 41:02time.
- 41:03So you don't get the memory safety
- 41:05hazard that if you have an arena in
- 41:08FilC, the whole arena is one capability.
- 41:10So you can go out of bounds of one
- 41:11object and into another. That probably
- 41:13allows uh more weird state
- 41:16possibilities than I'm comfortable with.
- 41:18So now
- 41:20obstack is no longer really an arena.
- 41:22It's allocating objects at a time.
- 41:24Uh and then if there's a garbage
- 41:26collector, then it depends on what the
- 41:28garbage collector is. For example, the
- 41:29Python garbage collector, I just kept
- 41:32it. So if you're running Python in FilC,
- 41:35you get a garbage collector in a garbage
- 41:37collector. Um
- 41:38just cuz that
- 41:41And that works because Python's garbage
- 41:42collector allocates objects using
- 41:44malloc.
- 41:45Um
- 41:46That was Of course it does.
- 41:48It's whatever, you know.
- 41:50Um but then uh
- 41:52Ruby and uh
- 41:54uh
- 41:55uh Ruby and Emacs
- 41:58um
- 41:59uh
- 41:59both had root Well, Ruby, Emacs, and
- 42:02JavaScript Core
- 42:03all have very sophisticated garbage
- 42:06collectors. By the way, I love the Emacs
- 42:09garbage collector. I've I've an Emacs
- 42:10user for so long, and I never actually
- 42:12had a reason to look at the C code of
- 42:14Emacs. And lo and behold, Emacs is this
- 42:17like beautiful Lisp virtual machine
- 42:21with this awesome garbage collector.
- 42:23It's got all these cool features,
- 42:25finalizers and weak references. Um
- 42:28really great stuff, but of course it's
- 42:30allocating these like uh
- 42:33large regions that it then chops up into
- 42:35objects. Um
- 42:36uh and uh and it does conservative stack
- 42:39scanning, so it does things like uh
- 42:42calls
- 42:44I hope I'm not messing this up cuz it's
- 42:46a while ago that I ported it, but I
- 42:47think it does the thing where it calls
- 42:49setjmp to get the register file,
- 42:52and then from there scans the stack
- 42:55looking for anything that might look
- 42:56like a pointer. So, that's totally
- 42:58illegal in Fil C. You can't do that in
- 43:00Fil C. I wouldn't let you.
- 43:02So, there for those programs, Emacs,
- 43:04Ruby, and JavaScript Core, I just ripped
- 43:07the GC out
- 43:09Okay. and replaced all of the entry
- 43:11points into the garbage collector with
- 43:12just calls to malloc.
- 43:14Um and just rely on the fact that in Fil
- 43:16C, if you call malloc and never call
- 43:17free, you're garbage collected.
- 43:19Um
- 43:21uh and then in in some cases, you have
- 43:23to go a little bit further, like in
- 43:25Ruby,
- 43:26uh objects have finalizers,
- 43:29and the finalizers are necessary for
- 43:32semantics.
- 43:33You actually can't successfully run a
- 43:36Ruby program
- 43:37if you don't support the finalizers. So,
- 43:40the So, Fil C has a special additional
- 43:43API uh stoodfil.h
- 43:46that you can include. And in there,
- 43:48there's additional APIs you can call
- 43:50where you actually can do things like uh
- 43:53allocate weak references and allocate
- 43:56objects that have finalizers.
- 43:58Um and so, the the Ruby uh
- 44:01the the Ruby port does the thing where
- 44:03every Ruby object is a finalizable Fil C
- 44:06object. Um so that the Ruby finalizer
- 44:09semantics are are are still are still
- 44:12there.
- 44:14Um
- 44:15yeah, that's what it looks like to port
- 44:17these programs.
- 44:18I trying to remember things to unpack
- 44:21there. So, one thing to unpack is
- 44:25the reason that arenas are being
- 44:28mentioned here, right? Is because the
- 44:32entire premise of memory safety is that
- 44:35you have some underlying policeman,
- 44:38right? Who you are articulating your
- 44:42expected
- 44:44memory capabilities to this policeman,
- 44:47and then they are watching you, right?
- 44:49To make sure that you don't disobey
- 44:51them. So,
- 44:52when I allocate a specific thing like
- 44:55I'm allocating this memory that I'm
- 44:57going to store this particular
- 44:58information for a network socket, right?
- 45:02You are telling the policeman, which in
- 45:04this case is is fill C, right? You're
- 45:06telling the policeman like anyone with
- 45:09this pointer that comes back from that
- 45:11allocation is only allowed to talk about
- 45:14that exact single chunk of memory, just
- 45:17that one socket. And then the
- 45:19policeman's like, great, I'll watch that
- 45:20for you, and if you ever try to use that
- 45:22pointer to talk about anything else, I
- 45:24will stop you right there, right? You're
- 45:26going to fill jail.
- 45:28The
- 45:29And so what happens is if you look at an
- 45:31existing program, and that existing
- 45:33program was trying to do something
- 45:35efficient, so it allocates something
- 45:36like an arena,
- 45:39and more importantly than arena, arena
- 45:41just, you know, I mean, generally just
- 45:42means we're going to free everything at
- 45:43once, but let's say something more like
- 45:45a stack allocator. I allocate a bunch of
- 45:46memory, and then I'm just going to like
- 45:48bump an integer to tell me like where I
- 45:49am in it, and hand those out cuz I'm
- 45:51going to allocate lots of sockets, like
- 45:54lots of storage for socket information
- 45:55or something like that.
- 45:57Then the problem is the part of your
- 45:59program that's talking to the policeman
- 46:02is just the part that allocates the big
- 46:04block for all that, you know, hundreds
- 46:07of sockets that you might be talking
- 46:09about later. It's going to allocate that
- 46:10giant block, and then it's individually
- 46:13handing those out, right, to parts of
- 46:15the program.
- 46:17And so, the policeman has never been
- 46:19told that you're parcelling this out
- 46:22into separate pieces, and that you
- 46:24actually also would like that policeman
- 46:27to check to make sure that anyone handed
- 46:29one of those little pieces cannot talk
- 46:32about some other of the little pieces,
- 46:34right? So, the point about the arena
- 46:37thing, it's not really about
- 46:38compatibility. I mean, you can correct
- 46:40me if I'm wrong, Phil, but I believe if
- 46:41you compile an arena program with PhilC,
- 46:43it will just work.
- 46:44The only reason you have to take these
- 46:46extra steps to like articulate further
- 46:49to PhilC, oh, actually I was talking
- 46:52about lots of little individual things
- 46:53there, is because you want the extra
- 46:56benefits of more granular memory safety
- 47:00than you were getting, right? So, you
- 47:02would still never get the case where
- 47:03somebody who's talking about objects in
- 47:06one arena can talk about objects in
- 47:08another arena because PhilC will be
- 47:10properly preventing that automatically,
- 47:12even without any modification. It's but
- 47:14when you want things inside an arena to
- 47:16themselves be policed so that nobody
- 47:19with a pointer to one thing in arena can
- 47:21talk about a pointer to another thing in
- 47:22the arena, right, by just jumping
- 47:24forward a little bit or backwards a
- 47:25little bit. That's where you then have
- 47:27to
- 47:28make the modification. And again, all
- 47:30you're really doing that for
- 47:32is just to tell PhilC, hey, these are
- 47:35the capabilities I was caring about. And
- 47:39it's it's the easy way to do that is
- 47:42just by saying, well, we all understand
- 47:44like malloc and free, so that's what
- 47:46we're going to use. But really the
- 47:48important part of it conceptually is
- 47:51this idea that somebody at some point
- 47:53needs to articulate to the police, here
- 47:56are the ranges, right? And Malicious
- 47:59Freeze basically doing that for you. So,
- 48:01I just wanted to unpack that for people
- 48:03who, again, I'm just trying to think
- 48:04about things that people who've never
- 48:06thought about memory safety and they're
- 48:07this is their first introduction to it,
- 48:09right? What are the things that they
- 48:10might be like, wait, what? Why do I have
- 48:12to I don't understand. It doesn't work
- 48:13with arenas. No, it works with arenas
- 48:14just fine, but if you want additional
- 48:17memory safety for individual objects in
- 48:18it, that's where you're, you know,
- 48:20looking at that.
- 48:21Um
- 48:22the other thing that I thought might
- 48:24maybe need to be unpacked there uh was
- 48:27just that so
- 48:29uh when
- 48:31when you're looking at at doing
- 48:33um
- 48:34just trying to I'm just trying to think
- 48:35of how to say this. So, when you're
- 48:37talking about doing like um
- 48:39memory safety on on on something like
- 48:41this,
- 48:43the the part about the capabilities is
- 48:46something that has to be tracked
- 48:49forever, right? And this is why all of
- 48:52this dynamic linking and stuff like that
- 48:54comes into play.
- 48:56When you talk about a particular
- 48:58capability, because there is no standard
- 49:02for articulating that anywhere. Like no
- 49:05one has ever defined When we talk about
- 49:08dynamic linking, someone has defined a
- 49:10standard that's like the standard of how
- 49:12these two things come together is we
- 49:15just pass bits that are labeled in some
- 49:18specific way. That labeling never had
- 49:22capabilities.
- 49:23So, the reason that you end up in this
- 49:26situation where you have to start
- 49:28thinking about what happens at the edges
- 49:29of programs is because no one, you know,
- 49:32memory safety is too new effectively.
- 49:34All of the existing standards, ABIs,
- 49:37application binary interfaces, all the
- 49:38things you're used to, none of those had
- 49:41memory safety in mind. And so, this is
- 49:44something that I think we should
- 49:45probably talk about um
- 49:47whenever you think it fits best, but uh
- 49:50feel free kind of has some really
- 49:52I it ways that it works is actually
- 49:55pretty interesting here about how it
- 49:56works around that fact to still get
- 49:58memory safety across the boundary and
- 50:00that's that's a really cool thing
- 50:03about doing these compiles on the full
- 50:05stack like this. But anyway, so just try
- 50:07to remember they probably missed some
- 50:08things in there but I'm just trying to
- 50:09unpack things for people who want more
- 50:11detail, right?
- 50:12Yeah, and you're you're exactly right
- 50:14about arenas. It's they work too well in
- 50:16Fill C. So
- 50:19that's like that's legitimately one of
- 50:21the downsides of the Fill C approach is
- 50:23imagine you have a ginormous code base
- 50:26and you don't have the time to look at
- 50:28all of it. Lo and behold there's arenas
- 50:30everywhere.
- 50:31Um you'll compile it with Fill C it
- 50:33it'll work and you'll probably be be
- 50:35vulnerable.
- 50:38Uh and and that is a problem that
- 50:40affects all memory safe languages,
- 50:42right? Like if you um there was the
- 50:45classic
- 50:46OpenSSL bug where they were reusing
- 50:50a 64 kilobyte buffer um over and over
- 50:53again.
- 50:55Um and you could write that in any
- 50:57language, right? Like you just pull a 64
- 50:59kilobyte buffer and they were storing
- 51:01secrets in there without zeroing them.
- 51:03And of course the attacker could control
- 51:05where in that array you were reading.
- 51:08And so now all of a sudden you had
- 51:09exfiltration of secrets.
- 51:11Um so in any programming language you
- 51:14have to in order to actually get like
- 51:17all of the benefit of memory safety even
- 51:20if it's a memory safe language, you
- 51:21can't just say, "Okay, I'm going to have
- 51:23a giant array where I'm storing all of
- 51:25my data and my pointers are just indices
- 51:28into the array." As soon as you say that
- 51:30then like all bets are off.
- 51:34So I would like to because you mentioned
- 51:37Casey the uh
- 51:39the dynamic when we're linking to a
- 51:42external yellow like that there's a cool
- 51:43part. I would first want to talk about
- 51:45like
- 51:46Fill C on the normal within the program
- 51:49itself, let's say within one binary,
- 51:51right? Because when you're compiling,
- 51:53you're actually adding new LLVM IR.
- 51:57So, can we talk a little bit about that?
- 51:59What is actually happening to implement
- 52:01the
- 52:02capabilities themselves, and then we can
- 52:05move towards like what will happen if
- 52:06you have more than one, for example, DLL
- 52:09linking?
- 52:10Yeah. Um
- 52:13It's It is hard to separate those
- 52:15though, because I did this thing where I
- 52:17started from memory unsafe C, and then I
- 52:20took this giant leap to 100% memory
- 52:23safety. Um and the way that I achieved
- 52:26that was the first version of Phil C
- 52:28what generated the worst code you could
- 52:30possibly imagine. Even doing a pointer
- 52:33plus was a function call to the runtime.
- 52:36Uh pointer dereferences were function
- 52:38calls to the runtime.
- 52:40Function calls were allocations in the
- 52:43heap. Uh just crazy crazy crazy
- 52:46nonsense. Uh
- 52:48just because, again, I Phil C started
- 52:50out as a thesis test. I was sure that
- 52:52this couldn't possibly work, and so I
- 52:54just wanted to make a completely memory
- 52:57safe C as quickly as possible
- 52:59just to convince myself that it's
- 53:01impossible, and then I could move on
- 53:02with my life, right? Just do something
- 53:05else.
- 53:05>> [laughter]
- 53:09>> So, it ended up working. Uh
- 53:12and then and then uh the compiler as it
- 53:14is now is
- 53:16uh the result of incrementally
- 53:18optimizing away the worst of those
- 53:20crimes in the original prototype. Um
- 53:24which is really interesting, cuz we're
- 53:25going to have to talk about Phil C's
- 53:26performance. And if you talk about Phil
- 53:28C's performance, the prob the problem
- 53:30with talking about it is that it like it
- 53:32it started out as the slowest thing you
- 53:34can imagine, and then I
- 53:36brought it to a point where it's fast
- 53:37enough that I can use it, but I haven't
- 53:39actually rolled up my sleeves and done
- 53:42all the things I could could fast.
- 53:44So, what do what happens? What happens
- 53:46is that um
- 53:49a pointer that you're passing around in
- 53:51local data flow
- 53:53um
- 53:54so, a pointer coming out of one
- 53:56expression into another
- 53:58is uh now two pointers. Uh one of those
- 54:01pointers is what I call the integer
- 54:02value, and the other pointer is what I
- 54:04call the lower. Uh why is it called the
- 54:07lower? Because the the trick is that the
- 54:10in every object the pointer to the lower
- 54:13bounds of that object points to the
- 54:16upper end of the capability object. So,
- 54:19the lower is simultaneously the lower
- 54:21bounds that you can check
- 54:23and a pointer to the top of
- 54:26uh the the capability object. Then, the
- 54:29capability object has a pointer to the
- 54:31upper bounds and a pointer to some
- 54:33additional metadata. So, you're always
- 54:35passing around this lower and this
- 54:37integer value.
- 54:38When you access a pointer
- 54:40um then we check that the lower is not
- 54:43null.
- 54:45So, that's a that's a branch, right?
- 54:47Uh if the access has to be aligned in
- 54:51order to be safe
- 54:52uh which is true for pointer accesses
- 54:56then alignment of the integer value is
- 54:58checked, so that's another branch.
- 55:01Um then the lower and upper bounds are
- 55:03checked. The lower and upper bounds
- 55:05checking is more complicated than you
- 55:07would think
- 55:09because uh FullC
- 55:12uh is engineered to be resilient against
- 55:15wrap-around. So, if you if you did the
- 55:18lower and upper bounds check naively,
- 55:21then you could have a pointer to the top
- 55:22of memory
- 55:24accessing an amount of memory that wraps
- 55:26around to the bottom of memory, and then
- 55:28the lower bounds would succeed, and the
- 55:30upper bounds would succeed every time.
- 55:32FullC is resilient against that, so the
- 55:35the way I emit the code for the lower
- 55:37and upper bounds checks is very kind of
- 55:39careful.
- 55:40Um and and more expensive than what it
- 55:42would be if I was just doing it naively.
- 55:45And then if you're if if you're
- 55:47accessing a primitive value, so like an
- 55:49integer or a double or something like
- 55:50that, then that's pretty much the whole
- 55:52story.
- 55:53If you're accessing a pointer, then uh
- 55:56the metadata at the bottom of the
- 56:00pointer you're storing into and out of
- 56:03has a pointer to an extra where the
- 56:07capabilities are. So then if you're
- 56:09accessing if you're loading a pointer
- 56:11from the heap or storing a pointer to
- 56:12the heap, then there's
- 56:15uh
- 56:16quite a lot of additional stuff that the
- 56:18compiler admits. Uh right now,
- 56:21the worst part of that is the code that
- 56:24I admit for loading a pointer. Uh
- 56:26there's there's uh
- 56:29two branches in there that are there
- 56:31just for silly reasons that I need to
- 56:33remove and some integer
- 56:36integer math dependencies that need to
- 56:37be removed. But all in all, like I think
- 56:39loading a pointer from the heap is
- 56:41something like
- 56:4313 instructions on the hot path and like
- 56:46seven basic blocks or something
- 56:48something completely ridiculous. Um so
- 56:51that the highest the the biggest source
- 56:54of overhead in FillC right now is those
- 56:56loads.
- 56:58Um and and and we do have to talk about
- 57:01calls, right? So the calls are memory
- 57:03safe in FillC. And the way that the
- 57:05calls are memory safe is that right now,
- 57:08uh the arguments are passed as a buffer
- 57:13in in the heap.
- 57:15Um uh and that buffer contain There's
- 57:18actually two buffers, one buffer for the
- 57:19integer values and one buffer for the
- 57:21capabilities. Um so what that means is
- 57:24uh C programs that intentionally
- 57:29uh type confuse function signatures
- 57:32work so long as that type confusion
- 57:36isn't too severe.
- 57:38Um, and that's important because real C
- 57:40programs do that. Like it's it's common
- 57:42to have
- 57:44um
- 57:45uh
- 57:46the caller pass the integer zero
- 57:51and the type signature at the call site
- 57:53is that it's an integer and then the
- 57:55callee thinks that they're getting a
- 57:58void star.
- 57:59And it's fine because the the person
- 58:02getting the void star checks is it is it
- 58:04null before doing anything. Well, zero
- 58:06turns into null, so it's all good. FillC
- 58:09allows that because the zero gets passed
- 58:11as a zero with a zero capability. On the
- 58:13other side, you null check it, you get
- 58:15null, you're fine.
- 58:17Um, but that the overhead of the calls
- 58:21themselves is
- 58:24is is really bad. I I
- 58:27the
- 58:28and it's it's it's like it again, you
- 58:31kind of have to like
- 58:32if you want if you want to make fun of
- 58:34FillC, then this is the perfect
- 58:35opportunity to make fun of it. Look at
- 58:37the code generated and be like, "Look at
- 58:39that. That's terrible. What is this guy
- 58:41thinking?" But like
- 58:43there's obviously better ways to do it
- 58:45if you've studied how memory safe
- 58:47languages work. It's just I haven't had
- 58:48a chance to fix it. But anyway, pass
- 58:51arguments and return values are passed
- 58:53in the heap.
- 58:54Uh but at least it's not a dynamic
- 58:56allocation every time that you make a
- 58:58call. It's reusing the same heap
- 59:00location. At least that that's true.
- 59:02Um
- 59:04and and we we do have to talk a little
- 59:06bit about linking because linking is
- 59:07like a fundamental part of C semantics.
- 59:11I think one of the things that makes C
- 59:14special among languages
- 59:17is [snorts] this fact that C has this
- 59:19global name space of symbols
- 59:21that are allowed to be externally
- 59:24resolved.
- 59:25Um, this is a very powerful feature in C
- 59:27and I think is one of the reasons why C
- 59:29gets used to build really large
- 59:30softwares. This enables you to have
- 59:34a very flexible kind of story for how
- 59:37you dynamically link. Whether Well,
- 59:38actually, do you link statically? Do you
- 59:40link dynamically? The language kind of
- 59:41doesn't care. You can do it however you
- 59:43want.
- 59:44And so, um, PhilC does have an answer
- 59:47there. And it even has an answer for
- 59:49what would happen if you, for example,
- 59:52define in one module
- 59:55that uh there's an external symbol
- 59:57called foo and it's a function. And then
- 59:59in another module, you define foo and
- 1:00:01you define it to be a float.
- 1:00:04Um, C allows you to do this.
- 1:00:06Uh, and if you do this normally in C,
- 1:00:09you get whatever the whatever the CPU
- 1:00:11gives you, right? Like
- 1:00:13uh probably you'll get a crash, but
- 1:00:15maybe not depending on what kind of CPU
- 1:00:17you're on. In PhilC, what happens is
- 1:00:21um
- 1:00:22every single global symbol,
- 1:00:26when you refer to it in your C program,
- 1:00:29uh turns into a function call to a
- 1:00:31getter. So, if there's a module that
- 1:00:34exports a symbol, what it's actually
- 1:00:36exporting, so like if you export the
- 1:00:38symbol foo and it's a float, you're
- 1:00:40actually exporting a symbol called
- 1:00:41pislonated_foo.
- 1:00:43And it's always a getter.
- 1:00:45And that getter always returns a PhilC
- 1:00:48pointer, so a tuple of
- 1:00:50uh lower and and intval.
- 1:00:53Um, and so when you
- 1:00:55call foo from another module, that's
- 1:00:57actually two steps. One,
- 1:00:59call the getter for foo so that you can
- 1:01:02get this this pointer. And then two, the
- 1:01:05call is an indirect call. Every call in
- 1:01:07PhilC currently is an indirect call.
- 1:01:10Um,
- 1:01:11where which involves uh checking whether
- 1:01:14the thing you're calling is a function
- 1:01:16pointer,
- 1:01:17uh whether the
- 1:01:19function pointer actually points at the
- 1:01:22function it's supposed to be pointing
- 1:01:23at.
- 1:01:24And then the the passing the arguments
- 1:01:26through the heap and all that kind of
- 1:01:27jazz.
- 1:01:28Um and so that enable that's what
- 1:01:30enables linking to be to work at all and
- 1:01:33and to be memory safe. So you if you
- 1:01:35define
- 1:01:37foo to be a float in one module and try
- 1:01:39to use it as a function in another
- 1:01:40module, you'll get
- 1:01:42a Fil C panic saying you can't call a
- 1:01:44float or something to that effect.
- 1:01:47Um
- 1:01:49Oh yeah, one more thing. There's a
- 1:01:50concurrent GC, right? So
- 1:01:52if you have a GC that supports multiple
- 1:01:55threads, Fil C supports threads.
- 1:01:58Um
- 1:01:59then you need to have some way of
- 1:02:01solving the race that happens
- 1:02:05if one thread has just loaded a value
- 1:02:09from the heap
- 1:02:11and the garbage collector runs at that
- 1:02:13time and deletes the object that you
- 1:02:14just loaded.
- 1:02:16Um Fil C protects against this race
- 1:02:18using a classic approach called safe
- 1:02:20pointing,
- 1:02:21um which basically comes down to every
- 1:02:23function periodically every
- 1:02:26all all generated all code generated by
- 1:02:29the Fil C compiler has periodic checks
- 1:02:31emitted in it to see if it needs to
- 1:02:34report to the GC.
- 1:02:36Um and and the slow path of that has a
- 1:02:39mechanism of uh allowing the stack to be
- 1:02:42scanned and all of the pointers that are
- 1:02:44in local variables to be accurately
- 1:02:47reported to the garbage collector.
- 1:02:49Um
- 1:02:52Yeah, so all of those things are
- 1:02:53happening all at once.
- 1:02:55Um the parts that have been optimized
- 1:02:57the most are
- 1:03:00um
- 1:03:01uh
- 1:03:03Oh oh oh, I forgot one thing. Local
- 1:03:05variables. If you have a local variable
- 1:03:08that escapes, that is the compiler can't
- 1:03:10prove that it that it's just local data
- 1:03:12flow.
- 1:03:13So you take the address of it, when give
- 1:03:15it to some something, so the compiler
- 1:03:17thinks, okay, this has to be on the
- 1:03:18stack. Can't be in a register.
- 1:03:21All of those local variables become uh
- 1:03:23become heap allocations.
- 1:03:25Um Okay.
- 1:03:27So,
- 1:03:28um
- 1:03:30Is that is that the whole story? Yeah,
- 1:03:31that's most of the whole story. And then
- 1:03:33the things that have been optimized is
- 1:03:35that the um
- 1:03:38there is some amount of uh escape
- 1:03:41analysis to make it so that
- 1:03:44uh not literally all of your variables
- 1:03:46become heap allocations.
- 1:03:49Um this is probably the area of the
- 1:03:50compiler that needs the most work still.
- 1:03:53There's a lot of cases in PhilC today
- 1:03:55where a local variable will be a heap
- 1:03:57allocation even though it just does not
- 1:03:59have to be.
- 1:04:00Um
- 1:04:01uh
- 1:04:02And then the other part that's been
- 1:04:03optimized is there's a certain amount of
- 1:04:06redundant bounce check removal.
- 1:04:08Uh not nearly as much as there could be,
- 1:04:10but just just a little teensy bit of
- 1:04:13redundant bounce check removal so so
- 1:04:15far.
- 1:04:17Um
- 1:04:19Yeah, that's
- 1:04:20that's the story what what happens to
- 1:04:22the code.
- 1:04:24Okay, can I just say like
- 1:04:25quick seg- quick segway, for how long
- 1:04:27have you worked on PhilC?
- 1:04:30I started in November of '23.
- 1:04:35Um and it's, you know, I have a
- 1:04:36full-time job. I manage a team.
- 1:04:38>> Yeah.
- 1:04:39Exactly.
- 1:04:39>> So, and I have I'm a single dad. I have
- 1:04:41two kids. So,
- 1:04:42>> Jesus. uh there's some days I don't work
- 1:04:45on it at all. Uh
- 1:04:46uh some days I get get a couple of hours
- 1:04:48in.
- 1:04:49Um
- 1:04:51uh You're effective. Like you
- 1:04:54Well,
- 1:04:55Well, so the the PhilC runtime is uh
- 1:04:59about 15,000 lines of code.
- 1:05:01And the main PhilC compiler pass is
- 1:05:03about 13,000 lines of code.
- 1:05:05So, a lot of the I think the the
- 1:05:07remarkable thing about PhilC is that it
- 1:05:10it what I what I kind of found is like
- 1:05:12what is the most surgical way that I can
- 1:05:15do this using things that are already
- 1:05:18out there LLVM and clang um uh
- 1:05:21primarily um
- 1:05:24and and and I really have been religious
- 1:05:27about saying look the the the goal here
- 1:05:30is full compatibility so that I can
- 1:05:32convert code
- 1:05:33to it with very little effort and let's
- 1:05:35just like not worry about performance
- 1:05:37too much for now you know like
- 1:05:40it cuz the the thesis is is if if
- 1:05:44if if I built a fast implementation of
- 1:05:47memory safe C that couldn't run any
- 1:05:49programs
- 1:05:51then who cares
- 1:05:54um
- 1:05:56like if you can't run any C programs
- 1:05:57there's already memory safe languages
- 1:05:59you could rewrite your C program into
- 1:06:02so that like I'm just reducing scope
- 1:06:05very aggressively to just like let's
- 1:06:07prove that you can make the C language
- 1:06:08memory safe and kind of defer everything
- 1:06:11else like performance like let's worry
- 1:06:13about that later
- 1:06:14>> [laughter]
- 1:06:15>> Although that said the performance is
- 1:06:16not that bad.
- 1:06:18Yeah it's kind of it's that's
- 1:06:20but it's still like well Compared to
- 1:06:22what you would expect yeah.
- 1:06:24>> Compared to what you would expect
- 1:06:25although you should have seen how long
- 1:06:27it took me to post on Twitter last
- 1:06:29night.
- 1:06:30>> [laughter]
- 1:06:31>> Fair enough.
- 1:06:34How long was it that you measure like
- 1:06:36what was the um it it took uh I think it
- 1:06:41takes something like 15 seconds
- 1:06:44for the x.com
- 1:06:46uh login window to pop up
- 1:06:49and then it takes between 10 and 15
- 1:06:51seconds between when I type in my login
- 1:06:53until when it shows me the password
- 1:06:55thing
- 1:06:56and then probably like
- 1:06:5820 to 30 seconds before I get to the
- 1:07:01what's happening and I can type
- 1:07:02something
- 1:07:03um
- 1:07:05uh So only slightly slower than normal.
- 1:07:08>> [laughter]
- 1:07:09>> Yeah. Well, what's interesting is I was
- 1:07:12mentioning before that one of the
- 1:07:13biggest weaknesses of PhilC is the
- 1:07:15escape analysis.
- 1:07:17And in JavaScript core
- 1:07:19one of the things we do all the time in
- 1:07:21JSC is
- 1:07:23really wacky unions.
- 1:07:26Like typical value being passed around
- 1:07:29in JSC is either going to be in a union
- 1:07:31or is going to be passed through a
- 1:07:32union. And right now the way that I
- 1:07:37I make LLVM's optimizations sound under
- 1:07:41unions is that I don't allow them to
- 1:07:44happen. So when you have a union,
- 1:07:48the escape analysis in LLVM that would
- 1:07:50have turned that union into a local
- 1:07:51variable just doesn't happen. It's you
- 1:07:53end up with a heap allocation. So I
- 1:07:55think what's happening during those 15
- 1:07:56seconds is every local variable in the
- 1:08:01JavaScript interpreter is being like
- 1:08:02heap allocated then heap allocated
- 1:08:04again. Like totally crazy.
- 1:08:07Um but uh but also if if you if you're
- 1:08:11want to bet against PhilC then you
- 1:08:13should be worried because this is
- 1:08:14something that I am
- 1:08:16you know, equipped as a compiler
- 1:08:17engineer to fix if I wanted to. If I had
- 1:08:20the time to.
- 1:08:22Do you have any I think you mentioned
- 1:08:25either on Twitter or somewhere
- 1:08:27like
- 1:08:28performance comparison to what would be
- 1:08:30like the normal let's say curl and then
- 1:08:33PhilC compiled curl. Like would it be
- 1:08:35like you know, two times slower like one
- 1:08:37time like four times slower. What would
- 1:08:40be the range usually? Huge range. Uh so
- 1:08:44for example, if you have
- 1:08:46uh
- 1:08:47C++ code that is um somewhat IO bound
- 1:08:53like xz utils
- 1:08:55the compression codec
- 1:08:58then the slow down
- 1:09:00um is like 1.2x or something like this.
- 1:09:04If you're really IO bound, there's no
- 1:09:06slowdown.
- 1:09:07Um, if you have a program that is
- 1:09:10aggressively using SIMD intrinsics,
- 1:09:14um,
- 1:09:15uh, then the slowdown is less than 2x.
- 1:09:17So, a lot of Dan Daniel Lemire's, uh,
- 1:09:21C++ libraries that use SIMD intrinsics
- 1:09:24have just very low slowdowns from what I
- 1:09:26can tell.
- 1:09:27Um, below 2x, sometimes it's like 1x.
- 1:09:30And the reason is that if if if all of
- 1:09:32your logic is loading and storing
- 1:09:35AVX-512 vectors,
- 1:09:38I'm still doing just one bounce check
- 1:09:40for that one AVX-512 vector load or
- 1:09:42store, but you're getting 512 bits,
- 1:09:45you know,
- 1:09:46from from it. So, the the cost of the
- 1:09:49fill C checks becomes aggressively
- 1:09:51amortized. So, if you're a SIMD
- 1:09:53programmer, fill C is like great. Um,
- 1:09:57uh, until you do a function call and
- 1:09:59then I'm going to put your SIMD vectors
- 1:10:01in the heap, but
- 1:10:02I'll fix that eventually. Um,
- 1:10:05>> [laughter and clears throat]
- 1:10:06>> um,
- 1:10:08if you're an interpreter, like the
- 1:10:09Python interpreter,
- 1:10:11uh, or the JavaScript core interpreter,
- 1:10:13then the slowdown is is somewhere in the
- 1:10:16vicinity of like more than 7x, sometimes
- 1:10:1810x.
- 1:10:20Um, and that's because interpreters
- 1:10:22typically are dealing with,
- 1:10:24uh, data structures that have pointers,
- 1:10:26um, and they have unions. So, uh, you
- 1:10:29kind of end up hitting,
- 1:10:31uh, some of fill C's worst cases in that
- 1:10:33in that situation.
- 1:10:35Um,
- 1:10:36a lot of programs are in the 2x, 3x, 4x
- 1:10:40regime.
- 1:10:42And a lot of programs
- 1:10:45have the kind of slowdown where you sort
- 1:10:49of don't care.
- 1:10:50Um, like, uh,
- 1:10:52the work that I was doing to port, uh,
- 1:10:55about
- 1:10:55to fill C is on Pizlex. So, I'm in a
- 1:10:59terminal that's written in PhilC, Bash
- 1:11:01written in PhilC. I'm committing to
- 1:11:03GitHub using a Git compiled with PhilC
- 1:11:06over an SSH compiled with PhilC, and I'm
- 1:11:09writing code in Emacs compiled with
- 1:11:11PhilC, and it's just fine. I'm grepping
- 1:11:15with a grep written in PhilC. I'm
- 1:11:16opening large log files in Emacs, and
- 1:11:18it's all written in PhilC, and it's just
- 1:11:20it's fine. It's like it's whatever.
- 1:11:22Um if I if I look carefully at the
- 1:11:25responsiveness, you can kind of tell
- 1:11:27that it's like not
- 1:11:29you know, what my computer would
- 1:11:30normally be capable of, but it's it's
- 1:11:33fast enough to just to just use and not
- 1:11:35care.
- 1:11:36Um
- 1:11:37and and that's kind of been my standard
- 1:11:39is like I just optimize things enough to
- 1:11:42get to that point where for the things
- 1:11:44that I care about, it's it's fast
- 1:11:45enough. It's just it's fine.
- 1:11:49Okay.
- 1:11:50Okay, so do you want to unpack some of
- 1:11:52the things said previously about how
- 1:11:55PhilC works? Um I mean, I think not not
- 1:11:59particularly because I think if we were
- 1:12:01to unpack those like any any in
- 1:12:04particular unpacking requires a lot of
- 1:12:06stuff if you want to go the whole nine,
- 1:12:09right? Um you know, even just looking at
- 1:12:11something at like he was talking about
- 1:12:14reducing
- 1:12:15bounds checking and things like that.
- 1:12:17And
- 1:12:19I mean, I guess just the way that I
- 1:12:20would say it for people who are new to
- 1:12:21this is if you imagine what's going on
- 1:12:25when you're talking about something in a
- 1:12:27high-level language, which at this point
- 1:12:29C is kind of
- 1:12:31maybe not properly called that because
- 1:12:33things have gotten so high-level, but
- 1:12:35you know, in the old days it was
- 1:12:36considered a higher-level language
- 1:12:38uh than something like assembly.
- 1:12:40When you're talking about this sort of
- 1:12:41thing,
- 1:12:42you the compiler is looking at
- 1:12:44everything you do. You know, you've got
- 1:12:46something like a pointer, and you're
- 1:12:47going to go talk or or you know, you
- 1:12:50think of maybe a reference to an object.
- 1:12:52However, you want to conceptualize it
- 1:12:53nowadays in the at the higher level.
- 1:12:56If you imagine what's happening inside a
- 1:12:57typical function, you have a lot of
- 1:12:58things such as, "Oh, I have this
- 1:13:00particular object um and I'm going to go
- 1:13:03get like this X value from it and this Y
- 1:13:06value from it and this string pointer
- 1:13:08for what its name is and things like
- 1:13:09this."
- 1:13:11So, if you can imagine in your head,
- 1:13:13Filthy's job is to protect all of those
- 1:13:16things. So, if you're going to go read
- 1:13:18the X coordinate out of some, you know,
- 1:13:20sprite that's in some location or
- 1:13:22whatever it is that you're imagining in
- 1:13:23your head,
- 1:13:24Filthy's job is to make sure that when
- 1:13:26you actually when you're asking for the
- 1:13:28X coordinate of this sprite, that the
- 1:13:30handle or whatever the thing that you're
- 1:13:32getting, which in this case would be,
- 1:13:33you know, a pointer or a reference, that
- 1:13:35that actually was legitimately
- 1:13:37originally something
- 1:13:39from an allocation of that particular
- 1:13:42sprite and that you had the authority
- 1:13:44when you got it to access that X
- 1:13:46coordinate, right?
- 1:13:48And if you think about the naive
- 1:13:50implementation of this,
- 1:13:52every single time you access anything
- 1:13:54anywhere from any handle, right?
- 1:13:58Anything that ever had its address
- 1:13:59taken, anything that ever had a pointer
- 1:14:01to it, all this thing, every single one
- 1:14:02of those has to have this sort of
- 1:14:05structure put around it in its actual
- 1:14:07run time code, so the machine code being
- 1:14:09generated,
- 1:14:11to look and see, "Did this pointer
- 1:14:14actually have the ability to access this
- 1:14:17thing?"
- 1:14:19And so, when we talk about optimization
- 1:14:21for something like Filthy, you can kind
- 1:14:22of now imagine your head like, "Oh,
- 1:14:24okay, like
- 1:14:26for for starters, if I'm accessing two
- 1:14:29different fields in the same object that
- 1:14:30are right next to each other, it would
- 1:14:32be pretty trivial for me to aggregate
- 1:14:35out a check to just see, let me do one
- 1:14:37check to make sure that I can access
- 1:14:39both of these things cuz that will be
- 1:14:41cheaper than checking each one
- 1:14:42individually before I check it, right?"
- 1:14:46Multiply that by a thousand, right?
- 1:14:48There are so many cases that you could
- 1:14:50imagine when you start going and like
- 1:14:52I'm going to spend, you know, if if this
- 1:14:54wasn't his spare time project, right?
- 1:14:57There are so many ways that you can
- 1:14:58imagine now like from the naive thing,
- 1:15:01which is just the thing you used to just
- 1:15:02get it working to a more complete
- 1:15:05picture where we're doing all kinds of
- 1:15:07static analysis to figure out like, oh,
- 1:15:09this variable never really escaped and
- 1:15:11the only people who like actually looked
- 1:15:12at its location were people I'm
- 1:15:14immediately calling and I know that they
- 1:15:16never actually do anything with it. So,
- 1:15:17we eliminated all of that and all the
- 1:15:19bounce checks went away and the whole
- 1:15:21thing can just be on the stack now. Like
- 1:15:23all of that is real work, like hard
- 1:15:25compiler work.
- 1:15:27And it's the kind of thing that's been
- 1:15:28done
- 1:15:29for optimizations for, you know, every
- 1:15:31other language. PhilC is brand new and,
- 1:15:34you know, there's not enough people
- 1:15:35working on it right now, right? And so,
- 1:15:38when you look at the performance of
- 1:15:39something like PhilC, it's very hard to
- 1:15:41say where it would eventually get to if
- 1:15:43you imagined a bunch of serious compiler
- 1:15:46people taking it seriously for a long
- 1:15:48time, finding all of those cases, doing
- 1:15:51all of that work.
- 1:15:52All of this stuff starts to now become
- 1:15:54faster and faster and faster and faster.
- 1:15:56So, it's, you know, I don't know how to
- 1:15:58put that picture in people's head, but
- 1:16:00it is a thing where
- 1:16:02if you asked people 30 years ago would
- 1:16:05the kinds of optimizations that
- 1:16:07something like Clang is doing be common
- 1:16:09and just happen automatically in a one,
- 1:16:12you know,
- 1:16:13one-shot compile that you just do
- 1:16:14doesn't run for 3 days, right? Just
- 1:16:16compiles your program.
- 1:16:17They would be kind of astonished at some
- 1:16:19of the program transformations that are
- 1:16:21now routine in something like Clang's
- 1:16:24back or LLVM's back end.
- 1:16:26And so, you just have to keep in mind
- 1:16:28that that what you're comparing PhilC to
- 1:16:32is something that's had absolutely
- 1:16:34heroic
- 1:16:35all kinds of craziness happening in its
- 1:16:37optimization passes and PhilC hasn't had
- 1:16:40a chance to have all that done. So,
- 1:16:41that's one of the reasons why
- 1:16:44no one right now can really state like
- 1:16:47how far could you go performance-wise on
- 1:16:49this. The The answer is
- 1:16:51I don't know, give it 20 years and we'd
- 1:16:54probably be shocked at how, you know,
- 1:16:56fast it could run over, you know,
- 1:17:00what you see today. Right? That's And
- 1:17:01so, I just want to make sure people
- 1:17:02understand these these deltas
- 1:17:05because compilers, you know, when we
- 1:17:07when we run compiled languages today,
- 1:17:09we're no longer thinking of just a
- 1:17:11straightforward compile like in the old
- 1:17:13days. We're thinking of massive program
- 1:17:15transformations that are very regularly
- 1:17:16applied and that same sort of thing can
- 1:17:18happen to FilC over time. Yeah.
- 1:17:23I would be interested to know where do
- 1:17:25you want to take FilC from where is it
- 1:17:27now?
- 1:17:29Like
- 1:17:30because you can spend your time, limited
- 1:17:32time, on like doing compiling different
- 1:17:35existing projects and checking whether
- 1:17:37they work,
- 1:17:38doing optimizations as mentioned. But
- 1:17:41probably like being tied to LLVM doesn't
- 1:17:44help with every now and then updating
- 1:17:46the LLVM and making sure that new things
- 1:17:48work and like, you know, everything's
- 1:17:50working and here's like you kind of
- 1:17:52always chasing the the the LLVM stack.
- 1:17:55So, how do you see the FilC now and
- 1:17:57where where would it go?
- 1:18:00Um
- 1:18:01So,
- 1:18:02about the chasing LLVM, it took one day
- 1:18:05to rebase FilC from LLVM 17 to LLVM
- 1:18:0820.1. Okay.
- 1:18:10>> cuz it it really is like this this like
- 1:18:13surgical, careful injection. So, I'm
- 1:18:17actually not too worried about the
- 1:18:20rebasing part of it. Um
- 1:18:22I do I think that the
- 1:18:24the thing that's brought the most value
- 1:18:26so far
- 1:18:27is porting lots of software to it
- 1:18:30because the way you
- 1:18:33do quality assurance on a compiler
- 1:18:37Let me back up. The thing that makes
- 1:18:38compilers super interesting um compared
- 1:18:41to other software is just the level of
- 1:18:44quality that they achieve. Like the
- 1:18:46likelihood that you're going to
- 1:18:47encounter a compiler bug is low uh to
- 1:18:51the point that there's jokes that you
- 1:18:52know you tell you tell uh startup
- 1:18:55starting programmers that anytime you
- 1:18:57think something is a compiler bug, it's
- 1:18:58not. Assume it isn't, right? It's never
- 1:19:01a compiler bug is what you tell people.
- 1:19:03And that's because compilers are that
- 1:19:04reliable. Um and so
- 1:19:08uh with Phil C, the thing that I want to
- 1:19:10do is I want to achieve that level of
- 1:19:12reliability in the compiler that when
- 1:19:15someone tries it out they are surprised
- 1:19:18and joyful about the fact that it just
- 1:19:20worked.
- 1:19:22And the way that you do that is
- 1:19:25you have to be able to test the compiler
- 1:19:27on a massive amount of code. Um
- 1:19:30compilers like clang
- 1:19:32um get tested not just on their own test
- 1:19:34suite but people who work on clang are
- 1:19:37at large corporations that have a
- 1:19:39billion lines of C++ code that they can
- 1:19:41try to compile it on.
- 1:19:43So the the
- 1:19:45the upside um to Phil C as a project to
- 1:19:49people trying Phil C of me porting tons
- 1:19:51and tons of programs to Phil C is that I
- 1:19:54am going to find the bugs before you do.
- 1:19:57So when you try it on your project,
- 1:19:59you're just going to be happy that it
- 1:20:01worked and you're not going to have to
- 1:20:02deal with with bugs.
- 1:20:04So I'm just going to keep doing that cuz
- 1:20:06one of the things that brings me the
- 1:20:08most joy is like I get an email or a
- 1:20:11message on Discord or Twitter from
- 1:20:13people once in a while where they're
- 1:20:15like, "Wow, I tried this on my program
- 1:20:17and I was surprised that it just
- 1:20:19worked."
- 1:20:20Um I I want to I I mean, that that makes
- 1:20:22my day, right? So like I want I want
- 1:20:24more of more experiences like that for
- 1:20:27people.
- 1:20:28Um
- 1:20:29and I think because of the fact that
- 1:20:31people are having those experiences,
- 1:20:32Fill See has gone in in the last year or
- 1:20:35so from being like kind of an obscure
- 1:20:38thing to being a thing that actually has
- 1:20:40like users and um a handful of
- 1:20:44contributors beyond just me.
- 1:20:46Um so I think I'm on a good trajectory
- 1:20:48just by doing that.
- 1:20:49Um interestingly though,
- 1:20:52with WebKit uh now starting to work and
- 1:20:56being
- 1:20:57uh too slow for for for my tastes, it's
- 1:21:01likely that I'm going to take a detour
- 1:21:02to do some optimizations. Just I want to
- 1:21:05be able to uh
- 1:21:07to you know, go on Twitter and and and
- 1:21:10use Twitter uh in a memory safe way
- 1:21:13um
- 1:21:13and not have to wait for like 15 seconds
- 1:21:16for the thing to load.
- 1:21:18Um so I'm going to try to see if I can
- 1:21:19do that. Um
- 1:21:22uh
- 1:21:24But beyond that, I'm not sure. I think
- 1:21:26this is still like an experiment. It's
- 1:21:28gone beyond the technical experiment to
- 1:21:30now being a social experiment.
- 1:21:32Um like the question the question is how
- 1:21:35many C++ shops
- 1:21:38uh out there uh would like to do things
- 1:21:42this way
- 1:21:43uh rather than the alternatives that are
- 1:21:45in front of them. The alternatives that
- 1:21:46are in front of them are
- 1:21:48uh rewrite in Rust,
- 1:21:50which you know, has its independent
- 1:21:52benefits. There's things about Rust that
- 1:21:55you like you might like Rust more than
- 1:21:57C++, in which case if you rewrite in
- 1:21:58Rust, you're going to be happy, right?
- 1:22:01Whatever. That's something that some
- 1:22:02people are going to choose
- 1:22:04uh if they're into that sort of thing.
- 1:22:06Um and then the other option is you
- 1:22:08could choose to just stick with normal
- 1:22:09C++.
- 1:22:12That might be the right option for some
- 1:22:13C++ shops,
- 1:22:15right? Um
- 1:22:16like if I'm playing a single-player game
- 1:22:18on my computer, I don't really care if
- 1:22:20it's memory safe. I just want it to be
- 1:22:22fast. I want the pixels to look pretty.
- 1:22:25Um right? And so for a lot of for a lot
- 1:22:28of domains, uh, just sticking with
- 1:22:30normal C++ might be fine.
- 1:22:33Um,
- 1:22:34so,
- 1:22:35I think the the thing that's the thing
- 1:22:37that's exciting for me going forward
- 1:22:39with this project is to see
- 1:22:41what other people decide now that they
- 1:22:44have, uh, FILSIC as an option.
- 1:22:48This is this is this is tying to a sort
- 1:22:51of my next question, meaning
- 1:22:54what do you see as the early adopters?
- 1:22:57Who do you see as the early adopters of
- 1:22:58FILSIC, uh,
- 1:23:00like as a category, right? Like people
- 1:23:02who are making software in C++ and
- 1:23:05they're like worried about the weird
- 1:23:07execution being possible. Is because
- 1:23:11like game as you mentioned, like games
- 1:23:13not necessarily like the most interested
- 1:23:15clients in FILSIC, where would you see
- 1:23:18them, the clients? Yeah. Uh, so, there's
- 1:23:21a there's a a handful of, um,
- 1:23:24uh, security-conscious people who I know
- 1:23:26who are running, um, like
- 1:23:28FILSIC-compiled OpenSSH server.
- 1:23:32That's a great idea. Um,
- 1:23:35you can do that today.
- 1:23:37Uh, in fact, the optFILSIC distribution
- 1:23:38is the optimal way to do that. Um, and
- 1:23:41the one thing I'll mention about the
- 1:23:42optFILSIC distribution is it comes with,
- 1:23:45uh, things like PAM, uh, and SE Linux
- 1:23:49libraries, so that when you start that
- 1:23:52SSHD men, it can actually use your
- 1:23:54existing SSHD men configuration,
- 1:23:56including your existing PAM stack.
- 1:23:59Um, so, you get like a completely
- 1:24:01memory-safe password authentication
- 1:24:04workflow, you get memory-safe OpenSSL,
- 1:24:08um, and the OpenSSL has has specific
- 1:24:10defenses in it to make sure that the
- 1:24:12crypto still has constant-time crypto in
- 1:24:15it. So, that's like a thing you can you
- 1:24:17can use, and there are people using
- 1:24:18that. So, that's one category of early
- 1:24:20the
- 1:24:21Another category of early adopter is
- 1:24:24um from what I've been hearing, there's
- 1:24:26folks who are shipping
- 1:24:29a server
- 1:24:31uh product of some sort.
- 1:24:33Um uh I think some of them are like it's
- 1:24:36like an embedded thing. There's some
- 1:24:37embedded device and it's got a server
- 1:24:39written in C++. The things connect to.
- 1:24:42Um and folks in that category um ha-
- 1:24:45have have been switching to Phil C++ and
- 1:24:47Phil C. I don't have a good handle on
- 1:24:49how many, but it it's a non-trivial
- 1:24:52number considering I've received a
- 1:24:54non-trivial number of emails from people
- 1:24:56saying they have done this.
- 1:24:59Um so um
- 1:25:01like you have to assume that not
- 1:25:03everybody who does this is going to drop
- 1:25:05a line and tell me that they did it,
- 1:25:07right? So there's there's some there's
- 1:25:09that's already out there. Like that ship
- 1:25:10has sailed. People are doing it. And the
- 1:25:13it's interesting like um like one of one
- 1:25:16of the emails that I received, they're
- 1:25:18like uh
- 1:25:20it worked out of the box. We're super
- 1:25:21happy.
- 1:25:22We measured performance on our
- 1:25:24benchmarks and it was 40% slower, but
- 1:25:26that's still within our budget. So we
- 1:25:29just did it.
- 1:25:30Um
- 1:25:31I think there there's a there's probably
- 1:25:33a large number of people out there like
- 1:25:35that who wrote a piece of server code in
- 1:25:39C or C++ because just that's
- 1:25:42what what it made sense to them.
- 1:25:45Uh and now memory safety is a thing and
- 1:25:47rather than having to rewrite it in a
- 1:25:49different language, they chose
- 1:25:51uh Phil C.
- 1:25:53That's an interesting category because
- 1:25:55let's say that you're writing um a
- 1:25:57server that operates in the embedded
- 1:26:00space. And so maybe it has to make some
- 1:26:02weird system calls
- 1:26:04to talk to a custom piece of hardware.
- 1:26:06Um
- 1:26:07Phil C is the only memory safe game in
- 1:26:10town in that case because if you want to
- 1:26:13make a weird syscall from Rust, you have
- 1:26:15to use an unsafe statement.
- 1:26:17If you want to make an unsafe syscall
- 1:26:18from Java, you have to write C code that
- 1:26:20you then bind to the Java and you get a
- 1:26:22bunch of memory unsafety. And it's very
- 1:26:24risky to do that. You can make mistakes
- 1:26:26when you do that. But in Phil C, you get
- 1:26:29all of the Linux syscalls
- 1:26:31and the Phil C runtime actually filters
- 1:26:33them for memory safety violations.
- 1:26:36So, if you need to do like some weird
- 1:26:38ioctl or fcntl or setsockopt or some
- 1:26:42weird stuff
- 1:26:43to set up whatever thing you need to do
- 1:26:46to or some weird memory mapped IO or
- 1:26:49whatever,
- 1:26:50you can do that in Phil C and it's
- 1:26:51memory safe.
- 1:26:53Um
- 1:26:54and so like if if you're writing that
- 1:26:57kind of low-level systems code and you
- 1:26:59need to flip the switch and make it
- 1:27:00memory safe today, then Phil C is going
- 1:27:03to be the the thing that that's going to
- 1:27:05let you do that.
- 1:27:07Um
- 1:27:08So, I think that's where that's where a
- 1:27:09lot of the adopters are.
- 1:27:11Um and probably that's where it'll kind
- 1:27:13of grow out of.
- 1:27:15Um but at the same time, what I want to
- 1:27:17do is I want to create um an OS that you
- 1:27:21can install eventually that has a web
- 1:27:23browser that's memory safe cuz there's a
- 1:27:25category of people out there who will
- 1:27:28want to be able to browse the web
- 1:27:30without having to worry about um some
- 1:27:33government agency hacking them while
- 1:27:35browsing the web. Um
- 1:27:37and Phil C might be the only game in
- 1:27:39town uh there as well.
- 1:27:43Now, can we mention also like uh you're
- 1:27:46you're you're keep mentioning that this
- 1:27:48is the only game in town in terms of
- 1:27:50software. There are other like
- 1:27:52alternatives that try to do the same
- 1:27:55thing-ish,
- 1:27:56but
- 1:27:58uh uh I think you even posted about them
- 1:28:00on Twitter or something. So, can you can
- 1:28:02you
- 1:28:03roughly like say how to what's the
- 1:28:05lookout in terms of like memory safety?
- 1:28:07Because Rust is like a famous option.
- 1:28:11Famous option for but we have memory
- 1:28:12safety, so of course Rust. But uh others
- 1:28:15are other projects that are trying to do
- 1:28:17similar things.
- 1:28:19Um
- 1:28:20let's see. I think there's a couple of
- 1:28:21categories. One is memory-safe
- 1:28:23languages. There's lots of memory-safe
- 1:28:26languages. Um you know, Go, uh Swift, um
- 1:28:31uh Rust, obviously, uh C#, Java. Lots of
- 1:28:34languages out there that are
- 1:28:35memory-safe.
- 1:28:37I think the comparison
- 1:28:39uh to PhilC is as follows.
- 1:28:42Most of those languages
- 1:28:45achieve memory safety for the the stuff
- 1:28:47that you write,
- 1:28:49but strongly rely on linking against
- 1:28:52memory-unsafe programs.
- 1:28:54Um so, this is this is a problem that
- 1:28:57plagues Rust and Swift and Go. Uh like
- 1:29:00with Go, uh Docker is written in Go.
- 1:29:02Great. You look at the stack of
- 1:29:04libraries it links to, they're C
- 1:29:05libraries. They're not memory-safe.
- 1:29:07Rust, you have the uh pseudo RS port,
- 1:29:11pseudo rewritten in Rust. It links to
- 1:29:13PAM. PAM is written in C. Again,
- 1:29:15memory-unsafe.
- 1:29:17Um so, I think the comparison between
- 1:29:19PhilC and a lot of the other approaches
- 1:29:22is
- 1:29:23uh just how fanatically far PhilC is is
- 1:29:26taking it. Um I'm sort of saying
- 1:29:29performance be damned. Um let's just
- 1:29:31make the whole stack memory-safe all the
- 1:29:33way down to the system call layer.
- 1:29:36Um and
- 1:29:37uh
- 1:29:38other others are in this space aren't
- 1:29:40thinking quite that aggressively.
- 1:29:43Um
- 1:29:44I think uh just to give a shout-out to
- 1:29:46Go here, uh Go might might be the
- 1:29:49closest to this in the sense that
- 1:29:51there's a variant of Go where Go uh gets
- 1:29:54rid of the C standard library entirely,
- 1:29:56and you make sys calls directly from Go.
- 1:30:00Um so, that's the closest uh thing to
- 1:30:03PhilC out there. But Go isn't completely
- 1:30:06memory-safe in the sense that there's
- 1:30:08situations where race conditions and go
- 1:30:10can be used as an escape hatch from the
- 1:30:12type system. Um PhilC doesn't have like
- 1:30:15a type system escape hatch if you race.
- 1:30:17Um so again, like it's it
- 1:30:21It it weirdly
- 1:30:23uh this little project of mine has this
- 1:30:27uh unique status of taking memory safety
- 1:30:30further than these other projects have
- 1:30:32taken it. Um now there's another class
- 1:30:34of project which is other folks have
- 1:30:36also had this idea of making C memory
- 1:30:40safe.
- 1:30:41Um
- 1:30:41there's a ton of academic literature in
- 1:30:43this space. I've read almost all of it.
- 1:30:46I've read all all of it that I could
- 1:30:47have read. Um probably the biggest
- 1:30:50inspiration for what PhilC does comes
- 1:30:52from
- 1:30:53uh a project called C cured uh from the
- 1:30:55early 2000s. Um
- 1:30:58uh and from another project called
- 1:31:00SoftBound uh from the like 10 years ago.
- 1:31:04Um
- 1:31:05The way that PhilC differs from those
- 1:31:07projects is that those projects were
- 1:31:10written in like a
- 1:31:12like typical kind of thing that, you
- 1:31:14know, folks working in academia want to
- 1:31:16do.
- 1:31:17Um they want to write a paper in which
- 1:31:18they show benchmarks.
- 1:31:20Um and they want to show a cool idea. So
- 1:31:23in the case of SoftBound, they didn't
- 1:31:25make the whole language memory safe.
- 1:31:27They just showed that you can make the
- 1:31:28pointer bounds memory safe. They didn't
- 1:31:29have any solution for linking or
- 1:31:31function calls.
- 1:31:32They didn't have a solution for
- 1:31:33threading in their original work. Um but
- 1:31:36they had cool ideas about how to make
- 1:31:38pointer bounds work.
- 1:31:40Uh and the compiler as far as I can tell
- 1:31:42is basically abandonware.
- 1:31:44Um
- 1:31:44it it you wouldn't have the same joyful
- 1:31:47experience with SoftBound or with C
- 1:31:50cured that you have with PhilC where you
- 1:31:52download it, you try it, and it works.
- 1:31:55Um
- 1:31:56uh
- 1:31:58And and by the way, this is one of the
- 1:31:59reasons why with PhilC I sort of
- 1:32:02let's defer the performance problem and
- 1:32:04focus on compiling as much stuff as
- 1:32:06possible cuz I have this feeling that if
- 1:32:08you build a compiler by first focusing
- 1:32:10on performance benchmarks and then
- 1:32:11trying to make it reliable, then you'll
- 1:32:13never make it reliable and no one will
- 1:32:15use it. But if you start by making a
- 1:32:16compiler from the standpoint of let's
- 1:32:18make it reliable and then then add
- 1:32:20performance later, then then you
- 1:32:22actually have something compelling.
- 1:32:25Um
- 1:32:26Uh and then of course there's the
- 1:32:27there's Cherry and other hardware
- 1:32:29capability models which are similar
- 1:32:32uh to Phil C in that they're based on
- 1:32:33capabilities.
- 1:32:35Um
- 1:32:37but uh like let's look at Cherry in
- 1:32:38detail, right? Uh the fastest Cherry
- 1:32:42computer you can get
- 1:32:45period
- 1:32:46will run your C program slower
- 1:32:50than your
- 1:32:52x86 box will run your Phil C program
- 1:32:54today,
- 1:32:55right?
- 1:32:57Just because of how like hardware
- 1:32:59economics work. When you have a
- 1:33:02something like Phil C that runs on stock
- 1:33:04hardware x86,
- 1:33:06um you get to benefit from the fact that
- 1:33:08hardware made at high volume tends to
- 1:33:10have high performance. Whereas if you
- 1:33:13like first of all, buying of a Cherry
- 1:33:15machine is very difficult. You have to
- 1:33:17get an FPGA and flash it yourself. But
- 1:33:19if you did that, you would end up with
- 1:33:20something that will be slower than Phil
- 1:33:22C despite the fact that it's getting the
- 1:33:25hardware
- 1:33:26acceleration.
- 1:33:27Um and then on top of that, uh
- 1:33:30uh
- 1:33:31Casey, I want to hear your thoughts on
- 1:33:33this cuz you're you're really grinning.
- 1:33:35I'm confused cuz I I thought uh modern M
- 1:33:38series like threes and fours now had
- 1:33:41Cherry
- 1:33:43uh style pointer tag checking
- 1:33:46uh and that that they actually have that
- 1:33:48in Apple's kernel now.
- 1:33:50No, they have something called MIE.
- 1:33:52Okay, so not the full like so so the
- 1:33:56they only have the pointer tag check.
- 1:33:59Or what you why don't you like let's
- 1:34:00just turn this into a question. So yeah,
- 1:34:02can you elaborate on like what the
- 1:34:04differences are between those two?
- 1:34:06Cherry and MIE or Cherry is a capability
- 1:34:08model like Phil C. MIE and MTE are
- 1:34:12really cool. I should mention them.
- 1:34:15But what they what what they do is
- 1:34:18uh
- 1:34:18they do kind of an extended version of
- 1:34:21what ASAN is doing, which is just a tag
- 1:34:23memory. Yeah. What that means is if you
- 1:34:26go out of bounds of an object into
- 1:34:28another object,
- 1:34:30it might let you access it.
- 1:34:33And with MIE and MTE, the protection is
- 1:34:36just that with high probability
- 1:34:40uh 14 out of 15 times that you access
- 1:34:43out of bounds,
- 1:34:44uh you will get a trap. So what this
- 1:34:46means is
- 1:34:48um
- 1:34:50if you're a determined attacker, you'll
- 1:34:52try 15 times.
- 1:34:55Um
- 1:34:56and what it also means is that the
- 1:35:00the economics
- 1:35:02are now more in
- 1:35:05slightly less in favor of the attacker.
- 1:35:07Without MTE or MIE, an attacker can
- 1:35:10craft an exploit and reuse it a whole
- 1:35:12bunch of times, and it's not until they
- 1:35:14use it like a lot that some threat
- 1:35:17intelligence ser- center discovers that
- 1:35:20the exploit is being used, and then the
- 1:35:21bug gets fixed.
- 1:35:23With MTE and MIE, if you went wide with
- 1:35:26an exploit, then the the victim
- 1:35:30operating system provider's crash
- 1:35:32reporter would see a spike,
- 1:35:34right? And so the the hope is that this
- 1:35:38means that
- 1:35:39the attacker has to has to invent new
- 1:35:43exploits
- 1:35:44more frequently.
- 1:35:46Um
- 1:35:47I think the jury's out on whether MTE
- 1:35:50and MIE
- 1:35:52are like very valuable or just a little
- 1:35:54bit valuable, right? Because we're we're
- 1:35:56in a we're in a situation where
- 1:35:58simultaneously
- 1:36:00LLMs are proving
- 1:36:02extremely effective at finding bugs and
- 1:36:04weaponizing them. So, we're
- 1:36:06simultaneously seeing attackers that
- 1:36:08favor the economics of the attacker.
- 1:36:11Um
- 1:36:12and so, like it might end up just being
- 1:36:14a wash, right? Like MTE and MIE finds
- 1:36:16the bug causes the bugs to be fixed more
- 1:36:18quickly, LLMs cause the bugs to be found
- 1:36:21more quickly and we're back to where we
- 1:36:22started. Um
- 1:36:25Historically, these raise the bar kinds
- 1:36:27of mitigations like MTE and MIE
- 1:36:30Uh when people talk about raise the bar
- 1:36:31mitigations, they mean something that
- 1:36:34doesn't actually completely prevent the
- 1:36:36attacker from succeeding. They just it
- 1:36:37just changes the economics. Those kinds
- 1:36:39of things haven't prevented attackers
- 1:36:43from being successful.
- 1:36:45Um and so,
- 1:36:47uh I think that's why
- 1:36:50uh MTE and MIE are not going to be so
- 1:36:54successful that we can all say, "Okay,
- 1:36:56it's cool. We can just keep programming
- 1:36:58in normal C++ cuz we've fixed memory
- 1:37:00safety." Like I don't think we'll I
- 1:37:01don't think they're that powerful. I
- 1:37:03think it'll it's just it's just a
- 1:37:06it just tweaks the economics a little
- 1:37:07bit.
- 1:37:08And so, can you contrast that with with
- 1:37:10CHERI then? C H E R I for people who are
- 1:37:13wondering what we're saying. Um can you
- 1:37:15contrast like what what does CHERI
- 1:37:17provide over and I guess I'll unpack a
- 1:37:19little bit.
- 1:37:20So, um
- 1:37:21my my uh knowledge of which things go
- 1:37:24with which ARM acronyms was clearly uh
- 1:37:27a bit bad, but the ones that they have
- 1:37:29in modern M-series chips uh
- 1:37:32effectively, what it's doing is it's
- 1:37:33using the fact that because people
- 1:37:36generally aren't going to be using 64
- 1:37:39bits of address space, but pointers are
- 1:37:4164 bits.
- 1:37:43Uh there's been many different schemes
- 1:37:46where people use the upper bits of
- 1:37:48pointers, the parts that you're not
- 1:37:49going to need cuz you're not using a
- 1:37:50full 64-bit address space, to do stuff.
- 1:37:53And you know, these have been used by
- 1:37:55garbage collectors or other sorts of VM
- 1:37:57style things.
- 1:37:59And so typically what they had uh in
- 1:38:01hardware was the ability to just ignore
- 1:38:04what those top bits were. This was the
- 1:38:06the more typical thing. So, you could
- 1:38:08have pointers and you wouldn't have to
- 1:38:09mask off these extra bits at the top
- 1:38:11that you were using to store whatever
- 1:38:13you're storing in your program.
- 1:38:15And that was all fine.
- 1:38:17Uh with memory tagging extensions, MTE
- 1:38:20in this case, uh effectively what they
- 1:38:22were saying was, well,
- 1:38:24what if we just used those top bits in
- 1:38:27hardware now and allowed you to tag
- 1:38:30allocations with some specific known
- 1:38:33pattern of those top bits. Now, remember
- 1:38:35there's not that many top bits here
- 1:38:38because you still have a pretty big
- 1:38:40address space. So, you're talking about,
- 1:38:42you know, maybe eight bits or something
- 1:38:43that in total that you can use or who
- 1:38:45knows how many you're going to allocate
- 1:38:46out to this.
- 1:38:48And so the idea is when you do uh when
- 1:38:51something like a kernel is partitioning
- 1:38:53up memory and saying what it's going to
- 1:38:54be used for, it can assign a specific
- 1:38:57unique tag, in this case I believe it's
- 1:38:59what a four-bit tag.
- 1:39:01Um
- 1:39:01you can assign a unique four-bit tag to
- 1:39:03it,
- 1:39:04not zero because zero was like specially
- 1:39:06reserved and I think also not all ones,
- 1:39:09right? There was a There's some weird
- 1:39:11thing about this, but point being you
- 1:39:13have some certain amount of that uh tag
- 1:39:16space, you can tag it, and then your
- 1:39:18pointers will also be tagged with that,
- 1:39:20and every time you do a memory access,
- 1:39:22it will look to see if the pointers tag
- 1:39:24bits match what it thinks the tag bit
- 1:39:27should be for that address range. So,
- 1:39:28it's effectively tracking address ranges
- 1:39:31as a thing in hardware and doing this
- 1:39:34kind of correlation. And the reason that
- 1:39:36uh I think Phil mentioned the like 14
- 1:39:38out of 15, it's like, well,
- 1:39:40you only have a limited amount of tags
- 1:39:42to give out. If you're only talking
- 1:39:44about four bits, there's only so many
- 1:39:46tag permutations you can give out. And
- 1:39:48so, if the memory that you happen to be
- 1:39:51talking about legitimately, and the
- 1:39:54memory that the attacker has
- 1:39:55illegitimately moved the pointer to,
- 1:39:57happens to have the same tag, well, the
- 1:40:00check will still succeed. And so, you
- 1:40:02won't really get the memory safety that
- 1:40:04you wanted. As opposed to if you had
- 1:40:06some huge tag space where, you know, if
- 1:40:08it was
- 1:40:09even 16 bits would probably be enough.
- 1:40:11But if you imagine 32 bits of tag or
- 1:40:13something, then they're never going to
- 1:40:15have that accident happen.
- 1:40:17So, that's basically what that what that
- 1:40:20kind of memory tagging is about. So, can
- 1:40:23you give us a little bit more
- 1:40:24information on Cherry? Like, why is
- 1:40:25Cherry better? Cuz I've I've not
- 1:40:27actually looked into what that adds. Oh,
- 1:40:29yeah. So, Cherry um is is a full
- 1:40:33capability model. The idea is there's no
- 1:40:36tag like like with MTE. Sorry.
- 1:40:42The There There's things that you could
- 1:40:44call tags, but they're not like the MTE
- 1:40:46lock and key scheme. So, the the the the
- 1:40:49term of art for what MTE does is lock
- 1:40:52and key, because the idea is that your
- 1:40:55pointer has the key, the four bits that
- 1:40:58that that say like I think this is what
- 1:41:00memory I should be able to access. And
- 1:41:02then the lock is that each cache line
- 1:41:06has behind the scenes somewhere these
- 1:41:08four bits. And when whenever you access
- 1:41:12a cache line, the pointer's high four
- 1:41:14bits are checked against the cache
- 1:41:15line's four bits.
- 1:41:18With Cherry, what happens is that
- 1:41:21uh
- 1:41:22pointers become 128-bit.
- 1:41:25Okay. Um and the pointer encoding is
- 1:41:30something special. It's somewhere
- 1:41:31there's there's the the actual pointer
- 1:41:33you're pointing to, and then there's
- 1:41:34some bounds. Uh similarly to how PhilC
- 1:41:37pointers carry a capability.
- 1:41:39Um and
- 1:41:42uh there's additional instructions that
- 1:41:44you have to use for for for pointer
- 1:41:47operations, for capability operations.
- 1:41:49It's not like on on x86 and on arm, you
- 1:41:53can use the same instruction for adding
- 1:41:55integers as for changing the offset of a
- 1:41:57pointer because it's just an integer. On
- 1:41:59Cherry, there's separate instructions
- 1:42:01for those things. I think there's even a
- 1:42:03separate register file for the
- 1:42:05capabilities.
- 1:42:06And when you store a 128-bit capability
- 1:42:09into a memory location,
- 1:42:12that memory location has a a single bit
- 1:42:14behind the scenes that says, "Yes, the
- 1:42:16thing stored here was a legitimate
- 1:42:18capability."
- 1:42:20And then if anyone stores an integer to
- 1:42:22that memory location, the bit is
- 1:42:23cleared, it becomes an illegitimate
- 1:42:25capability. Then if you load a
- 1:42:27capability from the heap and the bit was
- 1:42:29set, then you get a capability that you
- 1:42:31can then access.
- 1:42:33So Cherry achieves
- 1:42:36uh
- 1:42:37all of what PhilC achieves minus the
- 1:42:39use-after-free protections.
- 1:42:41So if you use-after-free, you could see
- 1:42:44some other object's contents.
- 1:42:47Um
- 1:42:47and then it it's uh there's an open
- 1:42:50question of whether that's enough to
- 1:42:52prevent weird execution or not because
- 1:42:56if you use-after-free,
- 1:42:58then you know, you still have a
- 1:42:59capability that's restricting you to a
- 1:43:01small range of of bytes in memory.
- 1:43:04Um so in order for you to achieve weird
- 1:43:06execution, the thing that lands in that
- 1:43:09small range has to be useful to you
- 1:43:11somehow.
- 1:43:12Um
- 1:43:12so open question of whether Cherry is
- 1:43:15practically weaker than PhilC as opposed
- 1:43:18to just theoretically weaker. Is I want
- 1:43:22to say that like exploits have been
- 1:43:24shown in the past that would fit that
- 1:43:26category. Like I feel like sock puppet
- 1:43:29may have been
- 1:43:31a
- 1:43:33just use after free. Like there was no
- 1:43:35like it literally was just because an
- 1:43:37object previously had, you know,
- 1:43:40a particular capability and was slotted
- 1:43:42into that slot, it it would not have
- 1:43:44been protected unless it had use after
- 1:43:46free. I could be wrong about that, but I
- 1:43:48want to say that there have been some
- 1:43:50exploits that
- 1:43:51legitimately did just use use after
- 1:43:53free, but I could be wrong. I remember
- 1:43:55seeing something like this.
- 1:43:57I think there have been, but um They
- 1:43:59might be They're very rare probably, but
- 1:44:01yeah.
- 1:44:01>> Yeah, like 99.9,
- 1:44:03maybe even five nines worth of use after
- 1:44:06free exploits
- 1:44:08are that um
- 1:44:11the object you thought you were pointing
- 1:44:12to has a pointer at offset eight. And
- 1:44:15then the object you put in that place
- 1:44:17after the use after free has an integer
- 1:44:19at offset eight. And now from one part
- 1:44:22of the pro program you get to read and
- 1:44:23write integers from the other you're
- 1:44:25using it as a pointer, and that gives
- 1:44:27the attacker
- 1:44:28the ability to access anything in memory
- 1:44:30because they just control the pointer
- 1:44:32value.
- 1:44:33And that in Cherry would not be possible
- 1:44:35because the moment that you
- 1:44:37Got you.
- 1:44:37>> wrote the integer into that location, it
- 1:44:39clears the capability bit almost exactly
- 1:44:41like what happens with Phil C. Um So it
- 1:44:44might be fine because the use after free
- 1:44:46the the the pathology of actual use
- 1:44:49after free bugs never only uses the use
- 1:44:52after free part
- 1:44:54in practice or something like this.
- 1:44:55Yeah, exactly.
- 1:44:56Um but this is like a this is an an area
- 1:45:00that's up for debate. Uh so the Cherry
- 1:45:02folks um
- 1:45:04I think one of the things that they did
- 1:45:06that might have just been like a mistake
- 1:45:08is rather than just going all in on
- 1:45:11like, "Okay, this is what we provide and
- 1:45:13this is as good as it gets and
- 1:45:15there aren't enough of these weird kind
- 1:45:17of use after free bugs that don't then
- 1:45:20uh use pointer confusion for us to worry
- 1:45:22about it and so end of story."
- 1:45:24They started engineering this whole
- 1:45:26thing where they have a whole system
- 1:45:28hardware assisted garbage collector that
- 1:45:30frees that clears the capabilities. And
- 1:45:34so then the sales pitch to an operating
- 1:45:36system vendor is like, "Hey, guess what?
- 1:45:38You get to put a garbage collector in
- 1:45:40your kernel." It's like
- 1:45:42I mean, come on, right? Like No nobody
- 1:45:45nobody wants that.
- 1:45:47Um
- 1:45:48uh
- 1:45:49So, um and I think the the the current
- 1:45:54uh like OS that they're building around
- 1:45:56Cherry is not a conventional OS. It's an
- 1:45:58OS that is all in on just the Cherry
- 1:46:01capabilities with a whole system garbage
- 1:46:04collector and no virtual memory. So, you
- 1:46:06lose the virtual memory and you're just
- 1:46:08using the capabilities, which is really
- 1:46:10really weird. So, um
- 1:46:13I think where Phil C has a benefit is
- 1:46:15you don't have to change how you think
- 1:46:16about the kernel or the boundary between
- 1:46:18the kernel and userland. Um it just runs
- 1:46:21on whatever kernel you have. Um doesn't
- 1:46:24And And you don't have to get rid of
- 1:46:25virtual memory. You still have virtual
- 1:46:27memory as an additional layer of
- 1:46:28protection.
- 1:46:29Um
- 1:46:31And the garbage collector is just per
- 1:46:33process. So, each process gets decide
- 1:46:35how it GC's itself.
- 1:46:37Um
- 1:46:39So,
- 1:46:40And I think also there's technically
- 1:46:42there isn't a
- 1:46:45There's an announcement of an
- 1:46:47announcement on the x86 side for
- 1:46:49something like the MIE part, not the
- 1:46:52Cherry part. They called it CheckTAG, c
- 1:46:55h k t a g.
- 1:46:58Am I correct Phil in in that no one has
- 1:47:00actually put out any materials about
- 1:47:03when what exactly this might be or when
- 1:47:06it's coming or have we actually received
- 1:47:08I I I saw things where they were like,
- 1:47:10"We're going to maybe do this." But then
- 1:47:13I haven't seen anything about what it
- 1:47:14will actually be. Although it sounded
- 1:47:16like it was going to be like an MIE
- 1:47:17thing.
- 1:47:18Uh yeah, there's no details uh that I've
- 1:47:20seen officially
- 1:47:23um
- 1:47:24Yeah, the announcement was really weird
- 1:47:25in that it was like
- 1:47:27a lot of bug work. Um
- 1:47:30Uh
- 1:47:31but from uh from all of the the research
- 1:47:34that I've done on it and asking people
- 1:47:36about it, it sounds like it is it is uh
- 1:47:39it is basically an MTE. Uh so it has the
- 1:47:43same property as MTE that uh a a
- 1:47:46determined [clears throat] attacker who
- 1:47:48tries enough times will get through. Oh,
- 1:47:50and I should point out another problem
- 1:47:51with MTE, which is that if the attacker
- 1:47:54has a way of systematically guessing
- 1:47:56what tag you have, then they just win
- 1:47:58every time.
- 1:47:59Um so one of the big concerns with MTE
- 1:48:02is if you combine a classical exploit
- 1:48:04with Spectre
- 1:48:06to snoop on what bits are in memory,
- 1:48:09then the attacker can work out exactly
- 1:48:11what tags are in what pointers, and then
- 1:48:14when the attacker does their
- 1:48:16out-of-bounds write or whatever type
- 1:48:17confusion and puts whatever pointer they
- 1:48:19want in there, they will know what tag
- 1:48:22to use, and then they beat MTE every
- 1:48:23single time.
- 1:48:25Um so I think I think
- 1:48:27uh
- 1:48:29Yeah, there's a as a C++ programmer, I
- 1:48:31wish something like MTE was the just the
- 1:48:34story because then I could just go back
- 1:48:37to programming in C++ and not worry
- 1:48:38about this stuff anymore.
- 1:48:40But I I actually think that uh MTE
- 1:48:44it is a weak enough story that it'll
- 1:48:46keep the PhilC thing in business.
- 1:48:49>> [laughter]
- 1:48:51>> I I like that you you want to you want
- 1:48:53to be done with PhilC. Like you wanted
- 1:48:55to make sure that it's not possible. It
- 1:48:57was possible. Now you need to optimize
- 1:48:59it. You need to compile fix. Like that's
- 1:49:01it's such so much work, man. And like
- 1:49:03you need to do it because like the whole
- 1:49:05damn thing is possible. Like that's the
- 1:49:07that's the problem.
- 1:49:08And on the MTE side of things
- 1:49:13for me as a sort of outsider, I I like
- 1:49:15it's a bit of a weird security
- 1:49:18system that like if you're a determinant
- 1:49:21determinant attacker, you still get
- 1:49:24through it. It's like what what kind of
- 1:49:26security guarantees you get? If you
- 1:49:29really want to do it, you're going to do
- 1:49:31it.
- 1:49:32It is a little bit weird because
- 1:49:35it's
- 1:49:38it's kind of only bulletproofing the
- 1:49:40sorts of code that only really
- 1:49:43determined hackers are targeting anyway.
- 1:49:46Like your people who are generally doing
- 1:49:48exploits or like sending fishing emails
- 1:49:50or just like calling people on the phone
- 1:49:52and getting them to get you know like
- 1:49:54like the ways that people practically
- 1:49:55get into systems a lot of times don't
- 1:49:57require
- 1:49:59>> don't require Spectre and Meltdown,
- 1:50:01right? Like those are not the common
- 1:50:02exploits that people actually do. So
- 1:50:04when you're talking about this level of
- 1:50:06kind of like bulletproofing, you're you
- 1:50:09are often talking I assume about only
- 1:50:11really sophisticated actors anyway. So
- 1:50:13yeah, I mean it it doesn't bode well for
- 1:50:15something that's only about memory
- 1:50:17tagging, but
- 1:50:18I'm assuming their idea is just like
- 1:50:20well, the more protection the better and
- 1:50:22this was something we could do
- 1:50:24relatively cheaply as as compared you
- 1:50:27know, in hardware.
- 1:50:28Adding a few extra bits per cache line
- 1:50:30of this tagging is not the end of the
- 1:50:32world.
- 1:50:33Whereas doing something more substantial
- 1:50:36is. So I guess they were just hoping
- 1:50:39relatively low implementation cost
- 1:50:43possibly stopping some exploits. I don't
- 1:50:45know.
- 1:50:46I just want to give a shout out to my
- 1:50:48friends at Apple who worked on this.
- 1:50:50Like the
- 1:50:51>> [laughter]
- 1:50:52>> like
- 1:50:53Yeah, I mean
- 1:50:55the reason why it's a good idea is if
- 1:50:58you're if you're making if you're
- 1:51:00selling iPhones or whatever something
- 1:51:02um there's going to be a it's already
- 1:51:05the case that it's very expensive to to
- 1:51:07build an exploit against an iPhone. It's
- 1:51:09like
- 1:51:11million bucks or something to to to
- 1:51:13build one of these exploits. So,
- 1:51:17the script kiddie down the street isn't
- 1:51:18going to be doing it. And if he was
- 1:51:20doing it, you'd know because he'd have
- 1:51:22like a garage full of Lamborghinis. So,
- 1:51:25um
- 1:51:26So, the the point here is
- 1:51:30to
- 1:51:31to keep making it more expensive for the
- 1:51:36folks building these exploits. The more
- 1:51:38expensive you make it, the less of them
- 1:51:40you have. Right? Like because it's
- 1:51:43already a million bucks to build one of
- 1:51:45these exploits, if I know that if I'm
- 1:51:47using an iPhone, cuz I'm not that
- 1:51:49important of a human being, it's not
- 1:51:51going to be worth it for somebody to try
- 1:51:53to attack me. Now, if it is the case
- 1:51:57that you build a million-dollar exploit
- 1:51:59and then you get to scan it, right? You
- 1:52:02get to reuse it on many many many
- 1:52:05people, then the cost amortizes.
- 1:52:08So, sure it cost me a million dollars to
- 1:52:09make the exploit, but once I make it, I
- 1:52:11can just keep reusing it. So, how do you
- 1:52:13get to the point where
- 1:52:15uh
- 1:52:16like if if I was if I put my my like I
- 1:52:19used to work at Apple hat on, the
- 1:52:21thinking is
- 1:52:22like how do you get to the point where
- 1:52:25it costs a million dollars per use?
- 1:52:30Uh okay.
- 1:52:31>> Right? And the the key thing is that if
- 1:52:35uh if if you combine that with the fact
- 1:52:38that Apple Apple tends to make software
- 1:52:40that's like reasonably stable, then
- 1:52:42well, this is the part where it's the
- 1:52:43gotcha, right? The hope is like imagine
- 1:52:46if your code is actually stable and
- 1:52:48you've got your crash reporter, someone
- 1:52:51uh deploys an exploit against somebody,
- 1:52:53they're going to have to try 15 times.
- 1:52:56Um you're going to get 15 crashes all in
- 1:52:59the same place within a short period of
- 1:53:02time. That's a pretty good signal that
- 1:53:04you've got a bug there.
- 1:53:06Um and fixing bugs, if you know where
- 1:53:09the bug is isn't that hard. Like the
- 1:53:12economics for the defender are only bad
- 1:53:14because there's bugs you just don't know
- 1:53:16about so you don't know to go and fix
- 1:53:18them.
- 1:53:19Um, so the the thing that MTE might
- 1:53:24achieve for someone like Apple is that
- 1:53:27it's not a million dollars and then you
- 1:53:29use it a bunch of times but it's a
- 1:53:31million dollars per use.
- 1:53:33Uh, now there's lots of reasons to
- 1:53:35believe that that's not what it
- 1:53:36achieves. One, the thing that I talked
- 1:53:39about with Spectre or other ways of
- 1:53:41systematically guessing the tag. Two, um
- 1:53:45I bet you that the typical thing that's
- 1:53:48being attacked on my Apple device
- 1:53:50crashes enough times as background noise
- 1:53:52already
- 1:53:54>> [laughter]
- 1:53:54>> mismatches aren't going to show up as a
- 1:53:56significant outlier.
- 1:54:01Um [clears throat]
- 1:54:02Uh, and then uh, the there's other
- 1:54:05there's other problems with MTE when you
- 1:54:07really drill into the into the into the
- 1:54:09details. Um
- 1:54:12So I think it's it it
- 1:54:14it's it's really an open question
- 1:54:18whether this will be a a game changer or
- 1:54:21not and it's too soon to tell cuz it's
- 1:54:23only been shipping for a short amount of
- 1:54:24time.
- 1:54:27Okay. Okay. And I mean presumably though
- 1:54:30uh
- 1:54:31is the background crashing thing really
- 1:54:33part of the concern though because uh
- 1:54:35presumably an MTE crash has its own
- 1:54:39particular exception code so you know
- 1:54:41when someone
- 1:54:43had an had a tag mismatch
- 1:54:46versus not. Okay, but your your
- 1:54:49background of crashes are going to have
- 1:54:51be hitting MTE
- 1:54:51>> Those two. Okay. too, right? So cuz
- 1:54:54Well, that that may be yeah. Yeah, like
- 1:54:56>> Okay, yeah. Just from people just
- 1:54:58sucking at what at the at the that at
- 1:55:00the kernel usage or whatever, yeah. Or
- 1:55:02sucking at writing user level whatever,
- 1:55:05right? And the thing is that MTE
- 1:55:07increases your crash rate because
- 1:55:09there's some amount of memory safety
- 1:55:11bugs that happen,
- 1:55:14but the process keeps running.
- 1:55:16Right? Cuz you happen to hit on a page
- 1:55:18that was mapped. Now those crashes
- 1:55:21become MTE crashes.
- 1:55:23So you actually have the the background
- 1:55:26noise level, I would imagine,
- 1:55:29goes up.
- 1:55:31So if I was an attacker, I would
- 1:55:34probably be thinking about like how do I
- 1:55:36hide in that noise?
- 1:55:38Yep.
- 1:55:39That makes sense.
- 1:55:41Okay.
- 1:55:43Then I think we're nearing the end of
- 1:55:44the interview. I have last last like
- 1:55:47open question.
- 1:55:50Right now FilC is like 0.6
- 1:55:5367 version. 67 is a meme now for kids,
- 1:55:56so but it like it it happened, you know,
- 1:55:58like
- 1:55:59but it's 0.67.
- 1:56:02What do you see long-term? And we talked
- 1:56:05a bit like what what would be the the
- 1:56:07next step? Like was it optimization? Is
- 1:56:08it more more programs compiling? What do
- 1:56:11you see
- 1:56:12it happening in the future? Like do you
- 1:56:14see making it into 1.0 proper product
- 1:56:18and like, you know, starting a business
- 1:56:20around it in in couple of years? Like
- 1:56:21what's
- 1:56:22what's the long-term plan? How do you
- 1:56:24see the future might unfold for for
- 1:56:27FilC?
- 1:56:29I think that
- 1:56:30what I'm hoping for
- 1:56:32is the number of users keeps going up
- 1:56:35and the number of contributors keeps
- 1:56:37going up to the point where I'm just no
- 1:56:39longer the bottleneck.
- 1:56:41And if if that if that were to happen,
- 1:56:45that it's like it's own independent
- 1:56:47thing where like
- 1:56:49like I get to maybe still be part of it,
- 1:56:51but there's other people who are working
- 1:56:53on making it better and other people
- 1:56:55using it, then that would be just
- 1:56:57absolutely the coolest thing ever.
- 1:57:00How can people like let's plug that a
- 1:57:02little bit? For people who are
- 1:57:04interested in compilers and have some
- 1:57:05experience with compilers, who might
- 1:57:07want to help out in something like this,
- 1:57:09where is it at? I assume there's the
- 1:57:11Phil C GitHub somewhere or something
- 1:57:13that you can go to to look at or That's
- 1:57:15exactly right. You can go on the GitHub
- 1:57:17and there's a bunch of issues that I
- 1:57:19filed that describe
- 1:57:22in some cases in great detail
- 1:57:24optimizations that I want to do.
- 1:57:26Um so if you're a if if you like LLVM IR
- 1:57:30hacking
- 1:57:31and you know how to do that,
- 1:57:33um then this is like a really fun
- 1:57:35playground.
- 1:57:37Um probably the easiest bug up for the
- 1:57:40taking is one about um how to make
- 1:57:43direct function calls not involve the
- 1:57:46getter indirection and not involve the
- 1:57:48passing through the heap stuff, but just
- 1:57:49using native ABI.
- 1:57:51Like that's
- 1:57:52probably a a large speed up.
- 1:57:55Um
- 1:57:55>> I bet.
- 1:57:56>> Yeah. And and like uh I have multiple
- 1:57:58bugs describing multiple different ways
- 1:58:00of getting there. So if someone likes
- 1:58:03thinking about this kind of stuff,
- 1:58:05um come on by, join the party. Um
- 1:58:08I'm I'm happy to accept contributions
- 1:58:10from people who are unsure or new to the
- 1:58:13space. Uh it's fun to just talk about
- 1:58:15compilers and think through this stuff.
- 1:58:17Um
- 1:58:18so uh yeah, just come and join and have
- 1:58:21some fun hacking compilers with me.
- 1:58:23So Phil C on GitHub, there's also a
- 1:58:26website on Phil C. When uh there's a lot
- 1:58:29of materials on how it does work, we can
- 1:58:31download the the distribution of the
- 1:58:33compiler, right? And then you have also
- 1:58:35social media, where can people follow
- 1:58:36your work?
- 1:58:38Uh I it's all on on x.com is the is the
- 1:58:41social media. I've sort of focused it
- 1:58:43there so that you get to see it all in
- 1:58:45one place. And then of course there's
- 1:58:47the Discord. So you can join the Discord
- 1:58:49and and and join the conversation in
- 1:58:51there. And there's a link to the Discord
- 1:58:52from the website.
- 1:58:54All right. Perfect. Fe thank you so much
- 1:58:58for joining me.
- 1:58:59>> Thanks Casey for showing also showing up
- 1:59:02>> pleasure. I I I learned a lot. Like I I
- 1:59:04love Phil C and I I'm really interested
- 1:59:06in such an interesting project to me and
- 1:59:08uh
- 1:59:09I hope to see it much as as Phil I I
- 1:59:11hope to see it continue in like a uh
- 1:59:14uh as people start making optimizations
- 1:59:16to it and it becomes easier and easier
- 1:59:17to just kind of slipstream in cuz I feel
- 1:59:19like there's a lot of low-hanging fruit.
- 1:59:21Tools like things like sudo and stuff
- 1:59:23like that are great examples of like
- 1:59:26these
- 1:59:27are prime for getting recompiled in a
- 1:59:29memory-safe language. They're not
- 1:59:30performance-critical. They're security,
- 1:59:33you know, nightmares a lot of the time.
- 1:59:35And so like I would love to see it catch
- 1:59:37on as as just a standard thing we do to
- 1:59:38a bunch of utilities, right? So.
- 1:59:43Perfect.
About this transcript
This page contains the full transcript of How Fil-C Works by Wookash Podcast, generated from the public captions YouTube serves with the video. The transcript has 19,927 words across 3,276 segments, with the original timestamps preserved so you can click any line to jump to that moment in the embedded player.
What you can do with it
Use the transcript to take notes, quote the speaker, build a study guide, generate a summary with ChatGPT or Claude via the YouTube Summary tool, or export it as a timed subtitle file with YouTube to SRT. You can also re-open it in the transcriber to translate the transcript into 100+ languages.
Free YouTube transcript tool
YouTube2Text is a free YouTube transcript generator — no signup, no daily limit. Paste any YouTube link and get the full transcript instantly, with timestamps, click-to-jump, translation to 100+ languages, AI prompts for ChatGPT, Claude, and Gemini, and exports to TXT, SRT, VTT, or Markdown.