< Return to Video

34C3 - May contain DTraces of FreeBSD

  • 0:00 - 0:14
    music
  • 0:14 - 0:19
    applause
  • 0:19 - 0:24
    Raichoo: Yeah sorry about that - beamers
    or projectors, I don't like them. They
  • 0:24 - 0:27
    don't like me either. So this is a little
    heads up - this is going to be the only
  • 0:27 - 0:32
    slide I'm going to show you today so,
    "slide", because I think doing stuff like
  • 0:32 - 0:36
    that in a terminal might be a little bit
    more interesting for you. But sadly
  • 0:36 - 0:40
    something is getting cut off so I we have
    to improvise a little bit. But anyway, so
  • 0:40 - 0:44
    today I will be able to talk about two of
    my favorite things right now which are
  • 0:44 - 0:48
    FreeBSD and DTrace. But this talk has been
    capped down to 30 minutes so we'll be
  • 0:48 - 0:53
    focusing a little more on the DTrace part.
    So there will be a little bit less BSD
  • 0:53 - 0:58
    than I anticipated. And also adjusted
    everything a little bit to fit better into
  • 0:58 - 1:03
    the resilience track so hopefully you'll
    enjoy that. So before we begin, who here
  • 1:03 - 1:09
    is actually using DTrace? Okay more than
    I expected but still not as many as I
  • 1:09 - 1:13
    would like to see. So hopefully after this
    talk you will think, "oh, this is a really
  • 1:13 - 1:17
    awesome tool, I gotta learn it." Because I
    totally love it - it changed the way I do
  • 1:17 - 1:22
    a lot of stuff. So for those of you who do
    not know what DTrace is, first, let me
  • 1:22 - 1:27
    fill you in on this stuff. So it's open
    source, it originated on Solaris, and been
  • 1:27 - 1:32
    developed currently on illumos which is a
    fork from OpenSolaris. It has been ported
  • 1:32 - 1:38
    to FreeBSD, NetBSD, OS X, there's also a
    port for Linux called next called DTrace
  • 1:38 - 1:44
    for Linux. I think it's done by a person
    called Paul Fox. It's been ported to QNX
  • 1:44 - 1:50
    and the OpenBSD folks are currently doing
    some work to get the technology like
  • 1:50 - 1:54
    DTrace on their system. And I think
    there's a port for Windows? I don't know
  • 1:54 - 1:58
    if this is actually true, but it is it's
    kind of cool because then that means it's
  • 1:58 - 2:05
    basically everywhere. So, most of you
    would probably know static tools like
  • 2:05 - 2:09
    strace. We have a very similar tool on
    FreeBSD that is called truss, and what
  • 2:09 - 2:14
    truss and strace are doing is - you can
    attach them to a process and look at the
  • 2:14 - 2:19
    system calls that this process is
    emitting. So in case something is going
  • 2:19 - 2:23
    wrong you can well look inside of the
    program, which can be kind of useful when
  • 2:23 - 2:29
    you're trying to find a problem. It's
    kind of handy but it's also pretty
  • 2:29 - 2:33
    limited. Because first of all it really
    really slows down the process that you're
  • 2:33 - 2:37
    currently looking at. So if you want to
    debug a performance issue, you're pretty
  • 2:37 - 2:42
    much out of luck there. And also it's kind
    of like, narrow down - you can just look
  • 2:42 - 2:48
    at one process. Which is also like bad
    thing because the system that we currently
  • 2:48 - 2:53
    have - all these systems are very
    complex: we have a lot of layers. You have
  • 2:53 - 2:56
    virtual file systems, you have virtual
    memory, you have network, you have
  • 2:56 - 3:00
    databases, processes communicating with
    each other. And in case you are using a
  • 3:00 - 3:05
    high-level programming language, you might
    also have a runtime system. So it's a
  • 3:05 - 3:10
    little operating system on top of your
    operating system. So when something goes
  • 3:10 - 3:15
    wrong in a system that has such large
    complexity, something happens that we call
  • 3:15 - 3:20
    the blame game. And the blame game - it's
    never your fault, it's always someone
  • 3:20 - 3:26
    else's. So what we want to be able to do
    is we want to look at the system as a
  • 3:26 - 3:30
    whole, so we can correlate all the data
    and come up with some meaningful answers
  • 3:30 - 3:35
    when something is really going wrong in
    there. And also, we don't want to
  • 3:35 - 3:39
    switch out all the processes for
    debug processes to make that happen,
  • 3:39 - 3:45
    because as these things are all -- every
    problem happens in production. It never
  • 3:45 - 3:48
    happens on the development box. So like,
    switching out all the processes - that's
  • 3:48 - 3:55
    totally out of the picture. So to do that
    in an arbitrary way, to like, instrument
  • 3:55 - 4:00
    the system in an arbitrary way, we sort of
    need like a programming language. So, we
  • 4:00 - 4:04
    need to describe - when that happens,
    please submit data so I can see what's
  • 4:04 - 4:09
    going on. So this kind of implies a
    programming language. And DTrace comes
  • 4:09 - 4:14
    with such a programming language - it's a
    little bit reminiscent of awk cross with
  • 4:14 - 4:19
    C? It's pretty simple to learn - you can
    pick it up 20 up to pick it up in 20
  • 4:19 - 4:25
    minutes and you can start churning out
    your first DTrace scripts. So like awk, if
  • 4:25 - 4:31
    you know awk, awk can be used to analyze
    large bodies of text. Dtrace is pretty
  • 4:31 - 4:35
    much the same, but for system behavior -
    so a little bit mind boggling, but
  • 4:35 - 4:40
    probably I can show you what I mean by
    that. And also, as a bonus we don't want
  • 4:40 - 4:44
    to slow down the system, so we want to be
    able to do things like performance
  • 4:44 - 4:52
    debugging, performance tests like that. So
    I've prepared this little demo here, and.
  • 4:52 - 4:59
    So since we had some issues here probably
    this is not -- I have to play around a
  • 4:59 - 5:04
    little bit. So what I'm going to do is
    I'm going to look at a very very naive way
  • 5:04 - 5:18
    to -- excuse me for a second -- very naive
    way to -- give me a second -- so very
  • 5:18 - 5:22
    naive way to authenticate a user. And
    there's a lot of stuff wrong with this
  • 5:22 - 5:26
    code, but like what we're going to do is
    we're going to take a user string as
  • 5:26 - 5:33
    input, and then we're going to just
    compare it to another, to a secret. So I
  • 5:33 - 5:36
    know, the the secret in here is like in
    plain text I know this is a problem, but
  • 5:36 - 5:42
    this is a little bit artificial. But I
    just want to get my point across. So from
  • 5:42 - 5:47
    an algorithmic perspective, this check
    function is correct: so we take a string
  • 5:47 - 5:52
    we take another string and we compare
    them. So everything's fine and easy. So if
  • 5:52 - 5:59
    you look at the way string compare works
    and what it does, it's essentially
  • 5:59 - 6:04
    taking these two strings and it's
    comparing every character bit by bit. So
  • 6:04 - 6:11
    when it finds the first pair of characters
    that do not match up, it's going to stop.
  • 6:11 - 6:18
    So we can we can conclude something about
    from that - so if it takes very short if
  • 6:18 - 6:23
    if this function this check function takes
    a very short amount of time, then, what
  • 6:23 - 6:29
    will happen is it will terminate earlier.
    And if our password guess is better, it
  • 6:29 - 6:34
    will take well, it will take longer. And
    if we can measure that we can basically
  • 6:34 - 6:41
    extract information from that running
    algorithm. So I wrote a little driver
  • 6:41 - 6:47
    program in Haskell that basically just
    iterates over an alphabet and just feeds
  • 6:47 - 6:53
    this one letter into that program,
    And I'm going to use DTrace to get some
  • 6:53 - 6:59
    timing information. So let me start the
    driver. So this is now just running in the
  • 6:59 - 7:05
    background. And you cannot see what I'm
    typing there, but don't worry - these
  • 7:05 - 7:12
    scripts will all be; I will push them on
    my github. So DTrace now produces this
  • 7:12 - 7:17
    nice little distribution. So if you if you
    were if you were able to see the entire
  • 7:17 - 7:23
    alphabet, you would see that everything
    except "D" behaves differently. So if you
  • 7:23 - 7:29
    squint a little, what you see there is
    DTrace the D letter takes a couple of
  • 7:29 - 7:33
    nanoseconds longer. This is the precision
    that I'm measuring here - ten to minus
  • 7:33 - 7:39
    nine seconds. Like really precise. And D
    takes longer than everything else, so it's
  • 7:39 - 7:44
    a little bit cut off there, but trust me.
    I know it sound like Donald Trump I'm
  • 7:44 - 7:53
    saying that. So yeah, and from that let's
    just enter a letter. And now the password
  • 7:53 - 7:57
    and now the script clears everything and
    it's going to guess the next letter. So
  • 7:57 - 8:02
    sadly this is cut off, because you would
    see that this distribution radically
  • 8:02 - 8:09
    changed. It looks completely different,
    and so we can play that game a little bit.
  • 8:09 - 8:13
    So let's just roll with that.
    And like every three seconds the script is
  • 8:13 - 8:19
    going to recompute looking at the new
    distribution. And you can probably see
  • 8:19 - 8:27
    where this is going. So here you can see,
    okay, and now it just - it just takes
  • 8:27 - 8:35
    about like three seconds for me to guess
    the next letter. So, and this is not a
  • 8:35 - 8:40
    problem that is only of
    something that happens when you do string
  • 8:40 - 8:44
    compares. This can happen with
    basically everything - so it's especially
  • 8:44 - 8:48
    in things like cryptographic stuff where
    you don't want to have some information
  • 8:48 - 8:57
    leaked out. So this is what we call a
    timing side channel attack. So I could
  • 8:57 - 9:03
    essentially use DTrace to analyze
    the real binary. So I didn't change the
  • 9:03 - 9:07
    binary - I didn't have some some debug
    code there. This is like the actual binary
  • 9:07 - 9:12
    that I would put into production. So
    what's important about out that, is to
  • 9:12 - 9:16
    take the actual binary, is some of these
    these timing side channels might be
  • 9:16 - 9:22
    introduced by a compiler optimization. And
    when you insert debug code into that code,
  • 9:22 - 9:27
    then it might actually go away. So, you
    want to look at the real code that you're
  • 9:27 - 9:34
    putting into production. Let me show you
    the script that I came up with to write
  • 9:34 - 9:41
    that. So there are three interesting
    things in this script. So and and don't
  • 9:41 - 9:44
    worry - this is the more
    complicated example, I just want to like
  • 9:44 - 9:49
    inspire your ideas. Because the things
    that you can do with DTrace that's pretty
  • 9:49 - 9:55
    much - the sky's the limit. You can
    come up with the weirdest ideas, and so
  • 9:55 - 9:59
    this is more complicated example. I'm
    going to show you simpler ones. So to
  • 9:59 - 10:04
    demonstrate how we got here. So there are
    three interesting things in this code. The
  • 10:04 - 10:10
    first one is something that we call a
    probe. So a probe is a point of
  • 10:10 - 10:15
    instrumentation in the system. So whenever
    a certain event happens in the system this
  • 10:15 - 10:21
    probe is going to fire. And in this case,
    the begin probe like marks the state
  • 10:21 - 10:27
    the moment when the script starts. So the
    second interesting thing is this clause.
  • 10:27 - 10:32
    So this clause is basically what this
    probe is going to execute - what's going
  • 10:32 - 10:38
    to be executed once that probe fires. So
    it's a little block of code.
  • 10:38 - 10:42
    And this probe is a little bit more
    interesting, because it tells us
  • 10:42 - 10:48
    something about the structure of how such
    a probe looks like. Because every
  • 10:48 - 10:54
    probe is uniquely identified by a four
    tuple. So it's like four components that
  • 10:54 - 10:59
    uniquely identify a probe. And the first
    one is called the first part of this
  • 10:59 - 11:03
    tuple is called the provider, and I'm
    going to talk about providers in a couple
  • 11:03 - 11:07
    of seconds and what they are. The second
    one is called the module. Third one is
  • 11:07 - 11:13
    called the function. And the last one is
    called the name. So these four pieces of
  • 11:13 - 11:21
    data, like, they identify a probe
    uniquely. So the third thing that is
  • 11:21 - 11:25
    interesting here is, sadly something that
    I don't have time to talk about today,
  • 11:25 - 11:31
    this is called an aggregation. And this
    single line that you see here is
  • 11:31 - 11:36
    essentially responsible for accumulating
    all this data to print out this
  • 11:36 - 11:40
    distribution stuff - to generate this
    distribution. So this is built
  • 11:40 - 11:45
    into DTrace. You don't have to do that
    yourself. As it, when you look at this
  • 11:45 - 11:50
    script, it's like 42 lines of code.
    And I came up with the first prototype
  • 11:50 - 11:55
    after five minutes. So it's not a lot
    of stuff to do to get something out of
  • 11:55 - 12:00
    that. So it's very useful to have things -
    if you use DTrace you
  • 12:00 - 12:05
    will use this a lot for performance
    debugging so it's kind of neat that we
  • 12:05 - 12:11
    have that. So yeah, let's talk a little
    bit about providers, and this will
  • 12:11 - 12:18
    probably also will be cut off. So I'm
    going to cheat a little bit here - I'm
  • 12:18 - 12:28
    just going to double that. So let's talk
    about providers -- oh that's handy --
  • 12:28 - 12:32
    so I got 27 providers here and the number
    of providers vary from operating system to
  • 12:32 - 12:38
    operating system. But these are the
    ones that I can see right now. There are
  • 12:38 - 12:44
    other providers that can be come into
    existence when you demand them. So I have
  • 12:44 - 12:49
    these 27 providers, and we're going to
    look at the syscall provider and the FBT
  • 12:49 - 12:55
    provider first. So, every provider knows
    how to instrument a specific part of the
  • 12:55 - 13:01
    system. So the syscall provider knows how
    to instrument the syscall table. That's not
  • 13:01 - 13:09
    very surprising. So if you can look at the
    syscall provider and here you can see
  • 13:09 - 13:17
    essentially every system call entry and
    return that FreeBSD offers. So
  • 13:17 - 13:20
    here you can see this four tuple, like,
    the provider syscall, FreeBSD is the
  • 13:20 - 13:28
    module, and so on. So these are all the
    system calls that I have in my system. And
  • 13:28 - 13:33
    the other provider that I want to look at
    is the so called FBT provider, and that is
  • 13:33 - 13:39
    pretty astonishing. The FBT provider, FBT
    stands for "function boundary tracer" and
  • 13:39 - 13:45
    what it allows us to do, it allows us to
    trace every single function in the kernel.
  • 13:45 - 13:51
    So I can look at the entire kernel at
    functions, as they are being called. So to
  • 13:51 - 13:58
    illustrate that I wrote a little, very
    simple DTrace script and this is probably,
  • 13:58 - 14:01
    look at the upper half please, so this is
    probably one of the first DTrace scripts
  • 14:01 - 14:06
    that you will come up with, it's a
    fairly simple example, so let's break it
  • 14:06 - 14:10
    down. So I'm going to instrument the mmap
    system call. For those of you who do not
  • 14:10 - 14:14
    know what the mmap system call is, what
    you can do with it is you can so you can
  • 14:14 - 14:21
    take a file and map that into the address
    space of your process, so very dumbed down
  • 14:21 - 14:27
    version. So whenever we enter the mmap
    system call we are going to set the
  • 14:27 - 14:33
    variable "follow" to one, and what this
    "self at" means: this is essentially a
  • 14:33 - 14:38
    thread local variable and we're going to
    associate that variable with the thread
  • 14:38 - 14:45
    that we're currently inspecting. Then I'm
    going to do something pretty, that sounds
  • 14:45 - 14:49
    scary but I'm going to instrument the
    entire kernel. Every function entry and
  • 14:49 - 14:53
    every function return, I'm going to
    instrument that and say "please emit data
  • 14:53 - 14:57
    when you do that". And this is what we
    call a predicate, so this is where the
  • 14:57 - 15:02
    awkiness of the DTrace programming
    language comes in. So this is a predicate
  • 15:02 - 15:07
    and whenever that evaluates to true
    then the probe is going to fire, so in
  • 15:07 - 15:11
    this case when we are in the thread that
    we're currently tracing we're going to
  • 15:11 - 15:16
    emit data. And this is just an empty
    clause, we just want to know "hey we got
  • 15:16 - 15:23
    here". So when we exit the mmap
    system call and the predicate is set we're
  • 15:23 - 15:28
    going to set the variable "follow" to
    zero, because every uninitialized variable
  • 15:28 - 15:34
    in DTrace is set to zero, so this pretty
    much amounts to deallocating that variable
  • 15:34 - 15:41
    and then we're going to exit cleanly. So
    let me run that. So it takes a couple of
  • 15:41 - 15:48
    seconds and boom. So you saw a little
    pause here, that was when the DTrace guard
  • 15:48 - 15:55
    reverted the driver, the kernel. So now
    you can see every function call that
  • 15:55 - 15:59
    happens inside the mmap system call. And
    this is a little bit hard on the eyes, so
  • 15:59 - 16:08
    let me pass this flag here and now you can
    have nice to read indentation. So
  • 16:08 - 16:13
    now you might say "I don't like that. You
    are injecting code into the kernel. That
  • 16:13 - 16:18
    is, that sounds dangerous" and yeah, but
    let me show you something that I find
  • 16:18 - 16:24
    really interesting. So I'm not
    going too much into depth here, but this
  • 16:24 - 16:29
    is a byte code, so every DTrace script
    gets compiled to bytecode and this
  • 16:29 - 16:34
    bytecode gets sent to the kernel and in
    the kernel you have a virtual machine that
  • 16:34 - 16:39
    interprets that bytecode. So in case you
    write a script that for some reason might
  • 16:39 - 16:45
    go rogue on your kernel, it like allocates
    too much memory, takes too much time, this
  • 16:45 - 16:49
    virtual machine can just say "okay, stop
    it" and just going to revert all the
  • 16:49 - 16:54
    changes that happened to your kernel, and
    that's kinda handy. And it's not a new
  • 16:54 - 17:01
    idea, so if you're using TCP dump it's
    basically the same approach. They also
  • 17:01 - 17:05
    have this kind of bytecode, so that's just
    a little excursion here. This is called
  • 17:05 - 17:13
    BPF, Berkeley Packet Filter, so it's not
    an entirely new idea. So everything I
  • 17:13 - 17:19
    showed you until now was "hey, I can look
    when function calls happen". that's not
  • 17:19 - 17:23
    very much information, so we're going to
    increase the amount of information that we
  • 17:23 - 17:35
    get out of the system with every example.
    So let me look at the actual kernel. So I
  • 17:35 - 17:40
    had to restart my machine, so my setup is
    basically gone now. So let's look at this
  • 17:40 - 17:45
    VM fault function. So this is, this is the
    source code of the operating system that
  • 17:45 - 17:53
    I'm running right now. This is FreeBSD
    current 12 and the VM fault function;
  • 17:53 - 17:58
    remember the mmap system call that I told
    you? So the mmap system call
  • 17:58 - 18:04
    I told you can bring, like map a file
    into your address space. And it doesn't
  • 18:04 - 18:10
    necessarily have to load the entire file,
    so whenever we are touching a page in the
  • 18:10 - 18:16
    system, like a memory page, this machine
    is four kilobytes and it's no super pages
  • 18:16 - 18:21
    here, so whenever it touches a piece of
    memory that you didn't bring into memory
  • 18:21 - 18:25
    yet, we're generating something that's
    called a page fault, and then this
  • 18:25 - 18:31
    function gets called. So here let's look
    at the arguments, and I'm going to skip
  • 18:31 - 18:37
    the zeroeth argument, to look at the first
    argument. So this is the address that
  • 18:37 - 18:44
    provoked that page fault, this is the
    type and these are the flags and I'm going
  • 18:44 - 18:49
    to show you something to make that a
    little bit more readable. So what about
  • 18:49 - 18:59
    this one? So you see it's a pointer and
    this is a big structure, so we want
  • 18:59 - 19:10
    to be able to look at that structure. And
    just probably should do this here, so
  • 19:10 - 19:17
    let's look at this VM fault script here.
    So this is, make this a little bit more,
  • 19:17 - 19:21
    so this is, don't pay too much attention
    to this code, this this is basically just
  • 19:21 - 19:26
    boilerplate to make make stuff readable
    and this is where the actual action is
  • 19:26 - 19:32
    happening. So this is, so what I'm doing
    there is I'm instrumenting the VM
  • 19:32 - 19:36
    fault function and whenever we enter it
    then we're going to use some information
  • 19:36 - 19:41
    that DTrace gives us for free. So this is
    execname, this is the name of the
  • 19:41 - 19:46
    currently running executable that provoked
    the page fault, this is the process ID and
  • 19:46 - 19:53
    here we have a bunch of argument
    variables. So these arg1, arg2, arg3,
  • 19:53 - 19:58
    that are essentially just integers, so
    nothing too fancy there. But we wanna
  • 19:58 - 20:02
    look, wanna be able to look at that
    struct. And here I'm going to use this
  • 20:02 - 20:08
    args array, and this args array
    is kind of special, because it has typing
  • 20:08 - 20:16
    information about the arguments. So when
    you run that, so you're referencing that
  • 20:16 - 20:27
    pointer there with the star, excuse me,
    and let's just run that and maybe, that's
  • 20:27 - 20:33
    a start yeah. So this is an in-kernel
    data structure that we can now look
  • 20:33 - 20:40
    at. So DTrace enabled us to look at in-
    memory data structures as the system runs.
  • 20:40 - 20:44
    And this is really really powerful.
    In in the DTrace script I could use all
  • 20:44 - 20:50
    these fields like I can manipulate this
    args array, this value in there, just like
  • 20:50 - 20:57
    just like every other variable; I
    can pretty much work like I was in C. So
  • 20:57 - 21:03
    how is it doing that? There is something
    that's called CTF, that's not capture the
  • 21:03 - 21:10
    flag, it's, this is the, the Compact C
    Tracing Format, so you can see that but
  • 21:10 - 21:14
    there is a man page in FreeBSD, and
    there's a little segment in the kernel
  • 21:14 - 21:19
    binary, where all this typing information
    is stored. I don't know how that compares
  • 21:19 - 21:24
    to modern DWARF but yeah this is what
    DTrace is working with. So now you might
  • 21:24 - 21:29
    ask yourself "Why on earth would I do
    that? Why on earth would I look at virtual
  • 21:29 - 21:34
    memory, because, yeah, um, this stuff is
    safe isn't it? I mean there's no bugs in
  • 21:34 - 21:43
    there." Except when they are. Anyone
    remembers remembers "Dirty COW"? So this
  • 21:43 - 21:49
    was a very nasty vulnerability in the
    Linux kernel and that that was a problem
  • 21:49 - 21:52
    in the virtual memory management. So it
    allowed you to write to a file that you
  • 21:52 - 21:57
    didn't own as a regular user. So you could
    essentially just write to a binary that
  • 21:57 - 22:02
    had "set UID" set. Very unpleasant, but
    I'm not going to bash the Linux folks
  • 22:02 - 22:08
    here, this is just, I just want to show
    you these things are hard. And the first
  • 22:08 - 22:15
    fix for this problem was in 2005 and then
    it came back in 2016. So now that's fixed
  • 22:15 - 22:21
    and then it came back with "Huge Dirty
    COW" in 2017, so this is, I mean this
  • 22:21 - 22:28
    was there for way over a decade.
    These things are hard to debug. And this
  • 22:28 - 22:33
    is what I like about these systems, so not
    having, not having tools like DTrace to
  • 22:33 - 22:38
    figure out what's going on inside of the
    system somehow, to me, amounts to security
  • 22:38 - 22:42
    by obscurity. And I've heard that some
    people who are developing exploits for
  • 22:42 - 22:46
    systems that have DTrace they say "Oh, I
    really like developing exploits on these
  • 22:46 - 22:53
    systems, because the tooling is so great!"
    Yeah, but, to be honest this is cool,
  • 22:53 - 22:59
    because an exploit is a proof of concept
    and coming up with these exploits quickly
  • 22:59 - 23:03
    is very usable, because you know what's
    going on you can show "Hey, this is going
  • 23:03 - 23:07
    wrong". I had situations, where
    people were telling me "Oh, this is this
  • 23:07 - 23:11
    is not a problem with our program, this is
    this weird operating system that you're
  • 23:11 - 23:18
    using. Like Solaris, weird operating
    system." And, yeah, and then I churned out
  • 23:18 - 23:22
    some DTrace scripts and "No, it's
    actually your problem". "Oh, now I can see
  • 23:22 - 23:31
    that on my Linux box!" Magic. So,
    everything I showed you until now was
  • 23:31 - 23:38
    very, very much related to function calls
    and we want to have a little bit more
  • 23:38 - 23:45
    semantics here, because you might want to
    write a script that inspects protocols,
  • 23:45 - 23:49
    stuff like TCP, UDP stuff like that. So,
    you don't want to know which function
  • 23:49 - 23:54
    inside of the kernel is responsible for
    handling your TCP/IP stuff, so DTrace
  • 23:54 - 24:01
    comes with something that's called static
    providers and I'm just going to show the
  • 24:01 - 24:05
    apropos here. So these are, so every
    static provider has a main page which is
  • 24:05 - 24:11
    kind of handy - documentation whoo - and
    you can see there is an I/O provider if
  • 24:11 - 24:18
    you are interested in looking at this guy:
    Oh, IP for looking at IPv4 and IPv6,
  • 24:18 - 24:24
    TCP... This one is pretty cool, it's about
    scheduling behavior. So, "what does my
  • 24:24 - 24:29
    scheduler do?" And if you look at that, you
    can see some interesting stuff like length
  • 24:29 - 24:33
    priority if you ever saw things like
    priority inversion, stuff like that, now
  • 24:33 - 24:37
    you can see that happen. I'm a nerd, I
    find this interesting for some reason, I
  • 24:37 - 24:43
    don't know. And it's also pretty
    interesting to figure out what's going on,
  • 24:43 - 24:48
    "why is this getting de-scheduled all the
    time?" So, some interesting things going
  • 24:48 - 24:56
    on there. So, I'm running a little bit
    short on time here, but I just quickly
  • 24:56 - 24:59
    want to show you something - this is all
    kernel stuff right now - can we do that
  • 24:59 - 25:05
    with userspace? Of course. So, there was
    one provider that didn't show up when I
  • 25:05 - 25:10
    had my provider listing, but was in the
    DTrace script where I did this timing
  • 25:10 - 25:16
    attack stuff. And that's called the PID
    provider. And the PID provider generates
  • 25:16 - 25:21
    probes on demand, because a process might
    have a lot of probes and you will shortly
  • 25:21 - 25:25
    see why and this is why I'm going to use a
    very small program which is called "true",
  • 25:25 - 25:32
    and true just exits with exit code zero.
    So, nothing too exciting going on here,
  • 25:32 - 25:38
    and this dollar target gets substituted
    in, we get the process ID there. And this
  • 25:38 - 25:45
    is everything that happens when I'm
    executing this program you see this is a
  • 25:45 - 25:49
    little bit more fine-grained than the FBT
    provider, because now we can trace every
  • 25:49 - 25:54
    single instruction inside of that
    function, which is kind of a handy. It's a
  • 25:54 - 25:58
    scriptable debugger. So, these numbers are
    the instructional offsets inside of that
  • 25:58 - 26:03
    function. We can also look at - so this is
    everything in the true segment - we can
  • 26:03 - 26:10
    also look at libraries that got linked in
    and there's a lot of stuff happening in
  • 26:10 - 26:16
    libc for example when you run true.
    So, one last thing that I wanted to show
  • 26:16 - 26:22
    you because it consumed a week of my life:
    I'm using a lot of Haskell and the Mac OS
  • 26:22 - 26:29
    people, they also have DTrace and they
    have GHC Haskell DTrace support - so the
  • 26:29 - 26:38
    Glasgow Haskell compiler - and glorious...
    they have probes to analyze what's going
  • 26:38 - 26:42
    on inside of the runtime system. So, I
    thought "I want to have that, I have
  • 26:42 - 26:47
    DTrace, why doesn't it work on FreeBSD?"
    So, after a week of fighting with make
  • 26:47 - 26:55
    files and linkers, that works: If you
    check out the recent GHC repository and
  • 26:55 - 27:00
    build it on FreeBSD, you get all the nice
    stuff that I'm going to show you now. So,
  • 27:00 - 27:06
    this is a very boring program - it just
    starts 32 green threads and schedules them
  • 27:06 - 27:10
    all over the place - and now I can do
    something like this: phone rings I can
  • 27:10 - 27:14
    ring a telephone.
    laughter
  • 27:14 - 27:19
    No, that would be
    interesting... So, you can also use
  • 27:19 - 27:27
    wildcards - and not as name of the probe -
    and this is what's going on inside, like
  • 27:27 - 27:32
    GC garbage collection and all this stuff.
    Now you can look at this and write useful
  • 27:32 - 27:38
    DTrace scripts that also take my runtime
    system into account. So, stuff like that
  • 27:38 - 27:42
    exists for I think Python - I'm not
    entirely sure because I don't use it -
  • 27:42 - 27:49
    nodejs same, Postgres - I used it but not
    with DTrace right now - and what a find
  • 27:49 - 27:55
    interesting: Firefox. When you run
    JavaScript in your Firefox, it actually
  • 27:55 - 27:59
    has a provider, so you can trace
    JavaScript running in your browser with
  • 27:59 - 28:05
    DTrace, so after everything I just showed
    you, there might be some stuff going on
  • 28:05 - 28:11
    there. So yeah, this is basically
    everything I wanted to show you and I
  • 28:11 - 28:14
    think I'm going to wrap out, because
    otherwise we're not going to have a lot of
  • 28:14 - 28:19
    time for questions and maybe you have
    some. So yeah, thanks.
  • 28:19 - 28:30
    applause
    Herald: Thank you very much Raichoo. We
  • 28:30 - 28:34
    are actually over time already, but we
    have two more minutes because we started
  • 28:34 - 28:39
    three minutes late, so if there are any
    really quick questions, possibly from the
  • 28:39 - 28:43
    internet... There is one, the signal angel
    says, let's hear it.
  • 28:43 - 28:48
    Question: Yeah, hi, okay. So, the question
    is, "which changes are actually necessary
  • 28:48 - 28:52
    to do in the kernel of an operating system
    to support DTrace?"
  • 28:52 - 28:56
    Answer: That's a lot of work. So, it's not
    something like you do in a weekend. This
  • 28:56 - 29:03
    is... So, the person who started the work
    on FreeBSD has sadly passed away now, but
  • 29:03 - 29:10
    I think they took a couple of years to
    have everything in place, so you have to
  • 29:10 - 29:14
    have stuff like the CTF thing that I
    showed you, which is what OpenBSD is
  • 29:14 - 29:20
    currently working on. And then you need
    all those those magic gizmos, like kernel
  • 29:20 - 29:26
    modules and stuff like that. So, it takes
    a lot of time, but it's been ported to
  • 29:26 - 29:31
    most operating systems that are available
    and in use right now. So yeah, hope this
  • 29:31 - 29:34
    answers the question.
    Herald: Excellent and there are no more
  • 29:34 - 29:39
    questions here in the room. I will thank
    Raichoo and you can find him outside of
  • 29:39 - 29:47
    the room and also on Twitter at "raichoo"
    if you have any more further question.
  • 29:47 - 29:51
    postroll music
  • 29:51 - 30:08
    subtitles created by c3subtitles.de
    in the year 2020. Join, and help us!
Title:
34C3 - May contain DTraces of FreeBSD
Description:

more » « less
Video Language:
English
Duration:
30:08

English subtitles

Revisions