link to reddit for ub-good-idea master
authorRalf Jung <post@ralfj.de>
Thu, 25 Nov 2021 00:13:08 +0000 (19:13 -0500)
committerRalf Jung <post@ralfj.de>
Thu, 25 Nov 2021 00:13:08 +0000 (19:13 -0500)
ralf/0x0CB18E521B24F3FF.asc [new file with mode: 0644]
ralf/_posts/2021-11-18-ub-good-idea.md [new file with mode: 0644]
ralf/_posts/2021-11-24-ub-necessary.md [new file with mode: 0644]
ralf/index.html
ralf/robots.txt [new file with mode: 0644]
research/contact.html
research/cv.pdf [new file with mode: 0644]
research/index.html
research/research-statement.pdf
research/thesis.html

diff --git a/ralf/0x0CB18E521B24F3FF.asc b/ralf/0x0CB18E521B24F3FF.asc
new file mode 100644 (file)
index 0000000..f11e320
--- /dev/null
@@ -0,0 +1,612 @@
+-----BEGIN PGP PUBLIC KEY BLOCK-----\r
+\r
+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\r
+=44lh\r
+-----END PGP PUBLIC KEY BLOCK-----\r
diff --git a/ralf/_posts/2021-11-18-ub-good-idea.md b/ralf/_posts/2021-11-18-ub-good-idea.md
new file mode 100644 (file)
index 0000000..19f8268
--- /dev/null
@@ -0,0 +1,165 @@
+---
+title: "Undefined Behavior deserves a better reputation"
+categories: rust research
+reddit: /rust/comments/qx168t/undefined_behavior_deserves_a_better_reputation/
+---
+
+*This is a cross-post of an [article that I wrote for the SIGPLAN blog](https://blog.sigplan.org/2021/11/18/undefined-behavior-deserves-a-better-reputation/).*
+
+"Undefined Behavior" often has a bad reputation. People see it as an excuse compiler writers use to break code, or an excuse by a lazy language designer to not complete the specification and properly define all this behavior.
+But what, really, is Undefined Behavior, and is it as bad as its reputation?
+In this blog post, I will look at this topic from a PL perspective, and argue that Undefined Behavior (or UB for short) is a valuable tool in a language designer's toolbox, and that it can be used responsibly to convey more of the programmer's insight about their code to the compiler with the goal of enabling more optimizations.
+I will also explain why I spent a significant amount of time adding *more* UB to Rust.
+
+<!-- MORE -->
+
+## A simple example
+
+In the best PL tradition, let us consider an artificial example to demonstrate the benefit of UB.
+Imagine we want to implement a function that returns the element in the middle of an array.
+If we are using Rust, we would probably write something like this:
+```rust
+fn mid(data: &[i32]) -> Option<i32> {
+  if data.is_empty() { return None; }
+  return Some(data[data.len()/2]);
+}
+```
+The argument is of type `&[i32]`, which is called a "slice" and consists of a pointer to some array and information about how long the array is.
+`mid` itself returns an integer wrapped in `Option` (corresponding to `Maybe` in Haskell) to properly signal the case where the array is empty.
+In the non-empty case, it computes the index in the middle of `data`, and returns that element.
+
+Now imagine this function is called in a tight loop in the benchmark for our next paper, so performance *really* matters.
+Is there any performance improvement we can hope to achieve in this function?
+It might seem like `mid` already does the absolute minimum amount of work required for the task, but there is some hidden cost in the array access `data[_]`:
+the compiler has to insert a bounds-check here to ensure that we do not access data beyond the size of the array that `data` points to.
+But as the programmer we know that bounds-check to be entirely unnecessary, since `data.len()/2` will always be smaller than `data.len()`!
+Wouldn't it be great if there was a way to tell the compiler about this, such that we can be sure no bounds check happens?
+
+Here is one way to accomplish that in Rust:
+```rust
+fn mid(data: &[i32]) -> Option<i32> {
+  if data.is_empty() { return None; }
+  match data.get(data.len()/2) {
+    Some(&x) => return Some(x),
+    None => unsafe { unreachable_unchecked() }
+  }
+}
+```
+We are now using the `get` operation to access the array, which returns an `Option` that is `None` for out-of-bounds accesses.
+And in case we get `None`, we call a special function `unreachable_unchecked` which makes a *binding promise to the compiler* that this piece of code is unreachable.
+The keyword `unsafe` here indicates that what we are doing is not covered by the type safety guarantees of the language: the compiler will not actually check that the promise we made holds true, it will just trust us on that.
+(The phrase "unchecked" is a Rust idiom; this is the "unchecked" version of `unreachable`, which inserts a run-time check that safely aborts the program should this code ever be reached -- or, to be more precise, it triggers a Rust panic.)
+
+After some inlining, the relevant part of this code looks as follows:
+```rust
+  let idx = data.len()/2;
+  if idx < data.len() { // Automatically inserted bounds-check.
+    ... // Access the array at `idx`.
+  } else {
+    unreachable_unchecked()
+  }
+```
+Since we told the compiler that the `else` branch is unreachable, it is easy to optimize away the conditional, so we end up with just a direct access to element `idx` in the array.
+Problem solved!
+(In fact, Rust provides `get_unchecked` as an alternative to `get` where the caller has to promise that the index is in-bounds, so a Rust programmer would just write `data.get_unchecked(data.len()/2)` to implement `mid` efficiently.)
+
+I expect some readers will not be happy with the way I achieved the desired optimization in the initial example, and argue that the compiler should be smart enough to do this automatically.
+I will get back to this point later; for now, just note that the latest stable version of Rust at the time of writing does [not perform this optimization](https://rust.godbolt.org/z/G34Ezzb9c) (as indicated by the call to `panic_bounds_check`).
+
+## Where is the Undefined Behavior?
+
+Hang on, you might say at this point, wasn't this blog post supposed to be about Undefined Behavior?
+That term did not even appear in the discussion of the example!
+Indeed, I was a bit sneaky and used different terminology that I think better captures a constructive way to think about Undefined Behavior.
+In the typical terminology, I would have said that calling the special function `unreachable_unchecked` causes immediate Undefined Behavior.
+Following the definition in the latest C standard (also shared by C++), the standard "imposes no requirements" on programs that exhibit Undefined Behavior.
+The compiler can hence basically replace the `else` branch by whatever code it wants, famously including "to make [demons fly out of your nose](http://www.catb.org/jargon/html/N/nasal-demons.html)", but also including just executing the `then` branch instead.
+
+This line of reasoning leads to the same result, but it paints an unnecessarily antagonistic picture of compiler writers. It makes it sound like compilers use complicated analyses to detect Undefined Behavior. Once they find UB, they have an excuse to emit broken code and hide behind the standard should anyone complain.
+This is not what actually happens.
+As we have seen in our example, the compiler really has no idea if this code has Undefined Behavior or not -- all it does is perform optimizations that are correct *under the extra assumption* that there is no Undefined Behavior.
+
+## UB is a double-edged sword
+
+Another reaction you might have is that `unreachable_unchecked` is not a "typical" example of UB.
+Most people probably associate that term with C or C++, which do not even have `unreachable_unchecked` (though many compilers provide an intrinsic with the same effect, e.g., `__builtin_unreachable` in GCC).
+So it may seem like I picked a strange example.
+Shouldn't I be talking about how, say, signed integer overflow is UB?
+
+This is the right time to admit that I am *not* going to defend all UB in C/C++.
+I think UB as a concept is a great idea, and `unreachable_unchecked` is the "most pure" form of UB that shows how it can be used by the programmer to convey extra information to the compiler -- but I also think that C and C++ are massively overusing UB.
+Of course, it is easy to say this with the benefit of hindsight; the first C compilers were extremely simple and today's use of UB for optimizations only emerged over time.
+It took a while for the implications of the modern interpretation of UB in the standard to become clear -- and C and C++, being very successful languages, have massive existing codebases which makes it super hard to revise any prior decision.
+This post is about defending and promoting UB as a concept, not UB in C/C++.
+
+Speaking of signed integer overflow, I think this is actually a good example for how to *not* use UB.
+An innocent-looking `+` turns into a promise of the programmer that this addition will never overflow, but the programmer probably will not carefully do a mental no-overflow proof for every single addition in their program.
+Instead, `+` could perform overflow checks or well-defined wrap-around, and the language could provide an `unchecked_add` function where overflows are UB.
+This lets the programmer opt in to providing extra no-overflow promises, to be used in situations where it is really beneficial for performance that the compiler can make this assumption (such as [this example](https://youtu.be/yG1OZ69H_-o?t=2357)).
+Basically, I am considering this a language (and library) design problem: UB is a sharp knife; when used well it gets the job done better, but it can also hurt a lot when used without enough care.
+
+Language and library design is not everything that can be used to tame UB, however.
+Good tooling can also make a big difference: if programmers can easily run their programs in "UB-checking mode", they can write tests to at least ensure the absence of UB for certain inputs.
+(Shameless plug: I am working on [Miri](https://github.com/rust-lang/miri/), a tool that provides exactly this for Rust.)
+Library authors can run their test suites with such a tool, and the tool can also be used exploratively to learn about what exactly is and is not UB in the first place.
+I think this is absolutely crucial, and language designers should design UB in a way that makes UB-checking tools more feasible.
+For the examples of UB we have seen so far (`unreachable_unchecked`, `get_unchecked`, and `unchecked_add`), this is obviously trivial.
+
+## How far can we push UB?
+
+That said, not all UB is that simple to teach and test.
+Even Rust, with its benefit of learning from several decades of experience with UB in C and C++, has UB that is a lot more subtle than this. The most glaring example of this is probably UB related to incorrect aliasing of mutable references.
+(Other, less extreme examples would be UB due to using uninitialized memory, or UB due to data races.)
+
+The Rust type system ensures that mutable references never alias any other reference that is currently being used in the program, i.e., they never point to the same memory as any other reference.
+This is a juicy guarantee for compiler writers, because while reordering memory accesses is often beneficial, it can be very hard to figure out if the transformation is even allowed -- if two accesses alias, then their original order must be preserved.
+
+However, `unsafe` code in Rust could easily create aliasing mutable references.
+So what can we do?
+We make the programmer promise that they do not do this!
+This is a lot like saying "the programmer promises that `unreachable_unchecked` is never called", so we can put on our UB lens and say that it is Undefined Behavior to have aliasing mutable references.
+
+The devil is of course in the details of defining what exactly this means.
+[Stacked Borrows](https://plv.mpi-sws.org/rustbelt/stacked-borrows/) (part of [my PhD thesis](https://www.ralfj.de/research/thesis.html) and also described in a series of blog posts: [v1.0](https://www.ralfj.de/blog/2018/11/16/stacked-borrows-implementation.html), [v2.0](https://www.ralfj.de/blog/2019/04/30/stacked-borrows-2.html), [v2.1](https://www.ralfj.de/blog/2019/05/21/stacked-borrows-2.1.html)) goes into all that detail by giving an operational semantics that exactly defines the promises programmers have to make.
+And that semantics is non-trivial!
+According to Stacked Borrows, the following code has UB:
+```rust
+let x = &mut 42; // Safely create a reference.
+let xptr = x as *mut i32; // Turn that reference into a raw (unchecked) pointer.
+let x1 = unsafe { &mut *xptr }; // Turn the pointer back into a reference...
+let x2 = unsafe { &mut *xptr }; // ...twice, so uniqueness is violated.
+*x1 = 0; // Undefined Behavior!
+```
+The reason this code has UB is that creating `x2` makes a promise that this is the unique reference created from `xptr`, so the previously created `x1` is invalidated when `x2` gets created.
+This means future uses of `x1` are Undefined Behavior.
+
+So this raises the question: can we really expect every author of `unsafe` Rust code to internalize Stacked Borrows to the extent that they can faithfully promise to the Rust compiler that their code will comply by this bespoke set of rules?
+Is it a good idea to interpret `&mut expr` as a promise that all aliasing was carefully checked and this reference is definitely unique?
+As with other UB, we can help programmers by providing tools; Miri contains an implementation of Stacked Borrows which both helps us to evaluate whether actual Rust code is compatible (or can reasonably be made compatible) with Stacked Borrows, and it helps Rust programmers by giving them a way to at least test for aliasing violations, and to interactively play with the semantics to gain a better understanding.
+I think that puts us in a pretty good spot overall, but some people still argue that Stacked Borrows goes too far and Rust will end up in a situation similar to the one C and C++ find themselves in -- where too few programmers actually know how to write UB-free code, and a significant amount of the code people rely on exhibits UB.
+
+Stacked Borrows is not part of the Rust spec, and is not the final word for aliasing-related UB in Rust.
+So there is still the chance that future revisions of this model can be made to better align with programmer intuition.
+The above code might get accepted because `x2` is not actually being used to access memory.
+Or maybe `&mut expr` should only make such promises when used outside an `unsafe` block -- but then, should adding `unsafe` really change the semantics of the program?
+As usual, language design is a game of trade-offs.
+
+## Conclusion
+
+I have presented Undefined Behavior as a tool that enables the programmer to write code that the compiler cannot check for correctness, and argued that -- used responsibly -- it is a useful component in a language designer's toolbox.
+
+As I alluded to earlier, the "obvious" alternative would be to make the compiler smarter.
+However, real programs are typically a lot more complicated than my simple example (which already outsmarts Rust's LLVM backend), and the reasoning required to justify an optimization can become arbitrarily complicated.
+Language designers should acknowledge that optimizers have their limitations and give programmers the tools they need to help the optimizer.
+Indeed, I think the fact that Rust combines a clever type checker with the idea of using `unsafe` code for the cases where the type checker is not clever enough is crucial for its success: `unsafe` is not a bug; it is a feature without which Rust would not be able to make systems programming safer in practice.
+It is also worth mentioning that many languages that we all know and love provide comparable "trusted" operations or annotations, e.g., `Obj.magic` in OCaml or the rewrite rules in GHC.
+Rust only differs in how prevalent unsafe code is in the ecosystem (and in emphasizing the importance of [encapsulating such code within safe APIs](https://blog.sigplan.org/2019/10/17/what-type-soundness-theorem-do-you-really-want-to-prove/)).
+
+In closing, I would like to propose that "Undefined Behavior" might need a rebranding.
+The term focuses on the negative case, when really all we ever care about as programmers or compiler authors is that programs do *not* have Undefined Behavior.
+Can we get rid of this double negation?
+Maybe we should talk about "ensuring Well-Defined Behavior" instead of "avoiding Undefined Behavior".
+
+To sum up: most of the time, ensuring Well-Defined Behavior is the responsibility of the type system, but as language designers we should not rule out the idea of sharing that responsibility with the programmer.
+
+*Thanks to Anish Athalye and Adrian Sampson for feedback on earlier drafts of this post.*
diff --git a/ralf/_posts/2021-11-24-ub-necessary.md b/ralf/_posts/2021-11-24-ub-necessary.md
new file mode 100644 (file)
index 0000000..970db70
--- /dev/null
@@ -0,0 +1,116 @@
+---
+title: "Do we really need Undefined Behavior?"
+categories: rust research
+---
+
+I recently published a [blog post on why Undefined Behavior is actually not a bad idea]({% post_url 2021-11-18-ub-good-idea %}).
+Coincidentally, this is just a few weeks after the publication of [this paper by Victor Yodaiken](https://dl.acm.org/doi/pdf/10.1145/3477113.3487274) which basically argues that Undefined Behavior (UB for short) made C unusable for one of its core audiences, OS developers.
+Here I refer to the typical modern interpretation of UB: assumptions the compiler may trust, without bounds on what happens if they are violated.
+The paper makes many good points, but I think the author is throwing out the baby with the bathwater by concluding that we should entirely get rid of this kind of Undefined Behavior.
+The point of this blog post is to argue that we do need UB by showing that even some of the most basic optimizations that all compilers perform require this far-reaching notion of Undefined Behavior.
+
+<!-- MORE -->
+
+To avoid ambiguity, I will refer to the above notion of UB as "unrestricted UB".
+The alternative interpretation of UB promoted by Yodaiken is what one might call "platform-specific UB".
+This requires that even programs with Undefined Behavior should behave in a consistent way: for example, the result of an out-of-bounds write may be 'unpredictable', it may either not actually happen or mutate some data somewhere.
+However, if a write occurs, the program must still behave in a way that is consistent with performing a write to the given address in the target platform.
+(At least, that is my understanding. I hope I am not misrepresenting their position here. The paper does not go into a lot of detail on how the situation could be improved, but it mentions proposals "where compilers map source operations to well-defined instruction sequences, in either a virtual or real machine, from which compiler optimisations may not observably stray".)[^N2769]
+
+[^N2769]: The paper also cites [C committee proposal N2769](http://www.open-std.org/jtc1/sc22/wg14/www/docs/n2769.pdf). However, N2769 explicitly says that `a + 1 < a` can still be optimized to `false`, while Yodaiken mentions this as an undesirable optimization. In fact, N2769 says it is okay and of "great value" to "assume the absence of UB". I admit I do not understand the distinction N2769 makes between "assuming the absence of UB" and "making assumptions about the result of UB", but it seems clear that Yodaiken goes even further than N2769 in restricting UB-based optimizations.
+
+## Examples of unrestricted UB
+
+So what is the problem with platform-specific UB?
+First of all, it does not reflect what the major compilers actually do in practice.
+I have seen claims in the past that GCC and LLVM are the only compilers making use of unrestricted UB; this is simply not true.
+Here is an [example of ICC performing such an optimization](https://godbolt.org/z/j18oW6YaE) (based on example code by Yodaiken):
+
+{% highlight c %}
+#include <stdlib.h>
+#include <stdio.h>
+
+int main () {
+  int *i = malloc(sizeof(int));
+  *i = 1;
+  int *j = malloc(sizeof(int));
+  *j = 1;
+  int *k = malloc(sizeof(int));
+  *k = 1;
+
+  int *x = j+(32/4);
+  *x = 40;
+  printf("*i=%d (%p) *j=%d (%p) *k=%d (%p)  *x=%d (%p)", *i, i, *j, j, *k, k, *x, x);
+}
+{% endhighlight %}
+
+This program prints the values and addresses of a few pointers.
+The concrete addresses are different on each execution, but the pattern is always the same:
+```
+*i=1 (0x1aef2a0) *j=1 (0x1aef2c0) *k=1 (0x1aef2e0)  *x=40 (0x1aef2e0)
+```
+Notice how `k` and `x` point to the same address (`0x1aef2e0` in this particular execution), but seem to contain different values.
+This is impossible under "platform-specific UB": no sequence of target platform operations can lead to a situation where the same address contains two different values.[^N2769-2]
+This example demonstrates that even ICC with `-O1` already requires unrestricted UB.
+(For completeness' sake, [here is a similar example for GCC](https://godbolt.org/z/c8qaWhnEG); at the time of writing, `i` and `x` have the same address but different values.
+And [here is an example for clang/LLVM](https://godbolt.org/z/r8TM7Ga8q), this time it's again `k` and `x` that behave inconsistently.
+godbolt supports MSVC but does not seem to be willing to execute the generated programs, but I have no doubt that similar examples can be found for this compiler.)
+
+[^N2769-2]: I assume N2769 would also not be happy with this outcome of our example program.
+
+What about niche compilers specifically built for reliable software?
+In their paper, Yodaiken claims that the verified C compiler CompCert "does not do any undefined behavior based optimization"
+(with a footnote saying "Except for assuming objects do not overlap in memory"; I am not quite sure what exactly is meant by this).
+This is incorrect.
+First of all, since CompCert has a proof of correctness, we can have a look at its specification to see what exactly it promises to its users---and that specification quite clearly follows the "unrestricted UB" approach, allowing the compiled program to produce arbitrary results if the source program has Undefined Behavior.
+Secondly, while CompCert's optimizer is very limited, it is still powerful enough that we can actually demonstrate inconsistent behavior for UB programs in practice:
+
+{% highlight c %}
+#include <stdio.h>
+
+int y, x;
+
+int f(void)
+{
+  y = 0;
+  *(&x + 1) = 1;
+  return y;
+}
+
+int main()
+{
+  int eq = (&x+1 == &y);
+  if (eq) {
+    printf("%d ", f());
+    printf("%d\n", y);
+  }
+  return 0;
+}
+{% endhighlight %}
+
+(Putting the result of the comparison into a local variable `eq` prevents CompCert from optimizing away the entire conditional.)
+This program, after being compiled with CompCert, prints "0 1".
+Again, this is printing "the same thing" twice, in this case the value stored at `y`, and produces two different results.
+CompCert exploited UB in a way that leads to a situation which should be "impossible" on the underlying machine.
+
+## Platform-specific UB is not an option
+
+Both of these examples highlight a fundamental problem with "platform-specific UB": *any* out-of-bounds write could potentially modify any other variable (at least any variable that has an address in memory).
+This can make even the most basic parts of high-quality code generation, such as register allocation, tricky or impossible: a variable that has its address taken has to be re-loaded from that same address any time an out-of-bounds write might have happened, since that write might just have hit the right address to change this variable's value.
+This applies even if the address has not yet been leaked to the outside world, as the first example shows.
+This is probably why there is hardly any compiler that follows the platform-specific interpretation of UB.
+(I say "hardly any" without knowing a counterexample, but I would not be surprised if some compilers for high-assurance embedded code are so simple that platform-specific UB is sufficient for them. But that is hardly representative for how C is used---and as we have seen with CompCert, even some high-assurance compilers do rely on unrestricted UB.)
+
+I honestly think *trying* to write a highly optimizing compiler based on a different interpretation of UB would be a worthwhile experiment.
+We sorely lack data on how big the performance gain of exploiting UB actually is.
+However, I strongly doubt that the result would even come close to the most widely used compilers today---and programmers that can accept such a big performance hit would probably not use C to begin with.
+Certainly, any proposal for *requiring* compilers to curtail their exploitation of UB must come with evidence that this would even be possible while keeping C a viable language for performance-sensitive code.
+
+To conclude, I fully agree with Yodaiken that C has a problem, and that reliably writing C has become incredibly hard since undefined behavior is so difficult to avoid.
+It is certainly worth reducing the amount of things that can cause UB in C, and developing practical tools to detect more advanced kinds of UB such as strict aliasing violations.
+I also wonder whether strict aliasing can be made more compatible with low-level programming patterns---or whether C should provide alternative means of alias control to programmers, such as `restrict` (not that its specification doesn't have its own set of problems, but an opt-in mechanism like `restrict` seems fundamentally more suited when the goal is to ensure compatibility with existing code).
+
+However, I do not think this problem can be solved with a platform-specific interpretation of UB.
+That would declare all but the most basic C compilers as non-compliant.
+We need to find some middle ground that actually permits compilers to meaningfully optimize the code, while also enabling programmers to actually write standards-compliant programs.
+I am not involved in the work that happens here on the C side, but for Rust, I think we can achieve this through a combination of being diligent about how much UB we really need, using language and API design to make it easier for the programmer to be aware of UB requirements imposed by the code they write, and providing [tools](https://github.com/rust-lang/miri/) that help programmers determine if their code exhibits UB or not.
index 32683c8..12c08a7 100644 (file)
@@ -5,8 +5,8 @@ title: ralfj.de
 <div>
 <h2>Welcome</h2>
 <p>
-Welcome at ralfj.de, my server for experiments and digital independence.
-On this machine I maintain several services which are part of modern life, and which I would rather not entrust to data krakens in some cloud (what if it's raining?):
+Welcome at ralfj.de, my server for experiments and digital self-sufficiency.
+On this machine I maintain several services which are part of modern life, and which I would rather not entrust to data krakens and the cloud (what if it's raining?):
 </p>
 <ul>
     <li><a href="mailto:post-AT-ralfj-DOT-de">E-Mail</a>,</li>
@@ -17,10 +17,10 @@ On this machine I maintain several services which are part of modern life, and w
     <li>and more.</li>
 </ul>
 <p>
-All software running on my server is of course <a href="https://en.wikipedia.org/wiki/Free_Software" target="_blank">free</a>.
-This is the only way for me to expect that it is not actually acting against my interests.
-Besides, all communication (if at all possible) is encrypted. This self-defense is seemingly necessary today to achieve freedom and basic rights (like privacy of telecommunications) in the digital world.<br>
-Speaking of which, my GPG key has the ID 0x1B24F3FF. You can find it <a href="0x1B24F3FF.asc">here</a> or on any <a href="https://sks-keyservers.net/" target="_blank">keyserver of the SKS network</a>.
+All software running on my server is of course <a href="https://en.wikipedia.org/wiki/Free_Software" target="_blank">free</a> (as in freedom, not just free beer).
+That way, I can expect it to not act against my interests.
+Besides, all communication (if at all possible) is encrypted. This self-defense is seemingly necessary today to achieve basic civil rights (like privacy of telecommunications) in the digital world.<br>
+Speaking of which, my GPG key has the ID 0x0CB18E521B24F3FF. You can find it <a href="0x0CB18E521B24F3FF.asc">here</a> or on <a href="https://keys.openpgp.org/vks/v1/by-fingerprint/BD3F5AF6D95D77C48A85AF680CB18E521B24F3FF" target="_blank">keys.openpgp.org</a>.
 </p>
 <p>
 You may wonder why I spend so much time on this. Well, I already mentioned independence of the usual internet giants.
@@ -38,7 +38,7 @@ Use the menu at the left to browse this site for information about me and my pro
 <div lang="de">
 <h2>Willkommen</h2>
 <p>
-Willkommen auf ralfj.de, meinem Server für Experimente und digitale Unabhängigkeit.
+Willkommen auf ralfj.de, meinem Server für Experimente und digitale Eigenversorgung.
 Auf dieser Maschine laufen diverse Dienste, die zum modernen Alltag gehören, und die ich ungern Datenkraken in irgendwelchen Wolken anvertrauen möchte (was, wenn es regnet?):
 </p>
 <ul>
@@ -52,8 +52,8 @@ Auf dieser Maschine laufen diverse Dienste, die zum modernen Alltag gehören, un
 <p>
 Alle Software, die auf meinem Server läuft, ist selbstverständlich <a href="https://de.wikipedia.org/wiki/Freie_Software" target="_blank">frei</a>.
 Nur so kann ich davon ausgehen, dass sie nicht gegen mich bzw. meine Interessen handelt.
-Zudem läuft alle Kommunikation (soweit irgend möglich) verschlüsselt ab. Diese Art von Selbstverteidigung ist heutzutage offenbar nötig, um verbriefte Rechte (wie das Postgeheimnis) und unsere Freiheit auch im Internet durchzusetzen.<br>
-Mein GPG-Schlüssel hat übrigens die ID 0x1B24F3FF. Du kannst ihn <a href="0x1B24F3FF.asc">hier</a> oder von einem beliebigen <a href="https://sks-keyservers.net/" target="_blank">Schlüsselserver des SKS-Netzes</a> herunterladen.
+Zudem läuft alle Kommunikation (soweit irgend möglich) verschlüsselt ab. Diese Art von Selbstverteidigung ist heutzutage offenbar nötig, um verbriefte Rechte (wie das Postgeheimnis) auch im Internet durchzusetzen.<br>
+Mein GPG-Schlüssel hat übrigens die ID 0x0CB18E521B24F3FF. Du kannst ihn <a href="0x0CB18E521B24F3FF.asc">hier</a> oder von <a href="https://keys.openpgp.org/vks/v1/by-fingerprint/BD3F5AF6D95D77C48A85AF680CB18E521B24F3FF" target="_blank">keys.openpgp.org</a> herunterladen.
 </p>
 <p>
 Warum ich mir diese Mühe mache? Nun, die Unabhängigkeit von den üblichen Internetgiganten habe ich ja schon erwähnt.
diff --git a/ralf/robots.txt b/ralf/robots.txt
new file mode 100644 (file)
index 0000000..e69de29
index a4c4076..fffa767 100644 (file)
@@ -10,8 +10,7 @@ sort: 2
 <h3>Work Address</h3>
 
 <p>
-Floor 9, PDOS<br/>
-M.I.T. CSAIL, the Stata Center<br/>
+MIT CSAIL, 32-G978B (PDOS)<br/>
 32 Vassar St<br/>
 Cambridge, MA 02139<br/>
 USA
diff --git a/research/cv.pdf b/research/cv.pdf
new file mode 100644 (file)
index 0000000..1030d4c
Binary files /dev/null and b/research/cv.pdf differ
index 87ce0d9..d121152 100644 (file)
@@ -4,14 +4,17 @@ title: Ralf Jung
 
 <div style="float:right; margin-left:0.8em; margin-bottom: 0.3em"><img src="me.jpg"></div>
 
-<p>I am a post-doctoral researcher in the <a href="https://pdos.csail.mit.edu/">PDOS group</a> at <a href="https://www.csail.mit.edu/" target="_blank">MIT CSAIL</a> under the supervision of <a href="https://people.csail.mit.edu/kaashoek/" target="_blank">Frans Kaashoek</a> and <a href="https://people.csail.mit.edu/nickolai/" target="_blank">Nickolai Zeldovich</a>.</p>
+<p>I am a post-doctoral researcher in the <a href="https://pdos.csail.mit.edu/">PDOS group</a> at <a href="https://www.csail.mit.edu/" target="_blank">MIT CSAIL</a> under the supervision of <a href="https://people.csail.mit.edu/kaashoek/" target="_blank">Frans Kaashoek</a> and <a href="https://people.csail.mit.edu/nickolai/" target="_blank">Nickolai Zeldovich</a>.<br>
+Previously, I completed my <a href="thesis.html">PhD</a> at <a href="https://www.mpi-sws.org/">MPI-SWS</a> and <a href="https://www.uni-saarland.de/" target="_blank">Saarland University</a> in Saarbrücken, Germany; my advisor was <a href="https://people.mpi-sws.org/~dreyer/">Derek Dreyer</a>.</p>
 
-<p>Previously, I completed my <a href="thesis.html">PhD</a> at <a href="https://www.mpi-sws.org/">MPI-SWS</a> and <a href="https://www.uni-saarland.de/" target="_blank">Saarland University</a> in Saarbrücken, Germany.</p>
+<p><i>I am on the academic job market this year (fall 2021), mostly looking for faculty positions in Europe.</i></p>
 
-<p>I am currently working on giving a formal model to <a href="https://www.rust-lang.org/">Rust's</a> type system.
-This work is part of the <a href="https://plv.mpi-sws.org/rustbelt/">RustBelt</a> project. <br/>
-The Rust work builds on my previous work on <a href="https://iris-project.org/">Iris</a>, a logic to support modular reasoning about higher-order concurrent imperative programs. The focus there was on providing simple building blocks that are powerful enough to recover more sophisticated reasoning techniques that were often axiomatized in previous logics. <br/>
-For some more information, check out my <a href="https://www.ralfj.de/blog/categories/research.html">research blog</a> and my <a href="research-statement.pdf">research statement</a>.</p>
+<p>My two main lines of work are about <a href="https://www.rust-lang.org/">Rust</a> and <a href="https://iris-project.org/">Iris</a>.<br>
+On the Rust side, I am working (also in collaboration with the Rust language team) towards a solid formal foundation for the language, including in particular the unsafe parts.
+One key result here is our <a href="https://plv.mpi-sws.org/rustbelt/popl18/">type safety proof</a>, which also describes a methodology for establishing type safety of well-encapsulated unsafe code.
+My goal is to make unsafe Rust just as safe as safe Rust by means of formal verification.<br>
+On the Iris side, besides continuing development of its logical foundations, I am interested in applying Iris to new problem domains; recently I started working on modular verification of fault-tolerant distributed system components.<br>
+For some more information, check out my <a href="https://www.ralfj.de/blog/categories/research.html">research blog</a>, my <a href="cv.pdf">CV</a>, and my <a href="research-statement.pdf">research statement</a>.</p>
 
 <p>In my free time, I like to run internet services myself and work on free software.
 This goes hand-in-hand with my pursuit of defending our privacy rights and our freedom in the digital world.
index 18ed190..225a940 100644 (file)
Binary files a/research/research-statement.pdf and b/research/research-statement.pdf differ
index b494077..5efaad2 100644 (file)
@@ -19,8 +19,9 @@ slug: Thesis
 <p style="color:red">
 This thesis has received an <a href="https://awards.acm.org/about/2020-doctoral-dissertation" style="color:red;font-weight:bold;">Honorable Mention for the ACM Doctoral Dissertation Award</a>,
 the <a href="https://sigplan.org/Awards/Dissertation/#2021_Ralf_Jung__Max_Planck_Institute_for_Software_Systems_and_Saarland_University" style="color:red;font-weight:bold;">ACM SIGPLAN John C. Reynolds Doctoral Dissertation Award</a> (as one of two recipients),
-an <a href="https://www.mpg.de/prizes/otto-hahn-medal" style="color:red;font-weight:bold;">Otto Hahn Medal</a>
-and the <a href="https://etaps.org/2021/doctoral-dissertation-award" style="color:red;font-weight:bold;">ETAPS Doctoral Dissertation Award</a>.
+an <a href="https://www.mpg.de/prizes/otto-hahn-medal" style="color:red;font-weight:bold;">Otto Hahn Medal</a>,
+the <a href="https://etaps.org/2021/doctoral-dissertation-award" style="color:red;font-weight:bold;">ETAPS Doctoral Dissertation Award</a>,
+and the Saarland University <a href="https://www.uni-saarland.de/universitaet/aktuell/news/artikel/nr/24072.html" style="color:red;font-weight:bold;">Dr. Eduard Martin-Preis</a>.
 </p>
 
 <h3>Download and references</h3>