<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom"><title>Geoffrey Thomas (geofft)</title><link href="https://ldpreload.com/" rel="alternate"></link><link href="https://ldpreload.com/feeds/all.atom.xml" rel="self"></link><id>https://ldpreload.com/</id><updated>2018-12-18T00:00:00+00:00</updated><entry><title>9 Reasons Python Sucks</title><link href="https://ldpreload.com/blog/9-reason-python-sucks" rel="alternate"></link><published>2018-12-18T00:00:00+00:00</published><updated>2018-12-18T00:00:00+00:00</updated><author><name>Geoffrey Thomas</name></author><id>tag:ldpreload.com,2018-12-18:/blog/9-reason-python-sucks</id><summary type="html">&lt;p&gt;This is a list of reasons why I think Python is a terrible programming language. Naturally, none of them apply to other programming languages.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;It's impossible to determine at compile time whether a Python program can terminate.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;While strings in Python 3 are significantly better than strings in Python 2 …&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;</summary><content type="html">&lt;p&gt;This is a list of reasons why I think Python is a terrible programming language. Naturally, none of them apply to other programming languages.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;It's impossible to determine at compile time whether a Python program can terminate.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;While strings in Python 3 are significantly better than strings in Python 2, they consist of a series of &lt;a href="https://manishearth.github.io/blog/2017/01/14/stop-ascribing-meaning-to-unicode-code-points/" title="Let's Stop Ascribing Meaning To Code Points"&gt;"code points" instead of characters&lt;/a&gt;, so there's no way to reference the third character of a Python string. For ASCII strings, this works fine in C, so I prefer writing in C. Python claims to support Unicode but can't even get this right.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;If I compile a Python module on Linux, it doesn't work on a Mac. This is a shocking oversight for a so-called "cross-platform" language.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The &lt;code&gt;os.link&lt;/code&gt; function does not let you create a hard link to a directory.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The standard library sorting function takes at &lt;em&gt;least&lt;/em&gt; O(&lt;em&gt;n&lt;/em&gt; log &lt;em&gt;n&lt;/em&gt;) time. I understand dynamic languages are slow, but why is it this slow?&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The &lt;code&gt;cryptography&lt;/code&gt; module claims to implement public-key cryptography, but mathematicians have so far been unable to prove that one-way functions, a prerequisite of public-key cryptography, even exist. It's surprising that the Python ecosystem is of such low quality and holds to dubious scientific standards.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;When you compile NumPy or SciPy from source, you need to build FORTRAN code, and FORTRAN sucks which is clearly Python's fault.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;If you're running two Python programs from different users on the same machine, a speculative load in one program might be able to learn information from the other program based on cache timing side channels.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Python is unable to reverse entropy.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;</content><category term="misc"></category></entry><entry><title>Finding a kernel regression in half an hour with git bisect run</title><link href="https://ldpreload.com/blog/git-bisect-run" rel="alternate"></link><published>2018-03-02T00:00:00+00:00</published><updated>2018-03-02T00:00:00+00:00</updated><author><name>Geoffrey Thomas</name></author><id>tag:ldpreload.com,2018-03-02:/blog/git-bisect-run</id><summary type="html">&lt;p&gt;The &lt;code&gt;git bisect&lt;/code&gt; command helps you identify the first commit in a range that broke something. You give it a good commit and a bad one, and it will do a binary search between the two to find the first bad commit. At each step, you say either &lt;code&gt;git bisect …&lt;/code&gt;&lt;/p&gt;</summary><content type="html">&lt;p&gt;The &lt;code&gt;git bisect&lt;/code&gt; command helps you identify the first commit in a range that broke something. You give it a good commit and a bad one, and it will do a binary search between the two to find the first bad commit. At each step, you say either &lt;code&gt;git bisect good&lt;/code&gt; or &lt;code&gt;git bisect bad&lt;/code&gt; depending on whether it passes your test, and it will move you halfway through the remaining commits in the range.&lt;/p&gt;
&lt;p&gt;There are several guides for using git bisect with the Linux kernel (e.g., &lt;a href="https://www.kernel.org/doc/html/v4.15/admin-guide/bug-bisect.html"&gt;upstream&lt;/a&gt;, &lt;a href="https://wiki.gentoo.org/wiki/Kernel_git-bisect"&gt;Gentoo&lt;/a&gt;, and &lt;a href="https://wiki.ubuntu.com/Kernel/KernelBisection"&gt;Ubuntu&lt;/a&gt; all have one). Unfortunately, they're pretty time-intensive operations; they all say something to the effect of, "now build the kernel, reboot into it, and test it, then type &lt;code&gt;git bisect good&lt;/code&gt; or &lt;code&gt;git bisect bad&lt;/code&gt; depending on whether it worked." For a tricky hardware compatibility bug, this might be your only option. But if you're testing something about the kernel's behavior, this is unnecessarily slow and manual, and you might be tempted to do something else, like read commit logs.&lt;/p&gt;
&lt;p&gt;At work a few days ago, someone reported that a certain application no longer worked in a new VM. After some initial debugging with &lt;code&gt;strace&lt;/code&gt;, we determined that the program was calling the &lt;a href="http://man7.org/linux/man-pages/man2/listen.2.html"&gt;listen system call&lt;/a&gt; with a backlog of 0: that is, it was saying it was willing to accept up to zero connections. By the specification, it shouldn't work&amp;mdash;and yet it did work on their older VM. A few things were different between the new systems, but one notable one was that the new VM had kernel 4.9 and the old one kernel 4.1. (Another was that it was deployed in a new cloud environment that my team is responsible for, with some networking changes, so we wanted to ensure we had not broken anything!)&lt;/p&gt;
&lt;p&gt;I tried reading through &lt;code&gt;git log --grep listen v4.1..v4.9 net/&lt;/code&gt;, but there was entirely too much and I couldn't find anything. So I decided to see if bisection could help me, with the use of &lt;code&gt;git bisect run&lt;/code&gt;, which enables &lt;a href="https://lwn.net/Articles/317154/"&gt;fully automated bisecting&lt;/a&gt;. I wasn't excited about rebooting my machine to do a binary search across eight kernel releases, but if I could get it to run in some other way, I could just leave it running.&lt;/p&gt;
&lt;p&gt;For a normal program, it's pretty easy to use &lt;code&gt;git bisect run&lt;/code&gt;, which just wants a command that returns success (0) or failure (1): you can usually do something like &lt;code&gt;git bisect run make test&lt;/code&gt;. For a kernel regression, though, we'll need a command to boot the kernel and run some code. We can use the &lt;a href="https://www.qemu.org/"&gt;qemu&lt;/a&gt; virtual machine software for this, which has two properties that make it particularly suitable as such a command: it can boot a Linux kernel directly, instead of emulating a bootloader on a hard disk, and it can run a temporary VM in a single command line without any additional setup.&lt;/p&gt;
&lt;p&gt;We'll build ourselves a tiny "initrd" (initial RAM disk), which is what's commonly used to load enough drivers to access your hard drive and completely boot your system. However, our initrd will just contain our one test program, which will possibly print a success message, and shut down the system. We can't meaningfully get a return value out of qemu, so we'll just grep its output for the success message.&lt;/p&gt;
&lt;p&gt;The first step is to check out the kernel sources, if we don't have them already, and build a kernel:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$&lt;span class="w"&gt; &lt;/span&gt;git&lt;span class="w"&gt; &lt;/span&gt;clone&lt;span class="w"&gt; &lt;/span&gt;https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable.git&lt;span class="w"&gt; &lt;/span&gt;linux
$&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;cd&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;linux
$&lt;span class="w"&gt; &lt;/span&gt;make&lt;span class="w"&gt; &lt;/span&gt;defconfig
$&lt;span class="w"&gt; &lt;/span&gt;make&lt;span class="w"&gt; &lt;/span&gt;-j8
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;which prints this after a while:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="n"&gt;Kernel&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;arch&lt;/span&gt;&lt;span class="sr"&gt;/x86/boot/&lt;/span&gt;&lt;span class="n"&gt;bzImage&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;is&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ready&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="mi"&gt;21&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Then make sure we can boot our new kernel with qemu, without an initrd:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$&lt;span class="w"&gt; &lt;/span&gt;qemu-system-x86_64&lt;span class="w"&gt; &lt;/span&gt;-nographic&lt;span class="w"&gt; &lt;/span&gt;-append&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;console&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;ttyS0&lt;span class="w"&gt; &lt;/span&gt;-kernel&lt;span class="w"&gt; &lt;/span&gt;arch/x86/boot/bzImage
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;That is, run it in text mode with the VM's serial console on standard input/output instead of trying to pop up a graphical window, and tell the kernel to use the serial port for console output. If your system supports it, you can add &lt;code&gt;-enable-kvm&lt;/code&gt; to make it a faster, although since we want to shut down the VM immediately once we run our test, it doesn't make a huge difference (2 seconds vs. 4 on my machine).&lt;/p&gt;
&lt;p&gt;This will panic, because we gave the kernel neither a root filesystem nor a working initrd. (You can kill the VM by typing Ctrl-A and then X.) So let's write an initrd with a single binary, &lt;code&gt;init&lt;/code&gt;. It needs to shut down the system, so we get back to our prompt:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$&lt;span class="w"&gt; &lt;/span&gt;mkdir&lt;span class="w"&gt; &lt;/span&gt;initrd
$&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;cd&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;initrd
$&lt;span class="w"&gt; &lt;/span&gt;cat&lt;span class="w"&gt; &lt;/span&gt;&amp;gt;&lt;span class="w"&gt; &lt;/span&gt;init.c&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;lt;&amp;lt; EOF&lt;/span&gt;
&lt;span class="s"&gt;#include &amp;lt;sys/reboot.h&amp;gt;&lt;/span&gt;
&lt;span class="s"&gt;#include &amp;lt;stdio.h&amp;gt;&lt;/span&gt;
&lt;span class="s"&gt;#include &amp;lt;unistd.h&amp;gt;&lt;/span&gt;

&lt;span class="s"&gt;int main(void) {&lt;/span&gt;
&lt;span class="s"&gt;        printf(&amp;quot;Hello world!\n&amp;quot;);&lt;/span&gt;
&lt;span class="s"&gt;        reboot(RB_POWER_OFF);&lt;/span&gt;
&lt;span class="s"&gt;}&lt;/span&gt;
&lt;span class="s"&gt;EOF&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;(Yes, the system call for shutting down the system is named "&lt;a href="http://man7.org/linux/man-pages/man2/reboot.2.html"&gt;reboot&lt;/a&gt;", because the name "&lt;a href="http://man7.org/linux/man-pages/man2/reboot.2.html"&gt;shutdown&lt;/a&gt;" was already used for the system call to close a socket. I guess early UNIX computers didn't support initiating a hardware poweroff from software, so the &lt;code&gt;shutdown&lt;/code&gt; &lt;em&gt;command&lt;/em&gt; would just stop all processes, sync and unmount disks, and print a message asking the operator to cut power.)&lt;/p&gt;
&lt;p&gt;Compile this program statically, so it's a single binary, put it in the particular form required for an initrd (a compressed cpio archive, an old but very simple format with a weird command-line tool) and make sure it's named &lt;code&gt;init&lt;/code&gt;, and then we can boot it up with qemu:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;cd&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;initrd
$&lt;span class="w"&gt; &lt;/span&gt;cc&lt;span class="w"&gt; &lt;/span&gt;-static&lt;span class="w"&gt; &lt;/span&gt;-o&lt;span class="w"&gt; &lt;/span&gt;init&lt;span class="w"&gt; &lt;/span&gt;init.c
$&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;init&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;cpio&lt;span class="w"&gt; &lt;/span&gt;-H&lt;span class="w"&gt; &lt;/span&gt;newc&lt;span class="w"&gt; &lt;/span&gt;-o&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;gzip&lt;span class="w"&gt; &lt;/span&gt;&amp;gt;&lt;span class="w"&gt; &lt;/span&gt;initrd.gz
&lt;span class="m"&gt;1621&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;blocks
$&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;cd&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;..
$&lt;span class="w"&gt; &lt;/span&gt;qemu-system-x86_64&lt;span class="w"&gt; &lt;/span&gt;-nographic&lt;span class="w"&gt; &lt;/span&gt;-append&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;console&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;ttyS0&lt;span class="w"&gt; &lt;/span&gt;-kernel&lt;span class="w"&gt; &lt;/span&gt;arch/x86/boot/bzImage&lt;span class="w"&gt; &lt;/span&gt;-initrd&lt;span class="w"&gt; &lt;/span&gt;initrd/initrd.gz
...
&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;.502593&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;ALSA&lt;span class="w"&gt; &lt;/span&gt;device&lt;span class="w"&gt; &lt;/span&gt;list:
&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;.502889&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="w"&gt;   &lt;/span&gt;No&lt;span class="w"&gt; &lt;/span&gt;soundcards&lt;span class="w"&gt; &lt;/span&gt;found.
&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;.503554&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;Freeing&lt;span class="w"&gt; &lt;/span&gt;unused&lt;span class="w"&gt; &lt;/span&gt;kernel&lt;span class="w"&gt; &lt;/span&gt;memory:&lt;span class="w"&gt; &lt;/span&gt;1088K&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;ffffffff81f2f000&lt;span class="w"&gt; &lt;/span&gt;-&lt;span class="w"&gt; &lt;/span&gt;ffffffff8203f000&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;.504262&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;Write&lt;span class="w"&gt; &lt;/span&gt;protecting&lt;span class="w"&gt; &lt;/span&gt;the&lt;span class="w"&gt; &lt;/span&gt;kernel&lt;span class="w"&gt; &lt;/span&gt;read-only&lt;span class="w"&gt; &lt;/span&gt;data:&lt;span class="w"&gt; &lt;/span&gt;14336k
&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;.505004&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;Freeing&lt;span class="w"&gt; &lt;/span&gt;unused&lt;span class="w"&gt; &lt;/span&gt;kernel&lt;span class="w"&gt; &lt;/span&gt;memory:&lt;span class="w"&gt; &lt;/span&gt;1680K&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;ffff88000185c000&lt;span class="w"&gt; &lt;/span&gt;-&lt;span class="w"&gt; &lt;/span&gt;ffff880001a00000&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;.505855&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;Freeing&lt;span class="w"&gt; &lt;/span&gt;unused&lt;span class="w"&gt; &lt;/span&gt;kernel&lt;span class="w"&gt; &lt;/span&gt;memory:&lt;span class="w"&gt; &lt;/span&gt;1340K&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;ffff880001cb1000&lt;span class="w"&gt; &lt;/span&gt;-&lt;span class="w"&gt; &lt;/span&gt;ffff880001e00000&lt;span class="o"&gt;)&lt;/span&gt;
Hello&lt;span class="w"&gt; &lt;/span&gt;world!
&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;.089618&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;input:&lt;span class="w"&gt; &lt;/span&gt;ImExPS/2&lt;span class="w"&gt; &lt;/span&gt;Generic&lt;span class="w"&gt; &lt;/span&gt;Explorer&lt;span class="w"&gt; &lt;/span&gt;Mouse&lt;span class="w"&gt; &lt;/span&gt;as&lt;span class="w"&gt; &lt;/span&gt;/devices/platform/i8042/serio1/input/input3
&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;.092997&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;ACPI:&lt;span class="w"&gt; &lt;/span&gt;Preparing&lt;span class="w"&gt; &lt;/span&gt;to&lt;span class="w"&gt; &lt;/span&gt;enter&lt;span class="w"&gt; &lt;/span&gt;system&lt;span class="w"&gt; &lt;/span&gt;sleep&lt;span class="w"&gt; &lt;/span&gt;state&lt;span class="w"&gt; &lt;/span&gt;S5
&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;.094083&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;reboot:&lt;span class="w"&gt; &lt;/span&gt;Power&lt;span class="w"&gt; &lt;/span&gt;down
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Great. We've built our own kernel, passed it a test binary to run, and got it booted in a qemu command that exits. This is turning into something we can pass to &lt;code&gt;git bisect run&lt;/code&gt;. Now it's time to write the actual test. Here's what I ultimately ended up with to track down my bug:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="nx"&gt;include&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;sys&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;types&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;h&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="nx"&gt;include&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;sys&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;socket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;h&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="nx"&gt;include&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;sys&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;h&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="nx"&gt;include&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;sys&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;reboot&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;h&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="nx"&gt;include&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;sys&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;ioctl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;h&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="nx"&gt;include&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;net&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;h&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="nx"&gt;include&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;netinet&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="k"&gt;in&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;h&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="nx"&gt;include&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;netinet&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;tcp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;h&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="nx"&gt;include&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;fcntl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;h&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="nx"&gt;include&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;stdio&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;h&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="nx"&gt;include&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;unistd&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;h&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="nx"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;main&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;void&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="cm"&gt;/* The problem I was tracing was only reproducible with syncookies&lt;/span&gt;
&lt;span class="cm"&gt;       disabled. While the initrd gets unpacked into a writable temporary&lt;/span&gt;
&lt;span class="cm"&gt;       filesystem, nothing exists yet, so if I need /proc, I need to create&lt;/span&gt;
&lt;span class="cm"&gt;       and mount it myself. */&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;getpid&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nx"&gt;mkdir&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;/proc&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nx"&gt;mount&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;proc&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;/proc&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;proc&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nx"&gt;char&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;buf&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;0\n&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nx"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;fd&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;/proc/sys/net/ipv4/tcp_syncookies&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;O_WRONLY&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nx"&gt;write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;fd&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;buf&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nx"&gt;close&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;fd&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nx"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;server&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;socket&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;AF_INET&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;SOCK_STREAM&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;IPPROTO_TCP&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="cm"&gt;/* Also, while a loopback ethernet device exist, it&amp;#39;s not&lt;/span&gt;
&lt;span class="cm"&gt;       enabled, so network tests won&amp;#39;t work. This code is equivalent&lt;/span&gt;
&lt;span class="cm"&gt;       to `ifconfig lo up`. */&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nx"&gt;struct&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;ifreq&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;ifreq&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ifr_name&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;lo&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nx"&gt;ioctl&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;server&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;SIOCGIFFLAGS&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nx"&gt;ifreq&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(!(&lt;/span&gt;&lt;span class="nx"&gt;ifreq&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ifr_flags&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;IFF_UP&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nx"&gt;ifreq&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ifr_flags&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;|=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;IFF_UP&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nx"&gt;ioctl&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;server&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;SIOCSIFFLAGS&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nx"&gt;ifreq&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nx"&gt;struct&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;sockaddr_in&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;addr&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;sin_family&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;AF_INET&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;sin_port&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;htons&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;54321&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;sin_addr&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;htonl&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;INADDR_LOOPBACK&lt;/span&gt;&lt;span class="p"&gt;)},&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nx"&gt;bind&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;server&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;struct&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;sockaddr&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="kd"&gt;addr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;sizeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;addr&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nx"&gt;listen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;server&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nx"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;socket&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;AF_INET&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;SOCK_STREAM&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;IPPROTO_TCP&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nx"&gt;struct&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;timeval&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;timeout&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nx"&gt;setsockopt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;SOL_SOCKET&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;SO_SNDTIMEO&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nx"&gt;timeout&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;sizeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;timeout&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;connect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;struct&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;sockaddr&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="kd"&gt;addr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;sizeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;addr&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nx"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;Success\n&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nx"&gt;perror&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;connect&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;getpid&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nx"&gt;reboot&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;RB_POWER_OFF&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Most of it is specific to the thing I was trying to test, but you may also need the code to create and mount &lt;code&gt;/proc&lt;/code&gt; or to enable &lt;code&gt;lo&lt;/code&gt;.  Also, I put a few things conditional on &lt;code&gt;getpid() == 1&lt;/code&gt; so that I could safely test the program on my host system, where it wasn't running as root and where I didn't want it powering anything off. (I ran it a few times under &lt;code&gt;strace&lt;/code&gt; to make sure it was doing what I expected it to do, and I didn't want to bother with getting &lt;code&gt;strace&lt;/code&gt; inside my initrd.)&lt;/p&gt;
&lt;p&gt;So I first made sure this is reproducible on a stock kernel by itself, isolated from any config my workplace might add:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$&lt;span class="w"&gt; &lt;/span&gt;qemu-system-x86_64&lt;span class="w"&gt; &lt;/span&gt;-nographic&lt;span class="w"&gt; &lt;/span&gt;-append&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;console&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;ttyS0&lt;span class="w"&gt; &lt;/span&gt;-kernel&lt;span class="w"&gt; &lt;/span&gt;arch/x86/boot/bzImage&lt;span class="w"&gt; &lt;/span&gt;-initrd&lt;span class="w"&gt; &lt;/span&gt;initrd/initrd.gz&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;grep&lt;span class="w"&gt; &lt;/span&gt;^Success
$&lt;span class="w"&gt; &lt;/span&gt;git&lt;span class="w"&gt; &lt;/span&gt;checkout&lt;span class="w"&gt; &lt;/span&gt;v4.1
$&lt;span class="w"&gt; &lt;/span&gt;make&lt;span class="w"&gt; &lt;/span&gt;defconfig&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;make&lt;span class="w"&gt; &lt;/span&gt;-j8
$&lt;span class="w"&gt; &lt;/span&gt;qemu-system-x86_64&lt;span class="w"&gt; &lt;/span&gt;-nographic&lt;span class="w"&gt; &lt;/span&gt;-append&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;console&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;ttyS0&lt;span class="w"&gt; &lt;/span&gt;-kernel&lt;span class="w"&gt; &lt;/span&gt;arch/x86/boot/bzImage&lt;span class="w"&gt; &lt;/span&gt;-initrd&lt;span class="w"&gt; &lt;/span&gt;initrd/initrd.gz&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;grep&lt;span class="w"&gt; &lt;/span&gt;^Success
Success
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Cool, it's definitely a regression somewhere between those versions. (The set of config options change from kernel version to kernel version, so across this wide of a range, the easiest thing is to just get the current kernel's default config - if you need custom config options, you might want to edit .config after running &lt;code&gt;make defconfig&lt;/code&gt; or something.) Now time to let &lt;code&gt;git bisect run&lt;/code&gt; do its thing:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$&lt;span class="w"&gt; &lt;/span&gt;git&lt;span class="w"&gt; &lt;/span&gt;bisect&lt;span class="w"&gt; &lt;/span&gt;start
$&lt;span class="w"&gt; &lt;/span&gt;git&lt;span class="w"&gt; &lt;/span&gt;bisect&lt;span class="w"&gt; &lt;/span&gt;bad&lt;span class="w"&gt; &lt;/span&gt;v4.9
$&lt;span class="w"&gt; &lt;/span&gt;git&lt;span class="w"&gt; &lt;/span&gt;bisect&lt;span class="w"&gt; &lt;/span&gt;good&lt;span class="w"&gt; &lt;/span&gt;v4.1
$&lt;span class="w"&gt; &lt;/span&gt;git&lt;span class="w"&gt; &lt;/span&gt;bisect&lt;span class="w"&gt; &lt;/span&gt;run&lt;span class="w"&gt; &lt;/span&gt;sh&lt;span class="w"&gt; &lt;/span&gt;-c&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;make defconfig &amp;amp;&amp;amp; make -j8 &amp;amp;&amp;amp; qemu-system-x86_64 -nographic -append console=ttyS0 -kernel arch/x86/boot/bzImage -initrd initrd/initrd.gz | grep ^Success&amp;#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;It started printing a bunch of build logs and I went to work on something else. About half an hour later (I expected it to take longer!), it prints this out:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="n"&gt;ef547f2ac16bd9d77a780a0e7c70857e69e8f23f&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;is&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;the&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;first&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;bad&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;commit&lt;/span&gt;
&lt;span class="n"&gt;commit&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ef547f2ac16bd9d77a780a0e7c70857e69e8f23f&lt;/span&gt;
&lt;span class="n"&gt;Author&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Eric&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Dumazet&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;edumazet&lt;/span&gt;&lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="n"&gt;google&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;com&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="n"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="n"&gt;Fri&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Oct&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;11&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;43&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;37&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2015&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;0700&lt;/span&gt;

&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;tcp&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;remove&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;max_qlen_log&lt;/span&gt;

&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;This&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;control&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;variable&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;was&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;set&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;at&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;first&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;listen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fd&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;backlog&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;call&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;but&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ow"&gt;not&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;updated&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;application&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;tried&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;to&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;increase&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ow"&gt;or&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;decrease&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;backlog&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;It&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;made&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;sense&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;at&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;the&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;listener&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;had&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;non&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;resizeable&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nb"&gt;hash&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;table&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;

&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;Also&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;rounding&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;to&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;powers&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;of&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;two&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;was&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ow"&gt;not&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;very&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;friendly&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;

&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;Signed&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;off&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;by&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Eric&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Dumazet&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;edumazet&lt;/span&gt;&lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="n"&gt;google&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;com&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;Signed&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;off&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;by&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;David&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;S&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Miller&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;davem&lt;/span&gt;&lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="n"&gt;davemloft&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;net&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="o"&gt;$&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;git&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;describe&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;contains&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ef547f2ac16bd9d77a780a0e7c70857e69e8f23f&lt;/span&gt;
&lt;span class="n"&gt;v4&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;rc1&lt;/span&gt;&lt;span class="o"&gt;~&lt;/span&gt;&lt;span class="mi"&gt;141&lt;/span&gt;&lt;span class="o"&gt;^&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;~&lt;/span&gt;&lt;span class="mi"&gt;238&lt;/span&gt;&lt;span class="o"&gt;^&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;~&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;which looks awfully relevant&amp;mdash;it implies they were previously rounding off the backlog. Looking at commit, we can see what happened: before kernel 4.4, &lt;a href="https://github.com/torvalds/linux/commit/ef547f2ac16bd9d77a780a0e7c70857e69e8f23f#diff-56ecfd3cd70d57cde321f395f0d8d743L44"&gt;the backlog argument was always capped to at least 8&lt;/a&gt;, and also rounded up to the next power of two. So &lt;code&gt;listen(fd, 0)&lt;/code&gt; was turning into &lt;code&gt;listen(fd, 8)&lt;/code&gt; on older kernels, and the program previously worked despite using &lt;code&gt;listen()&lt;/code&gt; incorrectly. This commit was actually somewhere in the &lt;code&gt;git log&lt;/code&gt; I was trying to read, but I must have scrolled past it.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;git reflog&lt;/code&gt; shows that &lt;code&gt;git bisect&lt;/code&gt; went through sixteen commits before settling on this one: it found this one on its 11th try, and then spent 5 more commits confirming that all the commits before this one were good. So I'm glad &lt;code&gt;git bisect run&lt;/code&gt; found this commit, and I'm especially glad it found it in half an hour unattended, without me having to manually compile and test sixteen kernels by hand.&lt;/p&gt;</content><category term="misc"></category></entry><entry><title>Hostnames and usernames to reserve</title><link href="https://ldpreload.com/blog/names-to-reserve" rel="alternate"></link><published>2015-11-26T00:00:00+00:00</published><updated>2015-11-26T00:00:00+00:00</updated><author><name>Geoffrey Thomas</name></author><id>tag:ldpreload.com,2015-11-26:/blog/names-to-reserve</id><summary type="html">&lt;p&gt;If you're setting up a service where people can register their own usernames to be used as a hostname (&lt;code&gt;username.example.com&lt;/code&gt;), email address (&lt;code&gt;username@example.com&lt;/code&gt;), or URL path (&lt;code&gt;example.com/username&lt;/code&gt;) within your domain, there are some common names you should avoid letting the general public register.&lt;/p&gt;
&lt;p&gt;Many …&lt;/p&gt;</summary><content type="html">&lt;p&gt;If you're setting up a service where people can register their own usernames to be used as a hostname (&lt;code&gt;username.example.com&lt;/code&gt;), email address (&lt;code&gt;username@example.com&lt;/code&gt;), or URL path (&lt;code&gt;example.com/username&lt;/code&gt;) within your domain, there are some common names you should avoid letting the general public register.&lt;/p&gt;
&lt;p&gt;Many Internet protocols make the assumption that a domain is manually managed by its owners, and in particular assume that a name like &lt;code&gt;admin&lt;/code&gt; must have been registered or approved by the actual owners. Automatic registration breaks this assumption, and has been the source of some attacks. Microsoft Live has fallen victim to this multiple times: in 2008, &lt;a href="http://www.theregister.co.uk/2011/04/11/state_of_ssl_analysis/"&gt;a researcher signed up for &lt;code&gt;sslcertificates@live.com&lt;/code&gt; and used it to get a login.live.com certificate&lt;/a&gt;, and as late as this March, the same problem happened to live.fi, the Finnish version of the service, when &lt;a href="http://www.tivi.fi/Kaikki_uutiset/2015-03-18/A-Finnish-man-created-this-simple-email-account---and-received-Microsofts-security-certificate-3217662.html"&gt;an IT professional tried registering the email account &lt;code&gt;hostmaster@live.fi&lt;/code&gt;&lt;/a&gt; as his personal Live account, and then found he could receive a certificate for that domain.&lt;/p&gt;
&lt;p&gt;This is a list of all the names I know that should be restricted from registration in automated systems. If you know of others, please let me know and I'll update this page.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;tl;dr:&lt;/strong&gt; Regardless of how you're currently using usernames, restrict them to lowercase letters, digits, and hyphens, starting with a letter and not ending with a hyphen (that is, &lt;code&gt;/^[a-z]([a-z0-9-]*[a-z0-9])?$/&lt;/code&gt; as an extended regex). Ban &lt;a href="https://ldpreload.com/files/names-to-reserve.txt"&gt;all the names in this file&lt;/a&gt; (last updated 2015-11-21). Get yourself listed as a public suffix: see below for directions and implications.&lt;/p&gt;
&lt;h2&gt;Hostnames&lt;/h2&gt;
&lt;p&gt;Most of these problems involve a computer on the domain doing an unqualified lookup: when a computer named &lt;code&gt;a.example.com&lt;/code&gt; looks for &lt;code&gt;b&lt;/code&gt;, it will usually find &lt;code&gt;b.example.com&lt;/code&gt;. If you're running a simple hosting service, or similar, you may not need to block all of these, but these names are extremely unlikely to be used by legitimate users anyway. So you may as well block all of them to allow expanding in the future.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;localhost&lt;/code&gt;&lt;/strong&gt;, &lt;strong&gt;&lt;code&gt;localdomain&lt;/code&gt;&lt;/strong&gt;, and &lt;strong&gt;&lt;code&gt;broadcasthost&lt;/code&gt;&lt;/strong&gt;: these are &lt;em&gt;usually&lt;/em&gt; present in &lt;code&gt;/etc/hosts&lt;/code&gt;, and applications or scripts might hard-code an assumption about them having their usual value (especially for &lt;code&gt;localhost&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;www&lt;/code&gt;&lt;/strong&gt;: Browsers will often prepend this if the domain itself does not resolve as a hostname.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;wpad&lt;/code&gt;&lt;/strong&gt;: &lt;a href="https://en.wikipedia.org/wiki/Web_Proxy_Autodiscovery_Protocol"&gt;Web Proxy Auto-Discovery&lt;/a&gt; in several browsers; someone who owns this (unqualified) name can act as a proxy for all web traffic.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;isatap&lt;/code&gt;&lt;/strong&gt;: &lt;a href="https://en.wikipedia.org/wiki/ISATAP"&gt;IPv6 tunnel autodiscovery&lt;/a&gt;, primarily on Windows. Similarly to WPAD, someone who owns this (unqualified) name can act as a proxy for all IPv6-capable traffic. Windows Server has a &lt;a href="https://technet.microsoft.com/en-us/library/cc794902.aspx"&gt;built-in blacklist of domain names&lt;/a&gt; that defaults to &lt;code&gt;WPAD&lt;/code&gt; and &lt;code&gt;ISATAP&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;autoconfig&lt;/code&gt;&lt;/strong&gt;: &lt;a href="https://wiki.mozilla.org/Thunderbird:Autoconfiguration"&gt;Thunderbird's spec for autoconfiguration&lt;/a&gt;. Thunderbird will query the website at &lt;code&gt;autoconfig.example.com&lt;/code&gt; for settings when attempting to set up &lt;code&gt;example.com&lt;/code&gt; email. Good way to harvest passwords.&lt;/li&gt;
&lt;li&gt;Along those lines, &lt;strong&gt;&lt;code&gt;imap&lt;/code&gt;&lt;/strong&gt;, &lt;strong&gt;&lt;code&gt;pop&lt;/code&gt;&lt;/strong&gt;, &lt;strong&gt;&lt;code&gt;pop3&lt;/code&gt;&lt;/strong&gt;, &lt;strong&gt;&lt;code&gt;smtp&lt;/code&gt;&lt;/strong&gt;, &lt;strong&gt;&lt;code&gt;mail&lt;/code&gt;&lt;/strong&gt;, for email clients that make guesses about what your email servers are. (This includes Thunderbird but also many others.)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Note that valid hostnames are &lt;a href="https://en.wikipedia.org/wiki/Hostname#Restrictions_on_valid_host_names"&gt;restricted in syntax&lt;/a&gt;: they must only contain letters, digits, or hyphens, and cannot start or end with a hyphen. DNS is case-insensitive, so make sure there are no case collisions. An older standard prevents hostnames from starting with a digit, which is a straightforward way to prevent all-numeric usernames (which can cause &lt;a href="https://debathena.mit.edu/trac/ticket/367"&gt;problems with tools that accept either names or UIDs&lt;/a&gt;). Dots separate portions of a domain name and cause various problems (wildcard certificates only apply to one level, &lt;code&gt;a.b.example.com&lt;/code&gt; can read and write cookies for &lt;code&gt;b.example.com&lt;/code&gt;, etc.), so they're usually more trouble than they're worth. &lt;em&gt;DNS records&lt;/em&gt; are much more liberal, but names that don't follow these rules will generally not resolve as hostnames: you can look them up with &lt;code&gt;dig&lt;/code&gt;/&lt;code&gt;host&lt;/code&gt;/etc., but you can't use them in applications. Checking hostname syntax also prevents you from worrying about names like &lt;strong&gt;&lt;code&gt;_tcp&lt;/code&gt;&lt;/strong&gt; or &lt;strong&gt;&lt;code&gt;_udp&lt;/code&gt;&lt;/strong&gt;, which are used in &lt;a href="https://en.wikipedia.org/wiki/SRV_record"&gt;SRV records&lt;/a&gt;.&lt;/p&gt;
&lt;h3&gt;Become a public suffix&lt;/h3&gt;
&lt;p&gt;Most parts of the web platform consider two pages with different &lt;em&gt;origins&lt;/em&gt;, that is, scheme (&lt;code&gt;http&lt;/code&gt; / &lt;code&gt;https&lt;/code&gt;), hostname, and port number, to be unrelated websites that cannot interact with each other by default. However, there are a few exceptions, most notably cookies. Web pages at &lt;code&gt;www.example.com&lt;/code&gt; and &lt;code&gt;login.example.com&lt;/code&gt; are allowed to set cookies with a scope of &lt;code&gt;example.com&lt;/code&gt;, despite not sharing the same hostname / origin. The simple rule of allowing parent domains created the problem of &lt;a href="https://en.wikipedia.org/wiki/HTTP_cookie#Supercookie"&gt;supercookies&lt;/a&gt;: &lt;code&gt;example.com&lt;/code&gt; could set a cookie scoped to &lt;code&gt;.com&lt;/code&gt;, which would then be sent to all sites ending in &lt;code&gt;.com&lt;/code&gt;. There are two big problems with this: the first is privacy (being tracked across websites), and the second is &lt;a href="https://en.wikipedia.org/wiki/Session_fixation#Attacks_using_cross-subdomain_cookie"&gt;session-fixation attacks&lt;/a&gt;, where an attacker can overwrite your session cookie with their own, and have your actions (including logging in or sending private data) happen within the attacker's session.&lt;/p&gt;
&lt;p&gt;The immediate fix was to ban top-level domains, but this still allowed setting cookies for publicly-registrable suffixes like &lt;code&gt;.co.uk&lt;/code&gt; that weren't at the top level. So browser vendors created the &lt;a href="https://publicsuffix.org/"&gt;public suffix list&lt;/a&gt; to track which suffixes are open for public registration. The public suffix list now includes not only "ICANN" entries, such as &lt;code&gt;.com&lt;/code&gt; and &lt;code&gt;.co.uk&lt;/code&gt;, but also "private" entries, such as &lt;code&gt;.herokuapp.com&lt;/code&gt; and &lt;code&gt;.github.io&lt;/code&gt;, since the same problems exist with allowing users to set cookies for all Heroku or GitHub Pages users.&lt;/p&gt;
&lt;p&gt;So, if you are letting users register hostnames in your domain, you should &lt;a href="https://publicsuffix.org/submit/"&gt;get it listed as a public suffix&lt;/a&gt;, which requires just sending a pull request or an email. It takes some time for the update to reach browsers (the list is compiled into browsers, so it's only updated by a browser version update), so you should try to do this as far in advance as possible before launching.&lt;/p&gt;
&lt;p&gt;Note that by making &lt;code&gt;example.com&lt;/code&gt; a public suffix, nobody, &lt;strong&gt;not even code on &lt;code&gt;example.com&lt;/code&gt; itself&lt;/strong&gt;, can set a cookie for &lt;code&gt;example.com&lt;/code&gt;. If you have a website of your own that needs cookies (analytics, registration, etc.), you'll need to run it at e.g. &lt;code&gt;www.example.com&lt;/code&gt;, and make &lt;code&gt;example.com&lt;/code&gt; just a redirect. Alternatively, you can use a completely separate domain for your own site vs. your users' sites, as with the Heroku and GitHub examples: their own websites are &lt;code&gt;heroku.com&lt;/code&gt; and &lt;code&gt;github.com&lt;/code&gt;.&lt;/p&gt;
&lt;h2&gt;Email addresses&lt;/h2&gt;
&lt;p&gt;The &lt;a href="https://cabforum.org/baseline-requirements-documents/"&gt;CA/Browser Forum Baseline Requirements&lt;/a&gt;, section 3.2.2.4 item 4, requires that if a CA is going to validate a domain by coming up with an administrative email address on its own, it may only use &lt;strong&gt;&lt;code&gt;admin&lt;/code&gt;&lt;/strong&gt;, &lt;strong&gt;&lt;code&gt;administrator&lt;/code&gt;&lt;/strong&gt;, &lt;strong&gt;&lt;code&gt;webmaster&lt;/code&gt;&lt;/strong&gt;, &lt;strong&gt;&lt;code&gt;hostmaster&lt;/code&gt;&lt;/strong&gt;, or &lt;strong&gt;&lt;code&gt;postmaster&lt;/code&gt;&lt;/strong&gt;. Reserve all of those names, regardless of whether they go somewhere useful.&lt;/p&gt;
&lt;p&gt;All CAs are supposed to be compliant with that these days, but for safety's sake, also reserve &lt;strong&gt;&lt;code&gt;root&lt;/code&gt;&lt;/strong&gt;, &lt;strong&gt;&lt;code&gt;info&lt;/code&gt;&lt;/strong&gt;, &lt;strong&gt;&lt;code&gt;ssladmin&lt;/code&gt;&lt;/strong&gt;, &lt;strong&gt;&lt;code&gt;ssladministrator&lt;/code&gt;&lt;/strong&gt;, &lt;strong&gt;&lt;code&gt;sslwebmaster&lt;/code&gt;&lt;/strong&gt;, &lt;strong&gt;&lt;code&gt;sysadmin&lt;/code&gt;&lt;/strong&gt;, &lt;strong&gt;&lt;code&gt;is&lt;/code&gt;&lt;/strong&gt;, &lt;strong&gt;&lt;code&gt;it&lt;/code&gt;&lt;/strong&gt;, and &lt;strong&gt;&lt;code&gt;mis&lt;/code&gt;&lt;/strong&gt; (see this &lt;a href="https://bugzilla.mozilla.org/show_bug.cgi?id=477783#c19"&gt;2009 comment on Mozilla's bug tracker&lt;/a&gt;).&lt;/p&gt;
&lt;p&gt;&lt;a href="https://tools.ietf.org/html/rfc2142"&gt;RFC 2142&lt;/a&gt; defines the names &lt;code&gt;info&lt;/code&gt;, &lt;strong&gt;&lt;code&gt;marketing&lt;/code&gt;&lt;/strong&gt;, &lt;strong&gt;&lt;code&gt;sales&lt;/code&gt;&lt;/strong&gt;, &lt;strong&gt;&lt;code&gt;support&lt;/code&gt;&lt;/strong&gt;, &lt;strong&gt;&lt;code&gt;abuse&lt;/code&gt;&lt;/strong&gt;, &lt;strong&gt;&lt;code&gt;noc&lt;/code&gt;&lt;/strong&gt;, &lt;strong&gt;&lt;code&gt;security&lt;/code&gt;&lt;/strong&gt;, &lt;code&gt;postmaster&lt;/code&gt;, &lt;code&gt;hostmaster&lt;/code&gt;, &lt;strong&gt;&lt;code&gt;usenet&lt;/code&gt;&lt;/strong&gt;, &lt;strong&gt;&lt;code&gt;news&lt;/code&gt;&lt;/strong&gt;, &lt;code&gt;webmaster&lt;/code&gt;, &lt;code&gt;www&lt;/code&gt;, &lt;strong&gt;&lt;code&gt;uucp&lt;/code&gt;&lt;/strong&gt;, and &lt;strong&gt;&lt;code&gt;ftp&lt;/code&gt;&lt;/strong&gt;. You won't need most of these to actually reach a useful mailbox, though you should reserve all of them.&lt;/p&gt;
&lt;p&gt;You may want to reserve &lt;strong&gt;&lt;code&gt;mailer-daemon&lt;/code&gt;&lt;/strong&gt;, &lt;strong&gt;&lt;code&gt;nobody&lt;/code&gt;&lt;/strong&gt; (a default UNIX user account), &lt;strong&gt;&lt;code&gt;noreply&lt;/code&gt;&lt;/strong&gt;, &lt;strong&gt;&lt;code&gt;no-reply&lt;/code&gt;&lt;/strong&gt;, etc. for automated processes that send email.&lt;/p&gt;
&lt;p&gt;Again, as these names are unlikely to be used by legitimate users, it's usually worth blocking them now and keeping your options open, even if you're not currently offering email service. You may add an email service in the future (Amazon launched &lt;a href="http://www.amazon.com/gp/sendtokindle/email"&gt;Send to Kindle by email&lt;/a&gt; over a decade after introducing user accounts). As always, you can &lt;em&gt;manually&lt;/em&gt; register these names to trusted or internal users.&lt;/p&gt;
&lt;h2&gt;URLs&lt;/h2&gt;
&lt;p&gt;For many websites with user-provided content, like Twitter, Facebook, or GitHub, user-chosen usernames become part of the URL at top level (&lt;code&gt;https://twitter.com/geofft&lt;/code&gt;, &lt;code&gt;https://github.com/geofft&lt;/code&gt;). If you're building a website like this, the easiest approach is to restrict these usernames as if they were hostnames. This has two advantages: the first is that it's easy to launch a hostname-based system later (e.g. GitHub Pages now supports &lt;code&gt;geofft.github.io&lt;/code&gt;) if you know that all your usernames are valid hostnames.&lt;/p&gt;
&lt;p&gt;The second is that there are several URL paths you need to reserve at top level, and all of them happen to contain dots and are therefore invalid hostnames. If you do permit dots, you need to block the following names:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;robots.txt&lt;/code&gt;&lt;/strong&gt;, for the &lt;a href="http://www.robotstxt.org/"&gt;Robots Exclusion Protocol&lt;/a&gt;, used to tell well-behaved crawlers how to well-behave.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;favicon.ico&lt;/code&gt;&lt;/strong&gt;, for the &lt;a href="https://en.wikipedia.org/wiki/Favicon"&gt;shortcut icon&lt;/a&gt; displayed in the tab bar and other places.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;crossdomain.xml&lt;/code&gt;&lt;/strong&gt;, which allows &lt;a href="https://www.adobe.com/devnet/adobe-media-server/articles/cross-domain-xml-for-streaming.html"&gt;the Flash plugin to make cross-origin requests&lt;/a&gt;. Java and Silverlight also look for and trust &lt;code&gt;crossdomain.xml&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;clientaccesspolicy.xml&lt;/code&gt;&lt;/strong&gt;, a &lt;a href="https://msdn.microsoft.com/library/cc197955(v=vs.95).aspx"&gt;Silverlight-specific version&lt;/a&gt; of &lt;code&gt;crossdomain.xml&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;.well-known&lt;/code&gt;&lt;/strong&gt;, specified in &lt;a href="https://tools.ietf.org/html/rfc5785"&gt;RFC 5785&lt;/a&gt; as a place for these sorts of things so they don't keep cluttering the root level. Thunderbird autoconfiguration looks in here, as do &lt;a href="https://tools.ietf.org/html/draft-barnes-acme-04"&gt;ACME&lt;/a&gt;, the automatic certificate enrollment spec from &lt;a href="https://letsencrypt.org"&gt;Let's Encrypt&lt;/a&gt;; &lt;a href="https://github.com/mozilla/id-specs/blob/prod/browserid/index.md"&gt;BrowserID&lt;/a&gt; / Mozilla Persona; and &lt;a href="http://tools.ietf.org/html/rfc7711"&gt;RFC 7711&lt;/a&gt;, a new standard for providing certificates for third-party non-HTTP services. So there are a number of security issues with an unauthorized user being able to create files under &lt;code&gt;/.well-known/&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;(These are URLs, not filenames. You should of course also disallow users from creating files named e.g. &lt;code&gt;.htaccess&lt;/code&gt; if your web server respects those.)&lt;/p&gt;
&lt;p&gt;All of these are invalid hostnames, so simply requiring usernames to be valid hostnames avoids having to check for these specific cases. If you're only allowing users to choose some portion of the URL, and inserting other text (e.g., &lt;code&gt;example.com/user/geofft&lt;/code&gt;, &lt;code&gt;example.edu/~geofft&lt;/code&gt;), then you don't have to worry about this, but again it may still be useful to keep your options open for other URL, hostname, or email schemes in the future.&lt;/p&gt;
&lt;p&gt;Do not allow users to publish custom HTML, &lt;em&gt;especially&lt;/em&gt; not custom scripts, at these sorts of URLs. &lt;code&gt;https://example.com/user1&lt;/code&gt;, &lt;code&gt;https://example.com/user2&lt;/code&gt;, and &lt;code&gt;https://example.com/login&lt;/code&gt; all share the same origin, so by the &lt;a href="https://developer.mozilla.org/en-US/docs/Web/Security/Same-origin_policy"&gt;same-origin policy&lt;/a&gt;, these web pages can freely interact with each other and mess with each other's content. A few JavaScript interfaces, including &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Service_Worker_API"&gt;service workers&lt;/a&gt;, make it very easy to attack another site on the same origin. If you want users to be able to publish custom HTML and JS, use separate hostnames within a public suffix. &lt;code&gt;https://user1.example.com&lt;/code&gt; and &lt;code&gt;https://user2.example.com&lt;/code&gt; are separate origins, and if you have made &lt;code&gt;example.com&lt;/code&gt; a public suffix as mentioned earlier, you can safely let them publish custom scripts, since the sites are no more able to interact with each other than two separate &lt;code&gt;.com&lt;/code&gt; websites could.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;This post was inspired by &lt;a href="https://github.com/sandstorm-io/sandcats/issues/43"&gt;a GitHub issue&lt;/a&gt; for &lt;a href="https://docs.sandstorm.io/en/latest/administering/sandcats/"&gt;Sandstorm's sandcats.io dynamic DNS service&lt;/a&gt;; thanks to &lt;a href="http://asheesh.org"&gt;Asheesh Laroia&lt;/a&gt; for pointing me at that thread and reviewing a draft of this article.&lt;/em&gt;&lt;/p&gt;</content><category term="misc"></category></entry><entry><title>Smashing the heap by overflowing the stack</title><link href="https://ldpreload.com/blog/stack-smashes-you" rel="alternate"></link><published>2015-07-06T00:00:00+00:00</published><updated>2015-07-06T00:00:00+00:00</updated><author><name>Geoffrey Thomas</name></author><id>tag:ldpreload.com,2015-07-06:/blog/stack-smashes-you</id><summary type="html">&lt;p&gt;I ran across something strange while learning about Rust's stack overflow and segmentation fault handling.&lt;/p&gt;
&lt;p&gt;First, some backstory: in the past, Rust (and Go) used segmented stacks, also known as &lt;a href="https://gcc.gnu.org/wiki/SplitStacks"&gt;split stacks&lt;/a&gt;. This is a scheme that allows you to start each thread with a small amount of stack space …&lt;/p&gt;</summary><content type="html">&lt;p&gt;I ran across something strange while learning about Rust's stack overflow and segmentation fault handling.&lt;/p&gt;
&lt;p&gt;First, some backstory: in the past, Rust (and Go) used segmented stacks, also known as &lt;a href="https://gcc.gnu.org/wiki/SplitStacks"&gt;split stacks&lt;/a&gt;. This is a scheme that allows you to start each thread with a small amount of stack space, and dynamically allocate a new, discontiguous chunk of stack space when you run out. Each function starts with a call to &lt;code&gt;__morestack&lt;/code&gt; to see if it has enough stack space for that function's variables. If not, &lt;code&gt;__morestack&lt;/code&gt; is supposed to allocate more space, quietly switch out the stack pointer, and call the function. When the function returns, &lt;code&gt;__morestack&lt;/code&gt; frees the additional space and restores the original stack pointer. For a system like pre-1.0 Rust's tasks or Go's &lt;a href="https://tour.golang.org/concurrency/1"&gt;goroutines&lt;/a&gt;, allocating lots of tiny, growable stacks makes sense.&lt;/p&gt;
&lt;p&gt;However, Rust's &lt;code&gt;__morestack&lt;/code&gt; function currently only &lt;a href="https://github.com/rust-lang/rust/blob/1.0.0/src/rt/arch/i386/morestack.S"&gt;serves to trigger stack-overflow handling&lt;/a&gt;: the only thing that it does, besides aligning the stack properly, is call the &lt;code&gt;rust_stack_exhausted&lt;/code&gt; function, which prints an error message and exits. Rust gives each thread plenty of stack space, so if it overflows, it probably means there's unbounded recursion and the thread should be terminated.&lt;/p&gt;
&lt;p&gt;I thought this was a little odd. When you overflow the stack in C, or in any other language without &lt;code&gt;__morestack&lt;/code&gt;, the next instruction tries to access unallocated memory. This causes a standard segmentation fault, which terminates the program. What's the need for Rust to catch this and terminate the program on its own?&lt;/p&gt;
&lt;p&gt;Part of the answer is to provide a &lt;a href="https://github.com/rust-lang/rust/issues/26458#issuecomment-113804288"&gt;better error message&lt;/a&gt;. A straightforward stack overflow is not a memory safety violation in the same way an access to out-of-bounds memory is, so a segmentation fault is the wrong way to report a stack overflow. But the real answer turns out to be subtler than that. While accessing an invalid page of memory cannot cause data corruption, it's not guaranteed that the page is in fact invalid! With enough luck, you can overflow the stack far enough and reach into a completely unrelated memory region.&lt;/p&gt;
&lt;p&gt;It turns out that this is possible in well-defined C, in a worrisomely straightforward way. The following program generates no warnings:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="cp"&gt;#include&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="cpf"&gt;&amp;lt;stdint.h&amp;gt;&lt;/span&gt;
&lt;span class="cp"&gt;#include&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="cpf"&gt;&amp;lt;stdio.h&amp;gt;&lt;/span&gt;
&lt;span class="cp"&gt;#include&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="cpf"&gt;&amp;lt;stdlib.h&amp;gt;&lt;/span&gt;

&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;clobber&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;uintptr_t&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;target_address&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dummy&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="kt"&gt;uintptr_t&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;dummy_address&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;uintptr_t&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;dummy&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="kt"&gt;char&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;array&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;dummy_address&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;target_address&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;array&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="sc"&gt;&amp;#39;x&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;array&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// suppress warning about unused variable&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;malloc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;sizeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;clobber&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="kt"&gt;uintptr_t&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;%d &amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;and produces this output on my computer (an x86-64 machine running Debian GNU/Linux 8):&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="n"&gt;geofft&lt;/span&gt;&lt;span class="nv"&gt;@titan&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;tmp&lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;gcc&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Wall&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Wextra&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Wpedantic&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;c99&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;o&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;lol&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;stacks&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;lol&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;stacks&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;
&lt;span class="n"&gt;geofft&lt;/span&gt;&lt;span class="nv"&gt;@titan&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;tmp&lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;lol&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;stacks&lt;/span&gt;
&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;7864323&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;What's going on? We create a variable on the stack called &lt;code&gt;dummy&lt;/code&gt;, to figure out where our stack is. Then we figure out how far we are from the target address and create a giant array of exactly that size. Now the end of the stack lines up, more or less, with the target address. The process of "creating an array" doesn't involve any actual changes to memory, just changes to the interpretation of memory (and usually updating the stack pointer register), so while there's a wide swath of invalid memory between &lt;code&gt;&amp;amp;dummy&lt;/code&gt; and &lt;code&gt;target&lt;/code&gt;, none of it is accessed. Therefore, because the only access is to a valid memory location, there's no segmentation fault generated, and the change to memory goes through. When the program writes to &lt;code&gt;array&lt;/code&gt;, it finds valid, writable memory at that location&amp;mdash;namely, one of the elements in the target array &lt;code&gt;x&lt;/code&gt;. (Remember that on x86 machines, the stack grows downwards, towards lower-valued addresses, so &lt;code&gt;array[0]&lt;/code&gt; is the end of the stack. On other architectures, if the stack grows upwards, we'd need to write to the other end of &lt;code&gt;array&lt;/code&gt;.)&lt;/p&gt;
&lt;p&gt;As you might expect with memory corruption, this is exploitable. In 2010, Rafal Wojtczuk, a researcher at &lt;a href="http://www.invisiblethingslab.com/"&gt;Invisible Things Lab&lt;/a&gt;, discovered that this sort of confusion could be used in a &lt;a href="http://www.invisiblethingslab.com/resources/misc-2010/xorg-large-memory-attacks.pdf"&gt;privilege-escalation exploit against the X server (PDF)&lt;/a&gt;. A client can cause the X server to exhaust most of its memory, request a shared-memory region that gets mapped right past the stack, and then trigger a recursive function in the X server. As the &lt;a href="http://theinvisiblethings.blogspot.com/2010/08/skeletons-hidden-in-linux-closet.html"&gt;associated blog post&lt;/a&gt; puts it, it "exploits a bug in... well, actually it doesn't exploit any concrete bug, which makes it so much more interesting."&lt;/p&gt;
&lt;p&gt;How can we defend against this? The X server vulnerability (CVE-2010-2240) relied on the stack running right up against mapped pages, so the straightforward solution was to ensure that an unmapped guard page is always just past the end of the stack. But this doesn't help for more complicated cases that span more than a single page&amp;mdash;like my example above, or even a less-contrived function with a 5000-byte string buffer.&lt;/p&gt;
&lt;p&gt;It turns out that &lt;a href="https://gcc.gnu.org/onlinedocs/gcc/Code-Gen-Options.html"&gt;GCC has an option&lt;/a&gt;, &lt;code&gt;-fstack-check&lt;/code&gt;, that inserts code to check for this problem. If I recompile my program with &lt;code&gt;-fstack-check&lt;/code&gt;, I get a segmentation fault. It appears that gcc has inserted code to step the stack down one page at a time, running a logical-OR with zero at each point, which doesn't affect any value on the stack but forces a memory access. Here's the disassembly of that section of code, from GDB:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;   0x0000000000400621 &amp;lt;+139&amp;gt;:   mov    %rsp,%rcx
   0x0000000000400624 &amp;lt;+142&amp;gt;:   sub    %rdx,%rcx
   0x0000000000400627 &amp;lt;+145&amp;gt;:   cmp    %rcx,%rsp
   0x000000000040062a &amp;lt;+148&amp;gt;:   je     0x40063a &amp;lt;clobber+164&amp;gt;
   0x000000000040062c &amp;lt;+150&amp;gt;:   sub    $0x1000,%rsp
=&amp;gt; 0x0000000000400633 &amp;lt;+157&amp;gt;:   orq    $0x0,(%rsp)
   0x0000000000400638 &amp;lt;+162&amp;gt;:   jmp    0x400627 &amp;lt;clobber+145&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The size of my variable-length array has already been computed in &lt;code&gt;%rdx&lt;/code&gt;. GCC has inserted code to step through the stack one page (&lt;code&gt;$0x1000&lt;/code&gt; bytes) at a time, in a loop. At each step, it ORs the value at the stack pointer with zero, which doesn't change any data but forces a read and write of memory.&lt;/p&gt;
&lt;p&gt;Why isn't this the default, like other safety mechanisms like &lt;code&gt;-fstack-protector&lt;/code&gt;? I don't know for sure. Part of the answer could be performance, since each somewhat large stack allocation will result in this code being run&amp;mdash;with overhead linear in the size of the allocation, instead of just a single change to the stack pointer&amp;mdash;but I'm not sure if anyone expects large stack allocations to be performant. Another answer could be lack of interest, since GCC doesn't even enable it by default &lt;a href="https://gcc.gnu.org/bugzilla/show_bug.cgi?id=34118"&gt;when compiling Ada code&lt;/a&gt;, even though the Ada language requires that stack overflows and segmentation faults be distinct errors.&lt;/p&gt;
&lt;p&gt;This technique is common on Windows. &lt;a href="https://support.microsoft.com/en-us/kb/100775"&gt;Microsoft's rationale for stack checking&lt;/a&gt; is less about preventing unexpected changes to memory and more about making sure the stack is actually in place. Windows places a single guard page past the end of the stack, which is reserved in the memory map, but causes a fault when accessed. The kernel takes this as an indication that the process needs more stack space, and will allocate more physical pages, provided that resource limits allow it and there's enough free RAM. Then it moves the guard page past the new end of the stack. So, if your program has an object that is even slightly more than the page size (e.g., a &lt;code&gt;char buffer[5000]&lt;/code&gt;), it's important that the guard page get touched, instead of skipped over. (Linux also uses a similar mechanism, but as far as I can tell, the entire possible stack region is treated as guard pages, so the problem of skipping over a single guard page doesn't arise.)&lt;/p&gt;
&lt;p&gt;Rust is looking at moving away from the &lt;code&gt;__morestack&lt;/code&gt; approach to this approach, under the name of &lt;a href="https://github.com/rust-lang/rust/issues/16012"&gt;stack probes&lt;/a&gt; (the term "probe" is also used in GCC documentation). Apparently the right name for this technique is &lt;a href="http://lists.cs.uiuc.edu/pipermail/llvmdev/2014-August/075331.html"&gt;a bit of a question&lt;/a&gt;. "Stack checking," as Microsoft and GCC call it, is a somewhat generic name, and I imagine many developers would interpret it as referring to the &lt;a href="https://lwn.net/Articles/584225/"&gt;more typical direction of stack protection&lt;/a&gt;. Indeed, I was very surprised to see that the first C program above "worked", clobbering memory, even with &lt;code&gt;-fstack-protector&lt;/code&gt;. It's common to see stack-smashing attacks, where an out-of-bounds pointer overwrites something valuable on the stack, and that's what &lt;code&gt;-fstack-protector&lt;/code&gt; (StackGuard, which uses &lt;a href="https://en.wikipedia.org/wiki/Buffer_overflow_protection#Canaries"&gt;stack canaries&lt;/a&gt;) protects against. But it's not as common to see the inverse problem, where an out-of-bounds stack pointer overwrite something elsewhere in memory, which can be just as unsafe and just as much of a security risk.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Thanks to &lt;a href="https://nelhage.com"&gt;Nelson Elhage&lt;/a&gt;, &lt;a href="https://lizdenys.com"&gt;Liz Denys&lt;/a&gt;, Alex Dehnert, and &lt;a href="http://www.asheesh.org/"&gt;Asheesh Laroia&lt;/a&gt; for feedback on drafts of this post.&lt;/em&gt;&lt;/p&gt;</content><category term="misc"></category></entry><entry><title>signalfd is useless</title><link href="https://ldpreload.com/blog/signalfd-is-useless" rel="alternate"></link><published>2015-05-17T00:00:00+00:00</published><updated>2015-05-17T00:00:00+00:00</updated><author><name>Geoffrey Thomas</name></author><id>tag:ldpreload.com,2015-05-17:/blog/signalfd-is-useless</id><summary type="html">&lt;p&gt;UNIX (well, POSIX) signals are probably one of the worst parts of the UNIX API, and that’s a relatively high bar. A signal can be sent to your program at any point when it’s running, and you have to deal with it somehow. Traditionally, there are three ways …&lt;/p&gt;</summary><content type="html">&lt;p&gt;UNIX (well, POSIX) signals are probably one of the worst parts of the UNIX API, and that’s a relatively high bar. A signal can be sent to your program at any point when it’s running, and you have to deal with it somehow. Traditionally, there are three ways of responding to signals (“dispositions”): you can let the default behavior run, which is often to kill the program; you can ignore it; or you can set up a function to be a signal handler.&lt;/p&gt;
&lt;p&gt;If you register a signal handler, it’s called in the middle of whatever code you happen to be running. This sets up some very onerous restrictions on what a signal handler can do: it can’t assume that any locks are unlocked, any complex data structures are in a reliable state, etc. The restrictions are &lt;em&gt;stronger&lt;/em&gt; than the restrictions on thread-safe code, since the signal handler interrupts and &lt;em&gt;stops&lt;/em&gt; the original code from running. So, for instance, it can’t even wait on a lock, because the code that’s holding the lock is paused until the signal handler completes. This means that a lot of convenient functions, including the &lt;code&gt;stdio&lt;/code&gt; functions, &lt;code&gt;malloc&lt;/code&gt;, etc., are unusable from a signal handler, because they take locks internally. POSIX defines a set of “Async-Signal-Safe” functions that are guaranteed not to rely on locks or non-atomic data structures (because a signal handler could be called between two instructions that update a non-atomic data type). &lt;a href="http://man7.org/linux/man-pages/man7/signal.7.html"&gt;Linux’s &lt;code&gt;signal(7)&lt;/code&gt; manual page&lt;/a&gt; documents has a list of these functions. But because of the constrained environment, one common approach is to defer the actual work until you’re no longer running in a signal handler. A standard solution is the &lt;a href="http://cr.yp.to/docs/selfpipe.html"&gt;“self-pipe trick”&lt;/a&gt;: open an unnamed pipe, write a byte to it in your signal handler and return, and read from it in the main loop. This makes signal handling resemble the handling of anything else that’s a file descriptor, like network sockets, which normalizes their handling a bit.&lt;/p&gt;
&lt;p&gt;There’s another problem with signal handlers: in addition to interrupting user code, they also need to interrupt &lt;em&gt;kernel&lt;/em&gt; code so that it gets delivered. So, if you’re in the middle of reading from a network socket, waiting for a timeout, or even &lt;a href="http://www.daemonology.net/blog/2011-12-17-POSIX-close-is-broken.html"&gt;closing a file descriptor&lt;/a&gt;, that system call gets aborted so that the signal handler can run. By default, once you exit the signal handler, your system call will appear to return early, with an error exit of &lt;code&gt;errno == EINTR&lt;/code&gt; (“Interrupted system call”). The intention is that you can &lt;a href="http://250bpm.com/blog:12"&gt;restart the call yourself if you want&lt;/a&gt;, but in practice, very few libraries do, which causes &lt;a href="http://stackoverflow.com/questions/5360644/sysread-interrupted-system-call-errnoeintr-when-using-ruby-and-mysql"&gt;confusing errors for application developers&lt;/a&gt;. (Extra credit: explain why the linked solution is wrong.) To avoid these sorts of problems, BSD added a mechanism to mark signal handlers as restartable, which was standardized as the &lt;code&gt;SA_RESTART&lt;/code&gt; flag to the &lt;code&gt;sigaction&lt;/code&gt; system call. But that does not reliably cause system calls to continue instead of returning &lt;code&gt;EINTR&lt;/code&gt;: as documented &lt;a href="http://man7.org/linux/man-pages/man7/signal.7.html"&gt;later in &lt;code&gt;signal(7)&lt;/code&gt;&lt;/a&gt;, Linux will return &lt;code&gt;EINTR&lt;/code&gt; in some cases even when a system call is interrupted by an &lt;code&gt;SA_RESTART&lt;/code&gt; handler. (The rationale for many of these makes sense&amp;mdash;e.g., timeouts where restarting the call would start a timer from zero&amp;mdash;but understanding the problem doesn’t make it any less of a problem.)&lt;/p&gt;
&lt;p&gt;So, in 2007, Linux gained an API called &lt;a href="http://man7.org/linux/man-pages/man2/signalfd.2.html"&gt;&lt;code&gt;signalfd&lt;/code&gt;&lt;/a&gt;, which lets you create a file descriptor that notifies on signals. The idea is that you can avoid the complexity of the self-pipe trick, as well as any problems with &lt;code&gt;EINTR&lt;/code&gt;, by just asking the kernel to send you signals via a file descriptor in the first place. You don’t need to register a signal handler, so everything works perfectly… except that &lt;code&gt;signalfd&lt;/code&gt; doesn’t actually change how signal dispositions work. If you only create a &lt;code&gt;signalfd&lt;/code&gt;, signals still get delivered via the the signal-handling mechanism, so in order to actually get the signal to get delivered over the file descriptor, you need to suspend normal processing of the system. There’s another part of the signal API that lets you set a mask to block the signal: the intention is that you can remove the mask later, and then pending signals will get delivered. But this also means that pending signals are readable from the signalfd, and they’re removed from the queue once read.&lt;/p&gt;
&lt;p&gt;This would work fine if signal masks applied only to your current process, but they also get inherited to children. So if you’re masking a signal like &lt;code&gt;SIGINT&lt;/code&gt; in order to receive it via &lt;code&gt;signalfd&lt;/code&gt;, and you run a subprocess, then that child process will start up with &lt;code&gt;SIGINT&lt;/code&gt; masked. And while programs &lt;em&gt;could&lt;/em&gt; reset their own signal masks when they start up, in practice, no software does. So you have to be very careful to reset any masked signals before starting a child process, and unfortunately you need to do this yourself: &lt;a href="https://lwn.net/Articles/415684/"&gt;most ways of starting child processes&lt;/a&gt;, including &lt;a href="https://github.com/carllerche/mio/issues/16#issuecomment-102151151"&gt;the standard libc &lt;code&gt;system(3)&lt;/code&gt; function&lt;/a&gt;, do not reset handlers or masks.&lt;/p&gt;
&lt;p&gt;There’s another problem with masking signals, which is that standard UNIX signals are permitted to coalesce when they queue. Namely, if you have a mask that’s blocking a signal, and that signal gets delivered twice before you proces the first one from the queue, it only gets reported to you once. For something like &lt;code&gt;SIGINT&lt;/code&gt;, this might be okay: probably you don’t need to handle multiple Ctrl-C keystrokes differently from a single one. For something like &lt;code&gt;SIGCHLD&lt;/code&gt;, which notifies you that a child process has terminated, this is quite a bit more unfortunate. It now means that you know that &lt;em&gt;at least one&lt;/em&gt; child process has terminated. And while signals can have associated info (via the &lt;code&gt;SA_SIGINFO&lt;/code&gt; flag to &lt;code&gt;sigaction&lt;/code&gt;, or by default for &lt;code&gt;signalfd&lt;/code&gt;), and &lt;code&gt;SIGCHLD&lt;/code&gt;’s siginfo tells you which process has terminated, if it gets coalesced, you only get one set of info. That is, you know that the specified child process has terminated, but also one or more other unspecified child processes could have terminated and &lt;em&gt;the information about which one has been lost&lt;/em&gt;. Not only does this apply to unmasking signals and letting them get delivered to a normal signal handler, it also applies to reading signals from a &lt;code&gt;signalfd&lt;/code&gt;, since &lt;code&gt;signalfd&lt;/code&gt; works by dequeuing signals.&lt;/p&gt;
&lt;p&gt;It turns out that there is, at least in theory, a better way to handle this. Just go back to the old self-pipe trick, but install the handler with the &lt;code&gt;SA_NODEFER&lt;/code&gt; flag, which allows signal handlers to interrupt themselves. &lt;s&gt;This way you reliably get one handler called per signal.&lt;/s&gt; [&lt;strong&gt;EDIT:&lt;/strong&gt; This is wrong, see below.] This brings back the &lt;code&gt;EINTR&lt;/code&gt; problem, but there’s a simple solution to that: simply dedicate a separate thread to signal handling, and make sure all signals get routed there. Then no system calls on any other thread will get interrupted. The only way to ensure this is to mask signals on every &lt;em&gt;other&lt;/em&gt; thread, but that’s no worse than the status quo with &lt;code&gt;signalfd&lt;/code&gt;, since we already had to mask signals in order to get them delivered to &lt;code&gt;signalfd&lt;/code&gt; alone. As a bonus, this is portable to other operating systems that don’t have &lt;code&gt;signalfd&lt;/code&gt;, so this is the solution I’m planning on implementing for the &lt;a href="https://github.com/carllerche/mio"&gt;MIO&lt;/a&gt; cross-platform event-handling library for Rust.&lt;/p&gt;
&lt;p&gt;Can &lt;code&gt;signalfd&lt;/code&gt; be fixed? I think it can, if we explicitly tie &lt;code&gt;signalfd&lt;/code&gt; into the signal-disposition mechanism. If &lt;code&gt;signalfd&lt;/code&gt; could claim responsibility for signal delivery, instead of requiring that signals be masked or ignored in addition to using &lt;code&gt;signalfd&lt;/code&gt;, this would solve both problems. For inheritance, just set the close-on-exec flag on the signalfd, and signals will go back to the default behavior in child processes, once the fd no longer exists. For multiple delivery, because &lt;code&gt;signalfd&lt;/code&gt; no longer interacts with signal queueing, it can just be specfied to send one message per signal. Alternatively, a mechanism to mask or ignore a signal that applies to the current process only would also be an improvement. These proposals would be a change to POSIX signal semantics, but fundamentally so is &lt;code&gt;signalfd&lt;/code&gt;, and the only way to get clean handling of signals is to avoid the POSIX API, not work within it.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;EDIT:&lt;/strong&gt; Greg Hudson pointed out to me that even traditional handlers can coalesce signals. If a signal is sent twice before the signal-handling thread is scheduled, it still gets coalesced, even if it's destined for a signal handler with &lt;code&gt;SA_NODEFER&lt;/code&gt;. So while a signal-handling thread can get you separate siginfo most of the time, it still can’t do so reliably. I’ve written an &lt;a href="https://ldpreload.com/p/blog/coalesced-signals.c"&gt;example of this behavior&lt;/a&gt; that uses &lt;code&gt;vfork&lt;/code&gt; to prevent the process from being scheduled: it starts multiple children, but only prints one notification. So my claim that there’s a better alternative to &lt;code&gt;signalfd&lt;/code&gt; is wrong, but it’s still true that &lt;code&gt;signalfd&lt;/code&gt; doesn’t solve any of the other troubles with signal handling: it just saves you a separate thread.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Thanks to Nelson Elhage for pointing me at the LWN article, and Alex Chernyakhovsky, David Benjamin, and Yehuda Katz for discussions about all the unfortunate parts of signal handling.&lt;/em&gt;&lt;/p&gt;</content><category term="misc"></category></entry><entry><title>Testing NSS modules in glibc</title><link href="https://ldpreload.com/blog/testing-glibc-nsswitch" rel="alternate"></link><published>2015-04-18T00:00:00+00:00</published><updated>2015-04-18T00:00:00+00:00</updated><author><name>Geoffrey Thomas</name></author><id>tag:ldpreload.com,2015-04-18:/blog/testing-glibc-nsswitch</id><summary type="html">&lt;p&gt;The &lt;a href="http://www.gnu.org/software/libc/manual/html_node/Name-Service-Switch.html"&gt;Name Service
Switch&lt;/a&gt;
(NSS) is the feature of many C libraries, including the standard Linux one
(GNU libc) and the standard Solaris one, that allows name lookup
routines to be implemented via plugins. "Name lookup" here refers to
things like usernames, host names, etc. When you run &lt;code&gt;ls -l …&lt;/code&gt;&lt;/p&gt;</summary><content type="html">&lt;p&gt;The &lt;a href="http://www.gnu.org/software/libc/manual/html_node/Name-Service-Switch.html"&gt;Name Service
Switch&lt;/a&gt;
(NSS) is the feature of many C libraries, including the standard Linux one
(GNU libc) and the standard Solaris one, that allows name lookup
routines to be implemented via plugins. "Name lookup" here refers to
things like usernames, host names, etc. When you run &lt;code&gt;ls -l&lt;/code&gt;, and the
&lt;code&gt;ls&lt;/code&gt; command maps numeric user IDs to usernames, the names are provided
by any module listed in the Name Service Switch's configuration. This
could be the &lt;code&gt;files&lt;/code&gt; module that looks at local files like
&lt;code&gt;/etc/passwd&lt;/code&gt;, the &lt;code&gt;ldap&lt;/code&gt; module that talks to a corporate LDAP server,
etc.&lt;/p&gt;
&lt;p&gt;One of my half-forgotten side projects involves writing a new NSS module.
NSS is configured via the file &lt;code&gt;/etc/nsswitch.conf&lt;/code&gt;, which is systemwide
configuration. If I want to test my NSS module, I could install it
globally and reconfigure my system. But I started wondering if there was
a way to load an NSS module just for a single process under my control.
Since the process is running in my user account, I should be able to
reconfigure it, without affecting the rest of the system.&lt;/p&gt;
&lt;p&gt;Turns out that it's possible in a somewhat hackish way. There's an
internal glibc function called &lt;code&gt;__nss_configure_lookup&lt;/code&gt; that overrides
NSS settings. If you're writing your own test program, you can just
call, e.g., &lt;code&gt;__nss_configure_lookup("passwd", "files")&lt;/code&gt; to force
all user lookups to go through &lt;code&gt;libnss_files&lt;/code&gt;. If you're using an
existing program, you can shoehorn this in by use of an &lt;code&gt;LD_PRELOAD&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="cp"&gt;#include&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="cpf"&gt;&amp;lt;nss.h&amp;gt;&lt;/span&gt;
&lt;span class="cp"&gt;#include&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="cpf"&gt;&amp;lt;stdlib.h&amp;gt;&lt;/span&gt;

&lt;span class="k"&gt;static&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;__attribute__&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="n"&gt;nsstest_ctor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="k"&gt;const&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;char&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;getenv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;NSSTEST_DB&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;getenv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;NSSTEST_CONFIG&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;                &lt;/span&gt;&lt;span class="n"&gt;__nss_configure_lookup&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Compile with &lt;code&gt;gcc -fPIC -shared -o nsstest.so nsstest.c&lt;/code&gt;. Then you can
do things like this:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;howe-and-ser-moving:/tmp geofft$ ls -ld ~
drwxr-xr-x 355 geofft root 34816 Apr 17 21:25 /afs/athena.mit.edu/user/g/e/geofft
howe-and-ser-moving:/tmp geofft$ LD_PRELOAD=./nsstest.so NSSTEST_DB=passwd NSSTEST_CONFIG=files ls -ld ~
drwxr-xr-x 355 40490 root 34816 Apr 17 21:25 /afs/athena.mit.edu/user/g/e/geofft
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Since my account isn't in the &lt;code&gt;files&lt;/code&gt; database on this machine (it's in
&lt;code&gt;hesiod&lt;/code&gt;), my user ID can no longer be looked up if I restrict &lt;code&gt;passwd&lt;/code&gt;
lookups to the &lt;code&gt;files&lt;/code&gt; database. A more straightforward way of testing
is using the &lt;code&gt;getent&lt;/code&gt; command that ships with glibc, which lets you ask
for a specific entry in a specific NSS database. For instance, both
&lt;code&gt;files&lt;/code&gt; and &lt;code&gt;hesiod&lt;/code&gt; have entries for the &lt;code&gt;root&lt;/code&gt; user:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;howe-and-ser-moving:/tmp geofft$ LD_PRELOAD=./nsstest.so NSSTEST_DB=passwd NSSTEST_CONFIG=files getent passwd root
root:x:0:0:root:/root:/bin/bash
howe-and-ser-moving:/tmp geofft$ LD_PRELOAD=./nsstest.so NSSTEST_DB=passwd NSSTEST_CONFIG=hesiod getent passwd root
root:*:0:101:Wizard A Root,,,:/mit/root:/bin/csh
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;If you're writing your own NSS library, you'll also need to set
&lt;code&gt;LD_LIBRARY_PATH&lt;/code&gt; to point to the directory where it lives, since NSS
configuration just takes names, not full paths.&lt;/p&gt;</content><category term="misc"></category></entry><entry><title>A proposal for /usr/bin/python between Python 2 and 3</title><link href="https://ldpreload.com/blog/usr-bin-python-23" rel="alternate"></link><published>2015-04-17T00:00:00+00:00</published><updated>2015-04-17T00:00:00+00:00</updated><author><name>Geoffrey Thomas</name></author><id>tag:ldpreload.com,2015-04-17:/blog/usr-bin-python-23</id><summary type="html">&lt;p&gt;I just got back from PyCon, where a few debian-python team members met to discuss some goals for Python packaging in Debian over the next release cycle. One item of interest is moving away from installing Python 2 by default (expecting it to be &lt;a href="https://www.python.org/dev/peps/pep-0373/"&gt;desupported in 2020&lt;/a&gt;), which raises questions …&lt;/p&gt;</summary><content type="html">&lt;p&gt;I just got back from PyCon, where a few debian-python team members met to discuss some goals for Python packaging in Debian over the next release cycle. One item of interest is moving away from installing Python 2 by default (expecting it to be &lt;a href="https://www.python.org/dev/peps/pep-0373/"&gt;desupported in 2020&lt;/a&gt;), which raises questions about what &lt;code&gt;/usr/bin/python&lt;/code&gt; should mean. At the moment, it very strongly means Python 2 specifically, so there's a question about what it should be on a system with only Python 3 installed&amp;mdash;should it become Python 3? Should it be nonexistent?&lt;/p&gt;
&lt;p&gt;&lt;a href="https://www.python.org/dev/peps/pep-0394/"&gt;PEP 0394&lt;/a&gt; recommends that Python 2 should be installed as &lt;code&gt;python2&lt;/code&gt; and Python 3 as &lt;code&gt;python3&lt;/code&gt;, and that &lt;code&gt;python&lt;/code&gt; should mean Python 2 for now. I think it's important that &lt;code&gt;python&lt;/code&gt; continue to mean Python 2, for the reasons described in the "Migration Notes" section of that PEP. In particular, I think it's very important that you should be able to install Python 2 (for the near future), even if your system did not ship with Python 2, and that the system version of Python 3 should not prevent you from using &lt;code&gt;python&lt;/code&gt; to run Python 2 applications.&lt;/p&gt;
&lt;p&gt;However, not shipping &lt;code&gt;/usr/bin/python&lt;/code&gt; by default also has its downsides. I made a &lt;a href="https://lists.debian.org/debian-python/2015/04/msg00046.html"&gt;suggestion on the debian-python list&lt;/a&gt; for handling this: this blog post is a more detailed version of that proposal.&lt;/p&gt;
&lt;p&gt;The basic motivation for this proposal is that third-party script authors love Python in part because it's just about universally available. &lt;code&gt;#!/usr/bin/env python&lt;/code&gt;, today, is sort of like &lt;code&gt;#!/bin/sh&lt;/code&gt;: you don't necessarily get nice things (Python 3-only features and bash-only features, respectively), but it works. If the &lt;code&gt;python&lt;/code&gt; command stops existing, this is inconvenient for end users, who will need to manually edit scripts or install a version of Python themselves, and authors, who may just decide to use a worse language like &lt;code&gt;#!/bin/sh&lt;/code&gt;. It's also bad for the Python language community, since it removes an incentive to use Python.&lt;/p&gt;
&lt;p&gt;So it would be nice to keep the &lt;code&gt;python&lt;/code&gt; command working usefully on both Python 2-only systems and Python 3-only systems. Fortunately, it's pretty doable to &lt;a href="https://wiki.python.org/moin/PortingToPy3k/BilingualQuickRef"&gt;port code to work on both Python 2 and 3 with the same source&lt;/a&gt;. Especially for third-party scripts with the goal of working out-of-the-box in as many places as possible, writing code to these restrictions isn't particularly onerous, since they needed to stay Python 2-compatible anyway. I've been writing a bunch of Python code recently as polyglot Python 2/3, and the biggest problem has been limiting myself to features in Python 2.7, not getting things to work in both versions of the language.&lt;/p&gt;
&lt;p&gt;So here's the proposal: &lt;strong&gt;we install a wrapper binary as &lt;code&gt;python&lt;/code&gt;, that defaults to launching Python 2&lt;/strong&gt; (or reporting an error if Python 2 is not installed). However, &lt;strong&gt;Python 2/3-compatible scripts can include a specific marker indicating they can be run on Python 3&lt;/strong&gt;, which makes these scripts able to run on both Python 2-only systems and Python 3-only systems.&lt;/p&gt;
&lt;p&gt;This marker is based on the existing &lt;code&gt;coding&lt;/code&gt;: syntax from &lt;a href="https://www.python.org/dev/peps/pep-0263/"&gt;PEP 0263&lt;/a&gt;: it's a "magic comment" on the first or second line of the form &lt;code&gt;pyversions=2.7+,3.3+&lt;/code&gt;, indicating which Python major and minor versions are supported. A script compatible with both Python 2 and 3 should include one of these magic comments, and also include a shebang line launching just &lt;code&gt;python&lt;/code&gt;. Here's an example based on one from PEP 0263:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="ch"&gt;#!/usr/bin/env python&lt;/span&gt;
&lt;span class="c1"&gt;# -*- coding=utf-8 -*- pyversions=2.6+,3.3+&lt;/span&gt;

&lt;span class="kn"&gt;from&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;__future__&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;print_function&lt;/span&gt;

&lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;u&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Hello world!&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;On new systems, the &lt;code&gt;python&lt;/code&gt; command itself is a wrapper binary that knows what versions of the Python interpreter are installed. If it detects a &lt;code&gt;pyversions&lt;/code&gt; comment, it will exec the newest Python interpreter compatible with the comment. For this example, if Python 3.3 is installed, it will launch that: if only Python 3.2 and 2.7 are installed, it will use Python 2.7, since Python 3.2 does not support the &lt;code&gt;u""&lt;/code&gt; literal syntax. Otherwise, it will assume that code is Python 2-only, and exec the newest Python 2 version installed. In either case, if a compatible interpreter cannot be found, it will print an error and exit.&lt;/p&gt;
&lt;p&gt;On legacy systems, the &lt;code&gt;python&lt;/code&gt; command refers to Python 2. So Python 2/3-compatible scripts will still be able to find an interpreter they are compatible with.&lt;/p&gt;
&lt;p&gt;For legacy scripts that use a shebang stating just &lt;code&gt;python&lt;/code&gt;, on both new and legacy systems, they will only ever run on Python 2, or not at all. This preserves the existing API, and avoids the poor user experience of running Python 2 scripts with the Python 3 interpreter, as PEP 0394 warns against doing.&lt;/p&gt;
&lt;p&gt;However, the &lt;code&gt;python&lt;/code&gt; wrapper supports running Python 2/3-compatible scripts with the Python 3 interpreter, which is useful for Python 3-only systems. A future version of Debian can choose to ship the Python 3 interpreter only, and remain compatible with third-party scripts that include the &lt;code&gt;pyversions&lt;/code&gt; magic comment. Meanwhile, these third-party scripts can state &lt;code&gt;#!/usr/bin/env python&lt;/code&gt; in their shebang, and remain compatible with legacy Python 2-only systems, including those (like Mac OS X) that do not include the &lt;code&gt;python2&lt;/code&gt; symbolic link.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;python&lt;/code&gt; wrapper can run in three possible modes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;As an interpreter, it follows the rules previously discussed. The "interpreter" mode covers both invocation via the shebang of a Python script, and invocation of the form &lt;code&gt;python script.py&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;For interactive use, it will just run the newest version of Python on the system. This allows, for instance, teachers of the language to have their students just run &lt;code&gt;python&lt;/code&gt;, without the pedagogical speed bump of having to explain versions of the language. Running the latest major version of Python is safe, since the interpreter will print out its own version at startup.&lt;/li&gt;
&lt;li&gt;Uses such as &lt;code&gt;python -c&lt;/code&gt; are considered scripted use, since in this context, the &lt;code&gt;python&lt;/code&gt; command is also serving as an API, and existing users of the API expect Python 2 just as much as scripts do. (Imagine, for instance, a shell script with &lt;code&gt;KEY=$(python -c "import local_settings; print SECRET_KEY")&lt;/code&gt;), which will fail if &lt;code&gt;python&lt;/code&gt; means Python 3.) In this mode, the wrapper will instead look for an environment variable named &lt;code&gt;PYVERSIONS&lt;/code&gt;. If this is set, it will be parsed as the value of the &lt;code&gt;pyversions&lt;/code&gt; magic comment. So shell scripts that include Python 2/3-compatible &lt;code&gt;python -c&lt;/code&gt; commands can e.g. &lt;code&gt;export PYVERSIONS=2.7+,3.3+&lt;/code&gt; at the top of the script, and work on systems with either just Python 2 or just Python 3.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The end result here is that third-party script authors can continue writing polyglot Python 2/3 code for the indefinite future, and be compatible with both existing Python 2-only distributions and newer Python 3-only distributions. Meanwhile, distributions can move towards installing Python 3 only by default and avoid installing Python 2 as far as possible, without closing off the ability to install Python 2 when needed, or breaking legacy Python 2-only code.&lt;/p&gt;
&lt;p&gt;This is a good transition story for distributions like Debian, Ubuntu, and Fedora that are currently trying to move to Python 3 only, but don't want to break existing code. It's also a good transition story for distributions like Arch that have already started moving &lt;code&gt;/usr/bin/python&lt;/code&gt; to Python 3: interactive and scripted use of the &lt;code&gt;python&lt;/code&gt; command can continue to launch Python 3, but compatibility with third-party Python 2 scripts is regained. And most importantly, it's good for third-party script authors, who want to write one script that works on Debian, Ubuntu, Fedora, Arch, and Mac OS X alike, and for their end users.&lt;/p&gt;
&lt;p&gt;I'm interested in initial feedback on this idea: if it generally seems like a good plan, I'll firm up the details and write it up as a formal PEP. There are a few details to work out, like how this interacts with the &lt;code&gt;py.exe&lt;/code&gt; Windows launcher described in &lt;a href="https://www.python.org/dev/peps/pep-0397/"&gt;PEP 0397&lt;/a&gt; (if at all), but my focus is making &lt;code&gt;/usr/bin/python&lt;/code&gt; useful and backwards-compatible on UNIX-like platforms.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Edit 3 May 2015:&lt;/strong&gt; I've uploaded a &lt;a href="https://github.com/geofft/pythonmux"&gt;proof-of-concept implementation of this launcher to GitHub&lt;/a&gt; to see what the overhead and complexity of this approach looks like.&lt;/p&gt;</content><category term="misc"></category></entry><entry><title>SSH ControlMaster and ControlPath</title><link href="https://ldpreload.com/blog/ssh-control" rel="alternate"></link><published>2014-04-07T00:00:00+00:00</published><updated>2014-04-07T00:00:00+00:00</updated><author><name>Geoffrey Thomas</name></author><id>tag:ldpreload.com,2014-04-07:/blog/ssh-control</id><summary type="html">&lt;p&gt;One of my favorite SSH tricks is using the &lt;code&gt;ControlMaster&lt;/code&gt; and
&lt;code&gt;ControlPath&lt;/code&gt; options for speeding up connections. The idea is simple:
if you're already logged into a server and you need to log in again,
just reuse the connection you already have instead of redoing the entire
connection handshake. In …&lt;/p&gt;</summary><content type="html">&lt;p&gt;One of my favorite SSH tricks is using the &lt;code&gt;ControlMaster&lt;/code&gt; and
&lt;code&gt;ControlPath&lt;/code&gt; options for speeding up connections. The idea is simple:
if you're already logged into a server and you need to log in again,
just reuse the connection you already have instead of redoing the entire
connection handshake. In addition to making connections much faster, if
you're logging in with a password, you don't have to re-type your
password for each connection. This can be really handy if you're doing a
lot of copies with &lt;code&gt;scp&lt;/code&gt;, checking out files with Subversion's
&lt;code&gt;svn+ssh://&lt;/code&gt;, etc., and don't want (SSH keys can also solve this problem
in many cases, but requires you to set up keys on the server, whereas
this just requires client-side configuration.)&lt;/p&gt;
&lt;p&gt;Setting this up is easy. We'll designate one &lt;code&gt;ssh&lt;/code&gt; process as a &lt;strong&gt;master&lt;/strong&gt;, and
then when another &lt;code&gt;ssh&lt;/code&gt; process wants to connect to the same host, it will
connect to the master process instead and request a shared connection. In order
to make this work, we first have to set up a place for this master process to
listen for requests.&lt;/p&gt;
&lt;p&gt;To do this, add the line&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;ControlPath ~/.ssh/control-%h-%p-%r
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;to your &lt;code&gt;~/.ssh/config&lt;/code&gt; file. You can read more about the syntax in the
&lt;code&gt;ssh_config&lt;/code&gt; man page; this particular setting puts the shared sockets in
your ~/.ssh directory, which is usually a good place for it, and makes
sure that the path is unique for each hostname, port, and remote
username, as recommended by the man page.&lt;/p&gt;
&lt;p&gt;Then create the master &lt;code&gt;ssh&lt;/code&gt; process by running it with the &lt;code&gt;-M&lt;/code&gt; option.
You'll get a normal login, which you can use or just keep around in a
minimized window. You have to keep this connection around until you're
done with all your other connections. If for some reason you want to
avoid opening a shell &amp;mdash; for instance, you're using this with
GitHub, which doesn't let you open a shell &amp;mdash; you'll also want the
&lt;code&gt;-N&lt;/code&gt; option.&lt;/p&gt;
&lt;p&gt;Once you've done this, every new &lt;code&gt;ssh&lt;/code&gt; process that's connecting to the
same host (with the same username and port) will reuse the master
connection instead of making its own. You don't need to do anything
special; as long as &lt;code&gt;ControlPath&lt;/code&gt; is set, each new &lt;code&gt;ssh&lt;/code&gt; process will
check for a master connection at that path.&lt;/p&gt;
&lt;p&gt;As mentioned, this can make SSH significantly faster for repeated
operations. For instance, &lt;code&gt;git fetch&lt;/code&gt; against GitHub becomes over twice
as fast for me, compared to re-doing SSH key authentication:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="n"&gt;geofft&lt;/span&gt;&lt;span class="nv"&gt;@cactuar&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;&lt;span class="o"&gt;~/&lt;/span&gt;&lt;span class="n"&gt;src&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;vireo&lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;time&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;git&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;fetch&lt;/span&gt;

&lt;span class="nc"&gt;real&lt;/span&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="n"&gt;m0&lt;/span&gt;&lt;span class="mf"&gt;.305&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;
&lt;span class="k"&gt;user&lt;/span&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="n"&gt;m0&lt;/span&gt;&lt;span class="mf"&gt;.005&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;
&lt;span class="n"&gt;sys&lt;/span&gt;&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="n"&gt;m0&lt;/span&gt;&lt;span class="mf"&gt;.011&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;
&lt;span class="n"&gt;geofft&lt;/span&gt;&lt;span class="nv"&gt;@cactuar&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;&lt;span class="o"&gt;~/&lt;/span&gt;&lt;span class="n"&gt;src&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;vireo&lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ssh&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;M&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;N&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;git&lt;/span&gt;&lt;span class="nv"&gt;@github&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;com&lt;/span&gt;
&lt;span class="n"&gt;geofft&lt;/span&gt;&lt;span class="nv"&gt;@cactuar&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;&lt;span class="o"&gt;~/&lt;/span&gt;&lt;span class="n"&gt;src&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;vireo&lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;time&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;git&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;fetch&lt;/span&gt;

&lt;span class="nc"&gt;real&lt;/span&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="n"&gt;m0&lt;/span&gt;&lt;span class="mf"&gt;.140&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;
&lt;span class="k"&gt;user&lt;/span&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="n"&gt;m0&lt;/span&gt;&lt;span class="mf"&gt;.000&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;
&lt;span class="n"&gt;sys&lt;/span&gt;&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="n"&gt;m0&lt;/span&gt;&lt;span class="mf"&gt;.010&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This example also used the &lt;code&gt;-f&lt;/code&gt; option, which puts the connection into
the background as soon as authentication is complete. To close the
connection, you can use the &lt;code&gt;-O exit&lt;/code&gt; option to &lt;code&gt;ssh&lt;/code&gt;, which, instead of
opening a new connection, signals the ControlMaster process to exit.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="n"&gt;geofft&lt;/span&gt;&lt;span class="nv"&gt;@cactuar&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;&lt;span class="o"&gt;~/&lt;/span&gt;&lt;span class="n"&gt;src&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;vireo&lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ssh&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;O&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;exit&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;git&lt;/span&gt;&lt;span class="nv"&gt;@github&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;com&lt;/span&gt;
&lt;span class="k"&gt;Exit&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;sent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;
&lt;span class="n"&gt;geofft&lt;/span&gt;&lt;span class="nv"&gt;@cactuar&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;&lt;span class="o"&gt;~/&lt;/span&gt;&lt;span class="n"&gt;src&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;vireo&lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;time&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;git&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;fetch&lt;/span&gt;

&lt;span class="nc"&gt;real&lt;/span&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="n"&gt;m0&lt;/span&gt;&lt;span class="mf"&gt;.303&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;
&lt;span class="k"&gt;user&lt;/span&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="n"&gt;m0&lt;/span&gt;&lt;span class="mf"&gt;.010&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;
&lt;span class="n"&gt;sys&lt;/span&gt;&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="n"&gt;m0&lt;/span&gt;&lt;span class="mf"&gt;.007&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;There's a good &lt;a href="http://en.wikibooks.org/wiki/OpenSSH/Cookbook/Multiplexing"&gt;article on Wikibooks about connection
multiplexing&lt;/a&gt;
that covers more advanced use of this feature.&lt;/p&gt;</content><category term="misc"></category></entry><entry><title>Creating tiny Debian packages and repositories for testing</title><link href="https://ldpreload.com/blog/creating-tiny-debian-packages-and-repositories" rel="alternate"></link><published>2011-08-15T00:00:00+00:00</published><updated>2011-08-15T00:00:00+00:00</updated><author><name>Geoffrey Thomas</name></author><id>tag:ldpreload.com,2011-08-15:/blog/creating-tiny-debian-packages-and-repositories</id><summary type="html">&lt;p&gt;For those of you who do a lot of Debian upgrade path testing…&lt;/p&gt;
&lt;p&gt;I got annoyed at equivs not supporting Breaks: lines at all ([Debian bug&lt;/p&gt;
&lt;h1&gt;571638](http://bugs.debian.org/571638)), so I wrote a small shell&lt;/h1&gt;
&lt;p&gt;script to spit out the &lt;a href="http://kitenet.net/~joey/blog/entry/cdbs_killer___40__design_phase__41__/"&gt;minimal debhelper 7 rules
file&lt;/a&gt;-using
package …&lt;/p&gt;</summary><content type="html">&lt;p&gt;For those of you who do a lot of Debian upgrade path testing…&lt;/p&gt;
&lt;p&gt;I got annoyed at equivs not supporting Breaks: lines at all ([Debian bug&lt;/p&gt;
&lt;h1&gt;571638](http://bugs.debian.org/571638)), so I wrote a small shell&lt;/h1&gt;
&lt;p&gt;script to spit out the &lt;a href="http://kitenet.net/~joey/blog/entry/cdbs_killer___40__design_phase__41__/"&gt;minimal debhelper 7 rules
file&lt;/a&gt;-using
package. You can then edit debian/control the way you’d edit an equivs
control file and run debuild, or you can continue writing a package for
actual software, since it’s a real package and not just an equivs
control file.&lt;/p&gt;
&lt;p&gt;I also got annoyed at apt not really being able to install packages
files on local disk, so I wrote an even tinier shell script to add all
packages (recursively) in the current directory to an apt repo and add
it via the file protocol to sources.list. It turns out
&lt;a href="http://manpages.ubuntu.com/manpages/natty/man1/dpkg-scanpackages.1.html"&gt;dpkg-scanpackages&lt;/a&gt;
does this, it’s just easier to have the two-line shell script to
remember for you what the command is and what the sources.list line
should be.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://web.mit.edu/geofft/arch/common/bin/newpackage"&gt;newpackage&lt;/a&gt; and
&lt;a href="http://web.mit.edu/geofft/arch/common/bin/fakerepo"&gt;fakerepo&lt;/a&gt; are in my
Athena home directory. See the comments at the top for usage
instructions. I might find a better place for these at some point, but I
don’t anticipate ever having to update them…&lt;/p&gt;</content><category term="misc"></category></entry><entry><title>Using Google ClientLogin</title><link href="https://ldpreload.com/blog/using-google-clientlogin" rel="alternate"></link><published>2011-05-13T00:00:00+00:00</published><updated>2011-05-13T00:00:00+00:00</updated><author><name>Geoffrey Thomas</name></author><id>tag:ldpreload.com,2011-05-13:/blog/using-google-clientlogin</id><summary type="html">&lt;p&gt;The answer to this was much less obvious than I expected it to be, so I
figured I’d blog it. If you’re using Google’s &lt;a href="http://code.google.com/apis/accounts/docs/AuthForInstalledApps.html"&gt;ClientLogin
API&lt;/a&gt;
for turning a username and a password into an auth token, what do you do
with the token? The result of …&lt;/p&gt;</summary><content type="html">&lt;p&gt;The answer to this was much less obvious than I expected it to be, so I
figured I’d blog it. If you’re using Google’s &lt;a href="http://code.google.com/apis/accounts/docs/AuthForInstalledApps.html"&gt;ClientLogin
API&lt;/a&gt;
for turning a username and a password into an auth token, what do you do
with the token? The result of POSTing to /accounts/ClientLogin gets you
three values, and Google says to “reference” the Auth=foo line and
discard the rest.&lt;/p&gt;
&lt;p&gt;The answer is to send back a header of the form &lt;code&gt;Authorization:
GoogleLogin auth=foo&lt;/code&gt;. (That is to say, your authentication token
doesn’t go anywhere in the POST data, which is what I tried for a
while…)&lt;/p&gt;
&lt;p&gt;Incidentally, I’m doing this because I’m playing with &lt;a href="http://www.google.com/support/cloudprint/"&gt;Google Cloud
Print&lt;/a&gt;. I successfully
created a cloud printer printed a PDF from my phone to, uh, a shell wget
command. More on that later.&lt;/p&gt;</content><category term="misc"></category></entry><entry><title>Be My Escape</title><link href="https://ldpreload.com/blog/be-my-escape" rel="alternate"></link><published>2010-09-13T00:00:00+00:00</published><updated>2010-09-13T00:00:00+00:00</updated><author><name>Geoffrey Thomas</name></author><id>tag:ldpreload.com,2010-09-13:/blog/be-my-escape</id><summary type="html">&lt;p&gt;My &lt;a href="http://xprod.mit.edu/"&gt;a cappella group&lt;/a&gt; is singing Relient K’s “Be
My Escape” this semester. In discussion at rehearsal after we received
the music, it was pointed out that the words are about as fundamental to
how cool the song is as the music (and the music is pretty amazing), but …&lt;/p&gt;</summary><content type="html">&lt;p&gt;My &lt;a href="http://xprod.mit.edu/"&gt;a cappella group&lt;/a&gt; is singing Relient K’s “Be
My Escape” this semester. In discussion at rehearsal after we received
the music, it was pointed out that the words are about as fundamental to
how cool the song is as the music (and the music is pretty amazing), but
it’s fairly intricate and rapid and hard to understand all the details.
Here’s my interpretation.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;I’ve given up on giving up slowly&lt;br&gt;
I’m blending in so you won’t even know me&lt;br&gt;
Apart from this whole world that shares my fate&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The song has essentially one large conceit, of which fate is going to be
an important part. One thing to note here is that “giving up slowly” is
keeping trying at least a little bit, or if nothing else pretending to
not have given up; if he’s “given up on giving up slowly”, he’s given up
hard. Another is that the last two lines are a full sentence, so he’s
&lt;em&gt;not&lt;/em&gt; “apart” from the world, but indistinguishable from it, and
resigned to share his fate with them. But that’s mostly straightforward.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;This one last bullet you mention&lt;br&gt;
Is my one last shot at redemption&lt;br&gt;
Because I know to live you must give your life away&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Suddenly there are a lot more things going on, of which the first is the
wordplay of “shot”. It’s both his chance at redemption and firing the
bullet; for redemption, or escape, he can kill himself and give his life
away. But he then says he does that to live, which seems to be a
contradiction. The statement, incidentally, sounds much like an
oft-repeated quote from the Gospels, Matthew 10:39, Luke 9:24 and 17:33,
etc. etc.&lt;/p&gt;
&lt;p&gt;Relient K is a Christian band, and they are undoubtedly going for that
reference. But more than that, there are parts near the end when “you”
cannot be anything other than Christ, and I think there’s no good reason
to say that it’s anyone else here. So what is the bullet Christ
mentions? Of course it’s not literal, and this resolves the
contradiction: the bullet is the chance to end the &lt;em&gt;old&lt;/em&gt; life, the one
that makes the singer just part of the rest of the world that shares his
fate, and to find spiritual rebirth. Stepping back in one more place
this is quoted, John 12, we find this verse before it: “I tell you the
truth, unless a kernel of wheat falls to the ground and dies, it remains
only a single seed. But if it dies, it produces many seeds. The man who
loves his life will lose it, while the man who hates his life in this
world will keep it for eternal life.”&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;And I’ve been housing all this doubt&lt;br&gt;
And insecurity&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;More wordplay here: “housing” is used both in the sense of keeping it
within himself, and building a kind of mental house to live in, out of
those fears. The song continues on that imagery,&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;And I’ve been locked inside that house&lt;br&gt;
All the while you hold the key&lt;br&gt;
And I’ve been dying to get out&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Keep the picture of the singer struggling with a locked door from the
inside, and Christ outside holding a key (somewhat reminiscent of
Revelation’s “I stand at the door and knock.”), for later in the song.
At the moment, the focus is on the word “dying”, which is again used
both in the idiomatic sense of desiring, and in a literal one,&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;And that might be the death of me&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Once more, the idiom “the death of me” is particularly intentional;
we’ve seen by here that the song is about spiritual death and rebirth.
From here on, the chorus a lot more straightforward:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;And even though there’s no way of knowing&lt;br&gt;
Where to go, I promise I’m going becauses&lt;br&gt;
I’ve got to get out of here&lt;br&gt;
I’m stuck inside this rut that I fell into by mistake&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;As long as we’re here, it’s worth commenting that, though he may have
fallen into the rut “by mistake”, it’s still entirely his responsibility
to find a way out. The chorus after the second verse fills out this
concept by changing that line to “’Cause I’m afraid that this
complacency is something I can’t shake.”&lt;/p&gt;
&lt;p&gt;There’s probably a full treatise on how this plays into the Christian
conception of sin and especially original sin, but I won’t get into that
detail here, except to note that this is a pretty fundamental part of
the song.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;I’ve got to get out of here&lt;br&gt;
And I’m begging you&lt;br&gt;
I’m begging you&lt;br&gt;
I’m begging you to be my escape&lt;/p&gt;
&lt;p&gt;I’ve given up, I’m doing this alone now&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;He’s no longer part of “this whole world that shares my fate”.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;’Cause I’ve failed and I’m ready to be shown how&lt;br&gt;
You’ve told me the way and now I’m trying to get there&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The Way, the Truth, and the Life.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;And this life sentence that I’m serving&lt;br&gt;
I admit that I’m every bit deserving&lt;br&gt;
But the beauty of grace is that it makes life not fair&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The last line is, in my opinion, one of the most powerful of the song.
Life’s not fair, it’s true, but if it were, he’d be stuck with his “life
sentence” instead of having any options to escape it.&lt;/p&gt;
&lt;p&gt;On the subject of a life sentence, I think this is more wordplay. At the
least there’s more wordplay between that and the word “life” two lines
later, but beyond that he’s not awaiting but currently serving that
sentence, while “locked inside that house.” My reading is that the pun
involves taking “life sentence” very literally — he is sentenced to have
nothing beyond earthly life. As a human, human life is what we deserve,
but the singer finds it constraining and seeks to escape and live more
than that. After another chorus, this view becomes clear:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;I am a hostage to my own humanity&lt;br&gt;
Self-detained and forced to live in this mess I’ve made&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;and we start getting to the heart of the Christian message. God is not
an almighty tyrant popping up out of nowhere to morally condemn humans
for being human; we are already constrained by the very nature of our
mortal life.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;And all I’m asking is for you to do what you can with me&lt;br&gt;
But I can’t ask You to give what you already gave&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;“While we were yet sinners, Christ died for us.” While we were still
“hostages to our humanity”, God came down, took on those chains in his
birth, and in his death broke them. In the attempt to figure out how to
escape humanity, God put his very being to that cause.&lt;/p&gt;
&lt;p&gt;One last chorus, drums and guitars quiet until two powerful downbeats on
“dying to get out,” and at the end of that:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;I fought you for so long, I should have let you in&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Remember the imagery of Christ from outside holding the key. Also here,
at least in my reading, is a little bit of a pun, in that we expect that
phrase to go “I should have let you win.”&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;(Oh how we regret those things we do)&lt;br&gt;
And all I was trying to do was save my own skin&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;One last idiom chosen very intentionally. Beyond the idiomatic meaning
of salvation and preservation in general, “skin” in particular refers to
his human nature, the earth-life that he was clinging to. But the God he
was fighting was trying to do nothing else but provide perfect
preservation and salvation for him,&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Oh, but so were you&lt;br&gt;
So were you&lt;/p&gt;
&lt;/blockquote&gt;</content><category term="misc"></category></entry><entry><title>The Quota Corollary to Parkinson’s Law</title><link href="https://ldpreload.com/blog/the-quota-corollary-to-parkinsons-law" rel="alternate"></link><published>2010-08-30T00:00:00+00:00</published><updated>2010-08-30T00:00:00+00:00</updated><author><name>Geoffrey Thomas</name></author><id>tag:ldpreload.com,2010-08-30:/blog/the-quota-corollary-to-parkinsons-law</id><summary type="html">&lt;p&gt;&lt;a href="http://en.wikipedia.org/wiki/Parkinson%27s_Law"&gt;Parkinson’s Law&lt;/a&gt;, the
famous quote from his 1955 essay, claims, &lt;em&gt;“Work expands so as to fill
the time available for its completion.”&lt;/em&gt; It seems there is an analogous
principle for disk space:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Date: Mon, 10 Sep 2007 23:05:25 -0400 (EDT)&lt;br&gt;
To: accounts@mit.edu&lt;br&gt;
Subject: AFS quota …&lt;/p&gt;&lt;/blockquote&gt;</summary><content type="html">&lt;p&gt;&lt;a href="http://en.wikipedia.org/wiki/Parkinson%27s_Law"&gt;Parkinson’s Law&lt;/a&gt;, the
famous quote from his 1955 essay, claims, &lt;em&gt;“Work expands so as to fill
the time available for its completion.”&lt;/em&gt; It seems there is an analogous
principle for disk space:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Date: Mon, 10 Sep 2007 23:05:25 -0400 (EDT)&lt;br&gt;
To: accounts@mit.edu&lt;br&gt;
Subject: AFS quota increase&lt;/p&gt;
&lt;p&gt;Hi,&lt;/p&gt;
&lt;p&gt;Could I get my quota increased a little bit? I have a LOT of
medium-size files for various projects… I tried to clear up my homedir
about a month ago but it didn’t help more than about 100 MB. And today
my usage jumped from 98% to 99% when I uploaded my first pset (for
6.170)…&lt;/p&gt;
&lt;p&gt;Thanks,&lt;/p&gt;
&lt;p&gt;Date: Thu, 4 Sep 2008 01:32:00 -0400 (EDT)&lt;br&gt;
To: accounts@mit.edu&lt;br&gt;
Subject: Quota bump&lt;/p&gt;
&lt;p&gt;Hi,&lt;/p&gt;
&lt;p&gt;Classes already having started, it’s going to be hard to spend time
cleaning out my AFS volume and e-mail this week, although I’ll do so
soon (I should probably move the things I don’t need regular access to
to other storage, anyway). Any chance I could please have a little bit
of a quota bump on each so I can do the first assignment for my
classes without worrying?&lt;/p&gt;
&lt;p&gt;Thanks,&lt;/p&gt;
&lt;p&gt;Date: Tue, 1 Sep 2009 15:05:00 -0400 (EDT)&lt;br&gt;
To: accounts@mit.edu&lt;br&gt;
Subject: quota bump for my locker&lt;/p&gt;
&lt;p&gt;Hi Accounts,&lt;/p&gt;
&lt;p&gt;Can I get more Athena quota on the grounds that it would be helpful
for continuing to work on Athena, or something? :)&lt;/p&gt;
&lt;p&gt;Also, term is starting soon… I did look around for things that seem
potentially likely to be removable, but nothing stands out. I can look
harder or try moving things to other storage if you’d prefer I start
with that.&lt;/p&gt;
&lt;p&gt;Thanks a bunch,&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Here are the current official disk policies:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="nv"&gt;maximum&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;volume&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;sizes&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nv"&gt;reference&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;snapshots&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;eg&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;unchanging&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;CD&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nv"&gt;DVD&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;images&lt;/span&gt;&lt;span class="ss"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;25&lt;/span&gt;&lt;span class="nv"&gt;G&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nv"&gt;swmaint&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nv"&gt;rel&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nv"&gt;eng&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="nv"&gt;G&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;but&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;negotiable&lt;/span&gt;&lt;span class="ss"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nv"&gt;course&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nv"&gt;cwis&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nv"&gt;leased&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="nv"&gt;G&lt;/span&gt;

&lt;span class="nv"&gt;quotas&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;user&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;homedirs&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;and&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;activity&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;lockers&lt;/span&gt;&lt;span class="ss"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nv"&gt;default&lt;/span&gt;:&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="nv"&gt;G&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;they&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;ask&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;more&lt;/span&gt;:&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="nv"&gt;G&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nv"&gt;and&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;justify&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;it&lt;/span&gt;:&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="nv"&gt;G&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nv"&gt;and&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;are&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;Thesing&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;and&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;have&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;a&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;signed&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;letter&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;from&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;the&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;Pope&lt;/span&gt;:&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="nv"&gt;G&lt;/span&gt;
&lt;span class="w"&gt;                &lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;sufficient&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;academic&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;need&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;may&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;substitute&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;the&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;Papal&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;letter&lt;/span&gt;&lt;span class="ss"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;My freshman year, the second half was 1G/1.5G/2G/3G (unchanged since
2004), so at least there’s more breathing room. But still, note
carefully,&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$&lt;span class="w"&gt; &lt;/span&gt;fs&lt;span class="w"&gt; &lt;/span&gt;listquota
Volume&lt;span class="w"&gt; &lt;/span&gt;Name&lt;span class="w"&gt;                    &lt;/span&gt;Quota&lt;span class="w"&gt;       &lt;/span&gt;Used&lt;span class="w"&gt; &lt;/span&gt;%Used&lt;span class="w"&gt;   &lt;/span&gt;Partition
user.geofft&lt;span class="w"&gt;                  &lt;/span&gt;&lt;span class="m"&gt;8000000&lt;/span&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="m"&gt;7586330&lt;/span&gt;&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="m"&gt;95&lt;/span&gt;%&amp;lt;&amp;lt;&lt;span class="w"&gt;       &lt;/span&gt;&lt;span class="m"&gt;78&lt;/span&gt;%&lt;span class="w"&gt;    &lt;/span&gt;&amp;lt;&amp;lt;WARNING
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;I guess it makes sense: in the normal case, there isn’t a lot of
incentive for me to care about disk space, and it’s not a worthwhile use
of my time until pressure appears. Even so, I find it amusing that no
matter how many quota bumps I’ve already had or how many iterations of
Moore’s Law have doubled my quota without even asking, it has become a
tradition that every fall (except my freshman year), before classes
start, I’ve used 95% of my quota. &lt;em&gt;Files expand so as to fill the disk
available for their storage.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Looking at the policy, I guess this time I don’t have a choice but to
clean it up.&lt;/p&gt;</content><category term="misc"></category></entry><entry><title>Testing C code from the command line: gccrun</title><link href="https://ldpreload.com/blog/gccrun" rel="alternate"></link><published>2010-08-23T00:00:00+00:00</published><updated>2010-08-23T00:00:00+00:00</updated><author><name>Geoffrey Thomas</name></author><id>tag:ldpreload.com,2010-08-23:/blog/gccrun</id><summary type="html">&lt;p&gt;I wrote a little utility the other day before I found myself in need of
it: it takes its argument, compiles it as the body of a C program, and
runs it.&lt;/p&gt;
&lt;p&gt;This is way more convenient than you’d think at first glance: it turns
out that, for one- …&lt;/p&gt;</summary><content type="html">&lt;p&gt;I wrote a little utility the other day before I found myself in need of
it: it takes its argument, compiles it as the body of a C program, and
runs it.&lt;/p&gt;
&lt;p&gt;This is way more convenient than you’d think at first glance: it turns
out that, for one- or two-line programs where you’re just testing how
something works, when 80% of your program is include boilerplate and
making a source file and running gcc followed by the program, you’re
somewhat disinclined to test small things. When you have a utility like
this, you end up using it a lot…&lt;/p&gt;
&lt;p&gt;How many file descriptors can I open?&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="nt"&gt;dr-wily&lt;/span&gt;&lt;span class="o"&gt;:~&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;geofft&lt;/span&gt;&lt;span class="o"&gt;$&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;gccrun&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;int fd; while ((fd = open(&amp;quot;/dev/null&amp;quot;, 0)) &amp;gt; 0) printf(&amp;quot;%d\n&amp;quot;, fd);&amp;#39;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;tail&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-1&lt;/span&gt;
&lt;span class="nt"&gt;1023&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;What error does that get me?&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="nt"&gt;dr-wily&lt;/span&gt;&lt;span class="o"&gt;:~&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;geofft&lt;/span&gt;&lt;span class="o"&gt;$&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;gccrun&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;while (open(&amp;quot;/dev/null&amp;quot;, 0) &amp;gt; 0); perror(&amp;quot;open&amp;quot;);&amp;#39;&lt;/span&gt;
&lt;span class="nt"&gt;open&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;Too&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;many&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;open&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;files&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Can I go higher by not having things open on lower fds, and just opening
something on fd 1024?&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="nt"&gt;dr-wily&lt;/span&gt;&lt;span class="o"&gt;:~&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;geofft&lt;/span&gt;&lt;span class="o"&gt;$&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;gccrun&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;dup2(0, 1023); perror(&amp;quot;dup2&amp;quot;);&amp;#39;&lt;/span&gt;
&lt;span class="nt"&gt;dup2&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;Success&lt;/span&gt;
&lt;span class="nt"&gt;dr-wily&lt;/span&gt;&lt;span class="o"&gt;:~&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;geofft&lt;/span&gt;&lt;span class="o"&gt;$&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;gccrun&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;dup2(0, 1024); perror(&amp;quot;dup2&amp;quot;);&amp;#39;&lt;/span&gt;
&lt;span class="nt"&gt;dup2&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;Bad&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;file&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;descriptor&lt;/span&gt;&lt;span class="err"&gt;`&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;What is errno 2?&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="nt"&gt;dr-wily&lt;/span&gt;&lt;span class="o"&gt;:~&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;geofft&lt;/span&gt;&lt;span class="o"&gt;$&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;gccrun&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;printf(&amp;quot;%s\n&amp;quot;, strerror(2));&amp;#39;&lt;/span&gt;
&lt;span class="nt"&gt;No&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;such&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;file&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;or&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;directory&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;What is my “session leader”?&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="nt"&gt;dr-wily&lt;/span&gt;&lt;span class="o"&gt;:~&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;geofft&lt;/span&gt;&lt;span class="o"&gt;$&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;gccrun&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;printf(&amp;quot;%d\n&amp;quot;, getsid(0));&amp;#39;&lt;/span&gt;
&lt;span class="nt"&gt;18291&lt;/span&gt;
&lt;span class="nt"&gt;dr-wily&lt;/span&gt;&lt;span class="o"&gt;:~&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;geofft&lt;/span&gt;&lt;span class="o"&gt;$&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;ps&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;18291&lt;/span&gt;
&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="nt"&gt;PID&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;TTY&lt;/span&gt;&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nt"&gt;STAT&lt;/span&gt;&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="nt"&gt;TIME&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;COMMAND&lt;/span&gt;
&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;18291&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;pts&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nt"&gt;28&lt;/span&gt;&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="nt"&gt;Ss&lt;/span&gt;&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="nt"&gt;0&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nd"&gt;00&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nt"&gt;bin&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nt"&gt;bash&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This is, of course, no substitute for reading formal docs or writing
rigorous tests, but it’s great for getting an intuition about how
something works.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://web.mit.edu/snippets/programming/gccrun"&gt;gccrun&lt;/a&gt; is a very tiny
shell script. Most of the convenience comes from it including a bunch of
headers by default; recommendations on headers to add, and patches in
general, welcome.&lt;/p&gt;</content><category term="misc"></category></entry><entry><title>Software I want (other people) to try</title><link href="https://ldpreload.com/blog/software-i-want-other-people-to-try" rel="alternate"></link><published>2010-08-02T00:00:00+00:00</published><updated>2010-08-02T00:00:00+00:00</updated><author><name>Geoffrey Thomas</name></author><id>tag:ldpreload.com,2010-08-02:/blog/software-i-want-other-people-to-try</id><summary type="html">&lt;p&gt;I find myself recommending software I’ve heard of but never tried with
the desire to get other people to spend effort on making them work and
letting me know if they’re worthwhile. I’m generally clear about that
that’s what I’m doing, but still, it feels …&lt;/p&gt;</summary><content type="html">&lt;p&gt;I find myself recommending software I’ve heard of but never tried with
the desire to get other people to spend effort on making them work and
letting me know if they’re worthwhile. I’m generally clear about that
that’s what I’m doing, but still, it feels a &lt;em&gt;little&lt;/em&gt; underhanded, so
here’s an explicit list of (some) software that I haven’t gotten around
to trying, would like to, and would appreciate comments about from
people who’ve used them before:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://cream.sourceforge.net/"&gt;Cream&lt;/a&gt;, a layer on top of vim with
    normal-people-style keyboard shortcuts. Mostly I’m curious if this
    is a reasonable thing to recommend to newcomers to the UNIX world
    who are used to Windows/Mac editors.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://code.google.com/p/partiwm/wiki/xpra"&gt;xpra&lt;/a&gt;, a more different
    way of running X applications across the network by making clever,
    perhaps too clever, use of compositing, and basically just
    compositing windows onto a &lt;em&gt;remote&lt;/em&gt; screen and windows thereon. It
    seems to boast reconnection support and be able to guarantee much
    better security than real X forwarding can.&lt;/li&gt;
&lt;li&gt;&lt;a href="https://git.wiki.kernel.org/index.php/Interfaces,_frontends,_and_tools#Version_Control_Interface_layers"&gt;Alternative git frontends
    (“porcelains”)&lt;/a&gt;,
    specifically &lt;a href="http://www.gnome.org/~newren/eg/"&gt;EasyGit&lt;/a&gt;,
    &lt;a href="http://repo.or.cz/w/yap.git"&gt;Yap&lt;/a&gt;,
    &lt;a href="http://repo.or.cz/w/vng.git"&gt;vng&lt;/a&gt;, &lt;a href="http://git.oblomov.eu/zit"&gt;zit&lt;/a&gt;
    (for single files).&lt;/li&gt;
&lt;li&gt;&lt;a href="http://canorus.berlios.de/"&gt;Canorus&lt;/a&gt;, a music score editor that
    looks like it might be very awesome. Compelling features include
    LilyPond integration and indications that it might actually have a
    reasonable UI.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://colloquy.info/"&gt;Colloquy&lt;/a&gt;, a Mac OS X IRC client. I don’t
    use OS X any more, so this is perhaps the closest to honestly
    wanting to know if it’s a good recommendation.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://fakeroot-ng.lingnu.com/"&gt;fakeroot-ng&lt;/a&gt;, a reimplementation of
    fakeroot using ptrace instead of LD_PRELOAD, which but for speed
    addresses the &lt;a href="http://geofft.mit.edu/blog/sipb/119"&gt;limitations in fakeroot I mentioned
    previously&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://caca.zoy.org/wiki/neercs"&gt;neercs&lt;/a&gt;, an allegedly awesomer
    version of the venerable &lt;a href="http://www.gnu.org/software/screen/"&gt;GNU
    screen&lt;/a&gt;. It has some nice
    tricks and is hopefully more extensible. I also hear the really cool
    kids use &lt;a href="http://tmux.sourceforge.net/"&gt;tmux&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.jedsoft.org/most/"&gt;most&lt;/a&gt;, a pager which is apparently
    even more than either &lt;a href="http://www.slackbook.org/html/file-commands-pagers.html"&gt;more or
    less&lt;/a&gt;.
    Great job on the naming all around, guys…&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;All of these are, as far as I know, free software.&lt;/p&gt;
&lt;p&gt;I’m sure I’ll think of more as time goes on (I already realized I forgot
about the last couple within two minutes of writing this). Anyone have
experience with any of these? Alternatively, what other
potentially-nifty software have you heard of but haven’t gotten a chance
to use?&lt;/p&gt;</content><category term="misc"></category></entry><entry><title>Per-computer colored prompts in bash</title><link href="https://ldpreload.com/blog/per-computer-colored-prompts-in-bash" rel="alternate"></link><published>2010-07-25T00:00:00+00:00</published><updated>2010-07-25T00:00:00+00:00</updated><author><name>Geoffrey Thomas</name></author><id>tag:ldpreload.com,2010-07-25:/blog/per-computer-colored-prompts-in-bash</id><summary type="html">&lt;p&gt;I use my Athena account from many computers, often multiple computers at
once via SSH, and it’s useful to keep track of which terminal is showing
a prompt from which computer. One reasonably easy way to accomplish that
is to color the prompt as a function of which computer …&lt;/p&gt;</summary><content type="html">&lt;p&gt;I use my Athena account from many computers, often multiple computers at
once via SSH, and it’s useful to keep track of which terminal is showing
a prompt from which computer. One reasonably easy way to accomplish that
is to color the prompt as a function of which computer I’m on. Here’s
what I use in my .bashrc:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;PS1&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;\[\e[1;$((31 + $(hostname | cksum | cut -c1-3) % 6))m\]\h\[\e[0m\]:\w \u\$ &amp;quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;From inside out:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;hostname&lt;/code&gt; gets the name of the current computer.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;cksum&lt;/code&gt; gives me a &lt;a href="http://en.wikipedia.org/wiki/Checksum"&gt;checksum&lt;/a&gt; of
its input, which I’m basically just using as a well-known hash function
with numerical output.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;cut&lt;/code&gt; picks out certain characters from the input, in this case the
first three digits/characters, because checksums can be fairly large.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;$(...)&lt;/code&gt; means to evaluate a command and substitute it’s output. (If
you’re familiar with backticks, it’s the same thing, except that
&lt;code&gt;$(... $(...))&lt;/code&gt; works the way you want and &lt;code&gt;`... `...``&lt;/code&gt; doesn’t.)&lt;/p&gt;
&lt;p&gt;&lt;code&gt;$((...))&lt;/code&gt; evaluates arithmetic. In this case, we take the checksum and
get the remainder when divided by six and add it to 31, so we get a
number between 31 and 36. This happens to be the range of &lt;a href="http://everything2.com/title/ANSI+color+codes"&gt;ANSI color
codes&lt;/a&gt; excluding white
and black.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;\e[1;35m&lt;/code&gt; (or whatever the number happens to be is the full ANSI escape
sequence to turn the prompt a certain color, bolded.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;\[&lt;/code&gt; and &lt;code&gt;\]&lt;/code&gt; tell bash that the intervening text in a prompt is a
formatting code, and shouldn’t be counted towards the length of the
prompt, although it doesn’t seem to work for me. It might be related to
&lt;a href="http://invisible-island.net/ncurses/ncurses.faq.html#readline_library"&gt;this snide observation about the code that displays the
prompt&lt;/a&gt;;
I’ve never looked into it in detail.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;\h&lt;/code&gt; actually displays the hostname in the appropriate color, and
&lt;code&gt;\[\e[0m\]&lt;/code&gt; resets the colors to default.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;\w&lt;/code&gt; prints my working directory and &lt;code&gt;\u&lt;/code&gt; my username: I sometimes use
this prompt or my .bashrc on other accounts, so it’s preferable not to
hard-code it.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;\$&lt;/code&gt; prints a dollar sign most of the time, except that it prints a
pound sign if the shell belongs to root: this is a classic UNIX way of
distinguishing the superuser account. Again, I sometimes reuse my
prompt, so it’s nice to have this flexibility.&lt;/p&gt;
&lt;p&gt;Finally, I stuff the result into the &lt;code&gt;PS1&lt;/code&gt; variable.&lt;/p&gt;
&lt;p&gt;So, I get something like this:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;
&lt;span style="color: cyan; font-weight: bold;"&gt;kid-icarus&lt;/span&gt;:~ geofft$ logout&lt;br&gt;
Connection to kid closed.&lt;br&gt;
&lt;span style="color: magenta; font-weight: bold;"&gt;dr-wily&lt;/span&gt;:~ geofft$&lt;br&gt;
&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;If you want more background on bash prompts in general, check out the
&lt;a href="http://www.gnu.org/software/bash/manual/bashref.html#Printing-a-Prompt&amp;quot;"&gt;section of the bash manual on
prompts&lt;/a&gt;.&lt;/p&gt;</content><category term="misc"></category></entry><entry><title>Stupid tricks at the userspace/kernelspace boundary, part 1</title><link href="https://ldpreload.com/blog/stupid-tricks-at-the-userspace-kernelspace-boundary" rel="alternate"></link><published>2010-07-19T00:00:00+00:00</published><updated>2010-07-19T00:00:00+00:00</updated><author><name>Geoffrey Thomas</name></author><id>tag:ldpreload.com,2010-07-19:/blog/stupid-tricks-at-the-userspace-kernelspace-boundary</id><summary type="html">&lt;p&gt;Basically every operating system structures execution into two logical
parts, &lt;em&gt;userspace&lt;/em&gt; and &lt;em&gt;kernelspace&lt;/em&gt;. The former is where the
application’s own code executes, and the latter is where the OS kernel
services requests from applications that require privileged access of
various kinds — reading and writing data on disk, getting more …&lt;/p&gt;</summary><content type="html">&lt;p&gt;Basically every operating system structures execution into two logical
parts, &lt;em&gt;userspace&lt;/em&gt; and &lt;em&gt;kernelspace&lt;/em&gt;. The former is where the
application’s own code executes, and the latter is where the OS kernel
services requests from applications that require privileged access of
various kinds — reading and writing data on disk, getting more memory,
interacting with other applications, making network connections, and so
forth.&lt;/p&gt;
&lt;p&gt;Let’s take a look at how recent versions of Linux (on x86-compatible
CPUs) implement the transition between the two.&lt;/p&gt;
&lt;p&gt;To start off, kernelspace is privileged and can easily return to
userspace. However, as userspace is unprivileged, it can’t just start
running code in kernelspace at will. So in order to make a request of
the OS, a &lt;em&gt;system call&lt;/em&gt;, it generates a software interrupt via the &lt;a href="http://www.intel.com/software/products/documentation/vlin/mergedprojects/analyzer_ec/mergedprojects/reference_olh/mergedProjects/instructions/instruct32_hh/vc140.htm"&gt;INT
instruction&lt;/a&gt;,
which causes essentially the same sort of response as a hardware
interrupt generated by some physical device (a timer, an external input
device, etc.): the processor switches to kernelspace and starts running
a predefined function in the kernel. This interrupt handler determines
what’s going on, acts on the system call, and returns (via
&lt;a href="http://www.intel.com/software/products/documentation/vlin/mergedprojects/analyzer_ec/mergedprojects/reference_olh/mergedprojects/instructions/instruct32_hh/vc143.htm"&gt;IRET&lt;/a&gt;)
from the interrupt back to userspace.&lt;/p&gt;
&lt;p&gt;Usually application programmers don’t have to think about any of this.
The standard C library includes a C function for each system call, which
additionally takes care of things like passing function parameters the
way the system call interrupt handler wants them, and providing unified
error reporting. Moreover, this abstraction layer allows the interface
to be changed: INT is somewhat time-consuming, since it makes the
processor deal with the &lt;em&gt;possibility&lt;/em&gt; of a hardware error, and
eventually Intel introduced the faster
&lt;a href="http://www.intel.com/software/products/documentation/vlin/mergedprojects/analyzer_ec/mergedprojects/reference_olh/mergedprojects/instructions/instruct32_hh/vc311.htm"&gt;SYSENTER&lt;/a&gt;
instruction, and AMD a similar SYSCALL one, which was specifically for
use for system calls and nothing else.&lt;/p&gt;
&lt;p&gt;Well and good, except now code running on older processors needs to
continue to use INT, and newer Intel ones should use SYSENTER, and newer
AMD ones should use SYSCALL, and so we need a different C library for
each processor type. And the problem isn’t just restricted to the C
library: nothing is stopping applications from ignoring the C library
and making system calls if they want to, and there are legitimate uses
for skipping standard libraries entirely (&lt;a href="http://packages.debian.org/stable/busybox-static"&gt;statically-linked rescue
utilities&lt;/a&gt; being one
of the big ones). So we need a different abstraction layer, preferably
one right at the syscall level with no C-library–style tricks.&lt;/p&gt;
&lt;p&gt;Enter the &lt;em&gt;VDSO&lt;/em&gt;, the “virtual dynamic shared object” that looks like it
might be a normal library (“dynamic shared object”) on disk, but is
actually provided by the kernel. Since the kernel does a lot of hardware
probing at boot up, it knows the fastest way to make a system call, so
in a stroke of genius the kernel provides to every process a &lt;em&gt;userspace
library&lt;/em&gt; that implements that fastest system call method. We can see
evidence of this by looking at a process’s own “maps” file in the /proc
directory, which contains information about each process:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="n"&gt;dr&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nl"&gt;wily&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;~&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;geofft&lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;cat&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="k"&gt;proc&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;maps&lt;/span&gt;
&lt;span class="mi"&gt;08048000&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;0804&lt;/span&gt;&lt;span class="n"&gt;f000&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;xp&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;00000000&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;fd&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;00&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;65412&lt;/span&gt;&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;bin&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;cat&lt;/span&gt;
&lt;span class="mi"&gt;0804&lt;/span&gt;&lt;span class="n"&gt;f000&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;08050000&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;rw&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;00006000&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;fd&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;00&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;65412&lt;/span&gt;&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;bin&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;cat&lt;/span&gt;
&lt;span class="mi"&gt;08050000&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;08071000&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;rw&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;08050000&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;00&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;00&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="w"&gt;          &lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;heap&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;b74e2000&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;b761c000&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;00000000&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;fd&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;00&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;630461&lt;/span&gt;&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;usr&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;lib&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;locale&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;locale&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;archive&lt;/span&gt;
&lt;span class="n"&gt;b761c000&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;b761d000&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;rw&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;b761c000&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;00&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;00&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;
&lt;span class="n"&gt;b761d000&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;b7772000&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;xp&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;00000000&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;fd&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;00&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;66165&lt;/span&gt;&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;lib&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;i686&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;cmov&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;libc&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mf"&gt;2.7&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;so&lt;/span&gt;
&lt;span class="n"&gt;b7772000&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;b7773000&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;00155000&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;fd&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;00&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;66165&lt;/span&gt;&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;lib&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;i686&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;cmov&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;libc&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mf"&gt;2.7&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;so&lt;/span&gt;
&lt;span class="n"&gt;b7773000&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;b7775000&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;rw&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;00156000&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;fd&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;00&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;66165&lt;/span&gt;&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;lib&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;i686&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;cmov&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;libc&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mf"&gt;2.7&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;so&lt;/span&gt;
&lt;span class="n"&gt;b7775000&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;b7778000&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;rw&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;b7775000&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;00&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;00&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;
&lt;span class="n"&gt;b778f000&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;b7791000&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;rw&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;b778f000&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;00&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;00&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;
&lt;span class="n"&gt;b7791000&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;b7792000&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;xp&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;b7791000&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;00&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;00&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="w"&gt;          &lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;vdso&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;b7792000&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;b77ac000&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;xp&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;00000000&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;fd&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;00&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;49513&lt;/span&gt;&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;lib&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;ld&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mf"&gt;2.7&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;so&lt;/span&gt;
&lt;span class="n"&gt;b77ac000&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;b77ae000&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;rw&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0001&lt;/span&gt;&lt;span class="n"&gt;a000&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;fd&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;00&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;49513&lt;/span&gt;&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;lib&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;ld&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mf"&gt;2.7&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;so&lt;/span&gt;
&lt;span class="n"&gt;bffeb000&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;c0000000&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;rw&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;bffeb000&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;00&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;00&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="w"&gt;          &lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;stack&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The line marked “[vdso]” indicates the virtual memory location of the
VDSO, and its permissions: readable but not writable, executable, and
private (i.e, not shared with other processes). If we’re curious, we can
write out the VDSO with a &lt;strong&gt;&lt;a href="http://geofft.mit.edu/p/blog/dump-vdso.c"&gt;simple C
program&lt;/a&gt;&lt;/strong&gt; to read its own
/proc/self/maps, search for the “[vdso]” line, parse the addresses, and
write out that section of its own memory.&lt;/p&gt;
&lt;p&gt;Let’s take a look at it with the objdump command, which includes a
simple decompiler:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;dr-wily:/tmp/geofft geofft$ ./dump-vdso &amp;gt; vdso
dr-wily:/tmp/geofft geofft$ objdump -d vdso

vdso:     file format elf32-i386

Disassembly of section .text:

ffffe400 &amp;lt;__kernel_sigreturn&amp;gt;:
ffffe400:       58                      pop    %eax
ffffe401:       b8 77 00 00 00          mov    $0x77,%eax
ffffe406:       cd 80                   int    $0x80
ffffe408:       90                      nop    
ffffe409:       8d 76 00                lea    0x0(%esi),%esi

ffffe40c &amp;lt;__kernel_rt_sigreturn&amp;gt;:
ffffe40c:       b8 ad 00 00 00          mov    $0xad,%eax
ffffe411:       cd 80                   int    $0x80
ffffe413:       90                      nop

ffffe414 &amp;lt;__kernel_vsyscall&amp;gt;:
ffffe414:       51                      push   %ecx
ffffe415:       52                      push   %edx
ffffe416:       55                      push   %ebp
ffffe417:       89 e5                   mov    %esp,%ebp
ffffe419:       0f 34                   sysenter 
ffffe41b:       90                      nop    
ffffe41c:       90                      nop    
ffffe41d:       90                      nop    
ffffe41e:       90                      nop    
ffffe41f:       90                      nop    
ffffe420:       90                      nop    
ffffe421:       90                      nop    
ffffe422:       eb f3                   jmp    ffffe417 &amp;lt;__kernel_vsyscall+0x3&amp;gt;
ffffe424:       5d                      pop    %ebp
ffffe425:       5a                      pop    %edx
ffffe426:       59                      pop    %ecx
ffffe427:       c3                      ret
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;So, on the computer I’m using (a server with four dual-core AMD
Opterons), the kernel recommends SYSENTER. Apparently AMD gave up on
SYSCALL at some point and decided to implement Intel’s SYSENTER.
Meanwhile, on my netbook with an Intel Atom that’s good for nothing
except low power consumption, I get the much simpler:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="n"&gt;geofft&lt;/span&gt;&lt;span class="nv"&gt;@white&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nl"&gt;elephant&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;tmp&lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="k"&gt;dump&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;vdso&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;vdso&lt;/span&gt;
&lt;span class="n"&gt;geofft&lt;/span&gt;&lt;span class="nv"&gt;@white&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nl"&gt;elephant&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;tmp&lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;objdump&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;vdso&lt;/span&gt;

&lt;span class="nl"&gt;vdso&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="k"&gt;file&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;format&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;elf32&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;i386&lt;/span&gt;


&lt;span class="n"&gt;Disassembly&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;of&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;section&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;text&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;

&lt;span class="n"&gt;ffffe400&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;__kernel_sigreturn&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;
&lt;span class="nl"&gt;ffffe400&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;       &lt;/span&gt;&lt;span class="mi"&gt;58&lt;/span&gt;&lt;span class="w"&gt;                      &lt;/span&gt;&lt;span class="n"&gt;pop&lt;/span&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;eax&lt;/span&gt;
&lt;span class="nl"&gt;ffffe401&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;       &lt;/span&gt;&lt;span class="n"&gt;b8&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;77&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;00&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;00&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;00&lt;/span&gt;&lt;span class="w"&gt;          &lt;/span&gt;&lt;span class="n"&gt;mov&lt;/span&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="mh"&gt;0x77&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;eax&lt;/span&gt;
&lt;span class="nl"&gt;ffffe406&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;       &lt;/span&gt;&lt;span class="n"&gt;cd&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;80&lt;/span&gt;&lt;span class="w"&gt;                   &lt;/span&gt;&lt;span class="nc"&gt;int&lt;/span&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="mh"&gt;0x80&lt;/span&gt;
&lt;span class="nl"&gt;ffffe408&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;       &lt;/span&gt;&lt;span class="mi"&gt;90&lt;/span&gt;&lt;span class="w"&gt;                      &lt;/span&gt;&lt;span class="n"&gt;nop&lt;/span&gt;
&lt;span class="nl"&gt;ffffe409&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;       &lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;b4&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;26&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;00&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;00&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;00&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;00&lt;/span&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;lea&lt;/span&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="mh"&gt;0x0&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;esi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;eiz&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;esi&lt;/span&gt;

&lt;span class="n"&gt;ffffe410&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;__kernel_rt_sigreturn&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;
&lt;span class="nl"&gt;ffffe410&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;       &lt;/span&gt;&lt;span class="n"&gt;b8&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ad&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;00&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;00&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;00&lt;/span&gt;&lt;span class="w"&gt;          &lt;/span&gt;&lt;span class="n"&gt;mov&lt;/span&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="mh"&gt;0xad&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;eax&lt;/span&gt;
&lt;span class="nl"&gt;ffffe415&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;       &lt;/span&gt;&lt;span class="n"&gt;cd&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;80&lt;/span&gt;&lt;span class="w"&gt;                   &lt;/span&gt;&lt;span class="nc"&gt;int&lt;/span&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="mh"&gt;0x80&lt;/span&gt;
&lt;span class="nl"&gt;ffffe417&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;       &lt;/span&gt;&lt;span class="mi"&gt;90&lt;/span&gt;&lt;span class="w"&gt;                      &lt;/span&gt;&lt;span class="n"&gt;nop&lt;/span&gt;
&lt;span class="nl"&gt;ffffe418&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;       &lt;/span&gt;&lt;span class="mi"&gt;90&lt;/span&gt;&lt;span class="w"&gt;                      &lt;/span&gt;&lt;span class="n"&gt;nop&lt;/span&gt;
&lt;span class="nl"&gt;ffffe419&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;       &lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;b4&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;26&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;00&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;00&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;00&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;00&lt;/span&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;lea&lt;/span&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="mh"&gt;0x0&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;esi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;eiz&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;esi&lt;/span&gt;

&lt;span class="n"&gt;ffffe420&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;__kernel_vsyscall&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;
&lt;span class="nl"&gt;ffffe420&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;       &lt;/span&gt;&lt;span class="n"&gt;cd&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;80&lt;/span&gt;&lt;span class="w"&gt;                   &lt;/span&gt;&lt;span class="nc"&gt;int&lt;/span&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="mh"&gt;0x80&lt;/span&gt;
&lt;span class="nl"&gt;ffffe422&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;       &lt;/span&gt;&lt;span class="n"&gt;c3&lt;/span&gt;&lt;span class="w"&gt;                      &lt;/span&gt;&lt;span class="n"&gt;ret&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Now here’s where I got curious. /proc/self/maps, as noted above, listed
the page as not writable. Could you make it writable? Let’s try calling
the standard function to change memory permissions and seeing if it will
let us:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;        if (mprotect(vdso_begin, vdso_size, PROT_EXEC | PROT_READ | PROT_WRITE) != 0) {
                perror(&amp;quot;mprotect&amp;quot;);
        }
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;… and we get no error, and in fact if we print out /proc/self/maps we
see&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="n"&gt;b774b000&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;b774c000&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;rwxp&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;b774b000&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;00&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;00&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="w"&gt;          &lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;vdso&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Huh. I wonder if it’s actually writable. Going back to objdump, it looks
like the SYSENTER operation is at 0×419 bytes into the page (the VDSO is
one page, and a page is 0×1000 bytes long). What if we overwrite it to
never make the system call?&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;        &lt;span class="gs"&gt;*(char *&lt;/span&gt;)(vdso_begin + 0x419) = 0x90;
        &lt;span class="gs"&gt;*(char *&lt;/span&gt;)(vdso_begin + 0x41A) = 0x90;
        printf(&amp;quot;Hello world!\n&amp;quot;);
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;0×90 being the opcode for a NOP (no operation, other than stepping one
byte forward). Compile it and — no error, and… it doesn’t terminate
either. Seems like printf is waiting for some system call to report
success, and now that we’ve severed communication with the kernel,
that’s never going to happen…&lt;/p&gt;
&lt;p&gt;It turns out that even without the printf, the program hangs forever:
“return 0;” is just another convenience from the C library. The actual
“entry point” of a program is in the C library, which calls main() and
waits for its return value. Once it has that, it makes the exit() system
call — but again, without the ability to make system calls, the program
can’t exit, and the C library’s exit() wrapper function just keeps
trying to exit, forever.&lt;/p&gt;
&lt;p&gt;Stay tuned for more useful stupid tricks involving modifying
&lt;code&gt;__kernel_vsyscall&lt;/code&gt; — what sorts of things can we do with this
abstraction layer? Here’s a hint: take a look at the “BUGS” section of
&lt;a href="http://linux.die.net/man/1/fakeroot"&gt;fakeroot’s man page&lt;/a&gt;. And yes, I’m
aware of ptrace, but there is a reason not to use it…&lt;/p&gt;
&lt;p&gt;(See &lt;a href="http://www.trilithium.com/johan/2005/08/linux-gate/"&gt;this blog post from Johan
Petersson&lt;/a&gt; for
another treatment of the first 3/5 of this, and &lt;a href="http://anomit.com/2010/04/18/examining-the-linux-vdso/"&gt;this blog post from
Anomit Ghosh&lt;/a&gt;
for a Python version of dump-vdso.)&lt;/p&gt;</content><category term="misc"></category></entry><entry><title>HTTPS and the clustered trusted third party</title><link href="https://ldpreload.com/blog/https-and-the-clustered-trusted-third-party" rel="alternate"></link><published>2010-06-21T00:00:00+00:00</published><updated>2010-06-21T00:00:00+00:00</updated><author><name>Geoffrey Thomas</name></author><id>tag:ldpreload.com,2010-06-21:/blog/https-and-the-clustered-trusted-third-party</id><summary type="html">&lt;p&gt;Rather than going into an in-depth rant about SSL/TLS/HTTPS and
everything I hate about them, let me just discuss two problems I’ve run
into recently.&lt;/p&gt;
&lt;p&gt;As a bit of background, SSL/TLS addresses the issue that Internet
connections are completely unauthenticated, and anyone who can intercept
your …&lt;/p&gt;</summary><content type="html">&lt;p&gt;Rather than going into an in-depth rant about SSL/TLS/HTTPS and
everything I hate about them, let me just discuss two problems I’ve run
into recently.&lt;/p&gt;
&lt;p&gt;As a bit of background, SSL/TLS addresses the issue that Internet
connections are completely unauthenticated, and anyone who can intercept
your request can forge a reply to it, all the more a concern these days
with prevalent wireless networking in public places. The solution, using
&lt;a href="http://www.rsa.com/rsalabs/node.asp?id=2165"&gt;public-key cryptography&lt;/a&gt;,
involves the website digitally signing its responses with a
&lt;em&gt;certificate&lt;/em&gt; that lists the website’s name. This certificate, in turn,
is signed by one of several well-known &lt;em&gt;certificate authorities&lt;/em&gt; who
verify that anyone asking them to sign a certificate legitimately owns
the domain name in question. An attacker can come up with his own
certificate, but should not be able to get that certificate signed by
any authority, and if he tried to invent his own certificate authority
it would not be one of the well-known ones.&lt;/p&gt;
&lt;p&gt;First, for MIT’s web hosting platform
&lt;a href="http://scripts.mit.edu/"&gt;scripts.mit.edu&lt;/a&gt;, we give users hostnames of
the form geofft.scripts.mit.edu. We have a single wildcard certificate
for “*.scripts.mit.edu” that covers our users’ sites. This is all well
and good, except that wildcard certificates for HTTPS, according to &lt;a href="http://www.ietf.org/rfc/rfc2818.txt"&gt;the
spec&lt;/a&gt;, only cover one domain
component. This is a problem for users who have dots in their username —
most notably courses. If you vist, say,
&lt;a href="https://6.001.scripts.mit.edu"&gt;6.001.scripts.mit.edu&lt;/a&gt; in your browser,
you’ll notice that you’ll get an error about 6.001.scripts.mit.edu being
an invalid hostname, as the certificate was “only” issued for
*.scripts.mit.edu. I asked the RFC author what the rationale was for
this restriction, and the related one that a *.*.scripts.mit.edu
certificate or similar is useless for HTTPS, and apart from “wait,
someone wants multiple wildcards?”, it boils down to protecting against
malicious certificates, like tricking a certificate authority into
getting a *.com or (if we prevent first-level wildcards) *.co.uk
certificate, which is much more damaging than tricking a CA into issuing
a particular site’s wildcard-less certificate to you. It seems that the
&lt;a href="http://www.cabforum.org"&gt;CA/Browser Forum&lt;/a&gt; is moving away from being
interested in wildcards in general; for instance, &lt;a href="http://en.wikipedia.org/wiki/Extended_Validation_Certificate"&gt;extended-validation
(EV)
certificates&lt;/a&gt;,
which verify real-world identity in addition to domain name ownership
(and are a lot more expensive), simply cannot be issued for wildcards.
So even if we can convince the folks who run MIT’s local certificate
authority (who know us in real life) to issue an EV certificate for
scripts.mit.edu or some other MIT site, there’s no way they can generate
one.&lt;/p&gt;
&lt;p&gt;Second, I tried visiting
&lt;a href="https://bugs.freedesktop.org/"&gt;https://bugs.freedesktop.org/&lt;/a&gt; earlier
tonight. If your browser is anything like mine (Firefox on Ubuntu), it
will give another certificate error because freedesktop got their
certificate signed by &lt;a href="http://www.cacert.org/"&gt;CAcert.org&lt;/a&gt;, a “community
driven certificate authority” that unlike every other CA out there
(Verisign, Equifax, etc.) is not a large corporation with both an
equally large business stake in never being found untrustworthy and a
bunch of business folks who can talk to the browser vendors and know how
to run a respectable business, and importantly, gives &lt;em&gt;free&lt;/em&gt;
certificates. (Certificates from large corporations can cost hundreds of
dollars a year.) CAcert has had some legitimacy and audit troubles in
the past that are too long to go in here, but it’s a bit of an uphill
battle for then to get themselves listed in the root certificate list of
most operating systems (&lt;a href="http://www.debian.org/"&gt;Debian&lt;/a&gt;, notably and
unsurprisingly, notwithstanding) or browsers. Long story short, Firefox
tells me that the signing authority isn’t trusted, and asks me if I want
to accept the presented cert for bugs.freedesktop.org.&lt;/p&gt;
&lt;p&gt;Now, this is a bit of a problem. I don’t really trust CAcert the way I
trust Verisign and Equifax; if I tried to get to my bank’s website or
Gmail or somesuch, and saw a CAcert-signed certificate, I would be
highly suspicious. But for a site like
&lt;a href="http://www.freedesktop.org/"&gt;freedesktop.org&lt;/a&gt;, it is completely in
character for them to use CAcert. Unfortunately, since my browser
doesn’t trust CAcert, it’s not going to tell me whether validation
passed, and this certificate was actually signed by the CAcert authority
certificate, or even whether the CA being passed off as CAcert belongs
to the real CAcert. If I wanted to do this verification, I have two
choices: either I can add CAcert to the list of CAs that my browser
trusts by default for everything, or I can learn how SSL certificates
work and a tool like OpenSSL, and manually do the verification, which is
a completely unreasonable burden even given that I do know how to use
the OpenSSL command-line tools, and just not even an option for most
users, even including the majority of technical ones.&lt;/p&gt;
&lt;p&gt;On the flip side, when I came to MIT and got my computer set up, I set
up my browser to trust the MIT certificate authority. The purpose here
is that MIT-internal services like online student records won’t need to
pay an outside company for a certificate, if the target audience is just
MIT folks who can do this configuration. However, if MIT decided one day
it wanted to snoop on my Gmail traffic, and one day I got an MIT-signed
certificate for mail.google.com, I would assuredly never notice: MIT’s
on the list of trusted root certificates and is as good as any other. I
certainly don’t check every HTTPS web site I visit to determine which CA
signed it: in the normal case, I couldn’t care less whether it’s
Verisign or Equifax or GoDaddy or Thawte or whomever. Of course, you
might say MIT would never do that, but there’s an actual real-world
concern that &lt;a href="http://lwn.net/Articles/372264/"&gt;the government of China might be doing
this&lt;/a&gt;. They have the same legitimate
concern about not paying outside foreign companies for every site that
only targets Chinese citizens, but the worry that CNNIC might sign a
mail.google.com certificate and execute a &lt;a href="http://en.wikipedia.org/wiki/Man-in-the-middle_attack"&gt;man-in-the-middle
attack&lt;/a&gt; against
Gmail and its users is much more real in that context.&lt;/p&gt;
&lt;p&gt;Ultimately, the design flaw here is that there is a single class of root
certificate authorities, and either a CA is in or it’s out. I want to
have the flexibility of saying that MIT’s CA can do whatever it wants,
including signing EV certificates, for .mit.edu sites, but nothing else,
and that CNNIC can generally do what it wants for .cn but definitely not
for anything else. I want to have the flexibility to say that although
no, I don’t trust CAcert in general, I would at least like to know if
something is honestly signed by the real CAcert as opposed to just being
signed by some fake authority calling itself CAcert, and I would like to
change my browser’s default for some sites, as I see them, to permit
CAcert-signed certificates. I want the error to say not that my browser
doesn’t know who signed this certificate and would I like to accept this
certificate on faith, but that my browser does know who CAcert is and
doesn’t in general trust them but wants to know if it should for this
website.&lt;/p&gt;
&lt;p&gt;Can we restructure HTTPS to give us these capabilities? More
importantly, are the real decision-makers here, the CA/Browser Forum,
interested in this restructuring? This mostly only affects small,
private CAs who aren’t part of the mostly-common list that all browsers
and operating systems trust out of the box: the group of signing
authorities that effectively operates as a single trusted third party
distributed among multiple companies. So it’s not really in the interest
of these commercial CAs to do something so invasive to the structure of
HTTPS at this point in the game. Can we convince the browsers that
there’s a way to pull this off, and that it’s worth it?&lt;/p&gt;</content><category term="misc"></category></entry><entry><title>Installing Ubuntu Lucid via debian-installer over wireless</title><link href="https://ldpreload.com/blog/installing-ubuntu-lucid-via-d-i-over-wireless" rel="alternate"></link><published>2010-06-13T00:00:00+00:00</published><updated>2010-06-13T00:00:00+00:00</updated><author><name>Geoffrey Thomas</name></author><id>tag:ldpreload.com,2010-06-13:/blog/installing-ubuntu-lucid-via-d-i-over-wireless</id><summary type="html">&lt;p&gt;I’m a huge fan of installing Debian and Ubuntu systems with
&lt;a href="http://wiki.debian.org/DebianInstaller"&gt;debian-installer&lt;/a&gt;. Unlike
&lt;a href="http://wiki.debian.org/Debootstrap"&gt;debootstrap&lt;/a&gt;, which just installs a
set of base packages into a directory, debian-installer does a number of
nice things such as offering to do partitioning, setting /etc/fstab
correctly, generating locales, installing a bootloader, etc. etc …&lt;/p&gt;</summary><content type="html">&lt;p&gt;I’m a huge fan of installing Debian and Ubuntu systems with
&lt;a href="http://wiki.debian.org/DebianInstaller"&gt;debian-installer&lt;/a&gt;. Unlike
&lt;a href="http://wiki.debian.org/Debootstrap"&gt;debootstrap&lt;/a&gt;, which just installs a
set of base packages into a directory, debian-installer does a number of
nice things such as offering to do partitioning, setting /etc/fstab
correctly, generating locales, installing a bootloader, etc. etc. — all
things that get you an installed and working &lt;em&gt;system&lt;/em&gt; as opposed to a
pile of packages. Also, unlike
&lt;a href="https://wiki.ubuntu.com/Ubiquity"&gt;Ubiquity&lt;/a&gt;, the standard (graphical)
Ubuntu installer from the live CD, which despite reusing some d-i code
works mainly by &lt;a href="http://bazaar.launchpad.net/~ubuntu-installer/ubiquity/trunk/annotate/head:/doc/README"&gt;copying the live CD onto the hard disk and cleaning it
up&lt;/a&gt;,
d-i actually installs each package in turn, which allows you to
customize your installs.&lt;/p&gt;
&lt;p&gt;I can and probably will talk at length on why I love debian-installer
and how I use it in another post, but this last ability was specifically
important to me when reinstalling my &lt;a href="http://gadgets.boingboing.net/2008/11/03/a-day-with-asus-eeep.html"&gt;Eee PC
900A&lt;/a&gt;,
a machine with under 4 gigabytes of disk space, most of which I wanted
free for myself and not for the operating system. What I can do is tell
d-i not to install any “tasks”, thereby leaving me with a base
(text-mode login!) system that I can later add packages to as I need.&lt;/p&gt;
&lt;p&gt;Unfortunately my favorite method of doing this sort of install is via
the network installer, and when I started the install process I quickly
found that I was getting checksum errors from &lt;a href="http://mirrors.mit.edu/"&gt;my local
mirror&lt;/a&gt; when downloading udebs (special
packages designed for the installer environment). Suspecting, at first,
the mirror, I downloaded by hand all the udebs from another nearby
computer, several times, and was able to verify their checksum.
Switching Ethernet cables didn’t help my netbook have any more luck, nor
did switching mirrors, so I’m left with the assumption that my Ethernet
card is slightly bad. Since I only ever use wireless networking on my
netbook, I wouldn’t care about that if I could do the install over
wireless, but d-i never gave me an option to use a wireless Ethernet
card, nor did one seem to be detected…&lt;/p&gt;
&lt;p&gt;However, in the process of sanity-checking the mirror, I noticed the
existence of a udeb called “wireless-tools-udeb”. I downloaded,
verified, and copied that udeb (and its dependency, “libiw30-udeb”) to
my disk via a live CD, and also copied the live CD’s copy of the kernel
modules necessary for my particular wireless card, ath.ko and ath5k.ko.
Then I restarted the installer, mounted my disk, ran “udpkg -i” on the
two udebs and “insmod” on the two kernel modules, and confirmed that I
started seeing a wireless device and was able to connect it to MIT’s
network with iwconfig.&lt;/p&gt;
&lt;p&gt;Much to my surprise, installing wireless-tools had two nice side
effects:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;After I selected wlan0 as my network device to install via, it asked
me what ESSID I wanted to connect to, and what WEP password (if
necessary). This completely surprised me; I expected that I’d have to
configure wireless networking by hand, and let the installer treat it as
essentially a wired-Ethernet device.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;When the install completed, /etc/network/interfaces on the installed
system was configured to automatically connect to the MIT network.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;I was able to successfully complete the install just over wireless. Now
I have a laptop that boots in approximately twelve seconds, including
connecting to the network.&lt;/p&gt;</content><category term="misc"></category></entry><entry><title>Free software and reusability</title><link href="https://ldpreload.com/blog/free-software-and-reusability" rel="alternate"></link><published>2010-01-11T00:00:00+00:00</published><updated>2010-01-11T00:00:00+00:00</updated><author><name>Geoffrey Thomas</name></author><id>tag:ldpreload.com,2010-01-11:/blog/free-software-and-reusability</id><summary type="html">&lt;p&gt;The rising popularity of the Free Software Movement and the open source philosophy have perhaps yielded an incomplete understanding of them in popular culture, that “open source” means merely “the code is public”. This is far from complete, and not just in an ideological sense but in a practical one …&lt;/p&gt;</summary><content type="html">&lt;p&gt;The rising popularity of the Free Software Movement and the open source philosophy have perhaps yielded an incomplete understanding of them in popular culture, that “open source” means merely “the code is public”. This is far from complete, and not just in an ideological sense but in a practical one. One of the common trip-ups I’ve seen is forgetting the importance of reusability, that free code should be free whether or not it’s part of the software that it came from.&lt;/p&gt;
&lt;p&gt;One of the examples that I ran across recently is that of &lt;a href="https://www.sugarcrm.com/"&gt;SugarCRM&lt;/a&gt;, which loudly advertises that it’s “open source” in its page title and marketing. This is true today; since 2007 the community edition of the software has been released under the GPL v3. But before then, the &lt;a href="https://www.sugarcrm.com/page/sugarcrm-public-license/en"&gt;license they used&lt;/a&gt; contained the following requirement:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;… all copies of the Covered Code in Executable and Source Code form distributed must, as a form of attribution of the original author, include on each user interface screen (i) the “Powered by SugarCRM” logo …&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;plus terms on the size of the logo and the fact that it must be a link. Not too onerous, you’d think, until you decide that you want to take some function for HTML text formatting or web form rendering or somesuch and incorporate it into MediaWiki, and suddently every page on Wikipedia needs to have a “Powered by SugarCRM” logo at the bottom of it. Worse, you could find some useful data structure for organizing e-mail addresses or something and try to incorporate it in your command-line e-mail client, and now you have a user interface screen with no way to display a “Powered by SugarCRM” logo even if you wanted to.&lt;/p&gt;
&lt;p&gt;The sad part about this is that these aren’t restrictions that you’d ordinarily think about. Most news articles focused on the ethics of running a company using “open source” in advertising but with a significantly more featureful proprietary version. Some did realize that the license hurt your &lt;a href="http://web.archive.org/web/20101127012152/http://meatballwiki.org/wiki/RightToFork"&gt;right to fork&lt;/a&gt;, since you’d always have to link to SugarCRM’s website (even if the company collapsed). But what’s really hurt by the inability to learn from and reuse the software is the community of free software development, the “creative commons”, if you will.&lt;/p&gt;
&lt;p&gt;(As a side note, the &lt;a href="https://creativecommons.org/"&gt;Creative Commons&lt;/a&gt; organization is pretty good about respecting this, often under the name of &lt;a href="https://en.wikipedia.org/wiki/Remix_culture"&gt;remix culture&lt;/a&gt;.)&lt;/p&gt;
&lt;p&gt;Debian’s &lt;a href="https://www.debian.org/social_contract"&gt;Social Contract&lt;/a&gt; demonstrates an awareness of this concern:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;We will give back to the free software community&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;When we write new components of the Debian system, we will license them in a manner consistent with the Debian Free Software Guidelines. We will make the best system we can, so that free works will be widely distributed and used. We will communicate things such as bug fixes, improvements and user requests to the upstream authors of works included in our system.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;So, too, do the Free Software Foundation’s &lt;a href="https://www.gnu.org/philosophy/free-sw.html"&gt;four freedoms&lt;/a&gt;, and the &lt;a href="https://people.debian.org/~bap/dfsg-faq.html#testing"&gt;three tests&lt;/a&gt; for whether a particular license is free outlined in an FAQ for Debian’s Free Software Guidelines. Software with conditions on how you can reuse the code for other software isn’t really up to the standards of free software.&lt;/p&gt;
&lt;p&gt;Another surprising example of forgetting to take reusability into account is the Free Software Foundation’s own GNU Free Documentation License. Most of the requirements are along the lines of free software licenses, but the GFDL adds the option to specify “front-cover texts”, “back-cover texts”, and “invariant sections” which cannot be changed in redistribution. You can see a typical example of this in the &lt;a href="https://gcc.gnu.org/onlinedocs/gcc-4.4.2/gcc/"&gt;GCC manual&lt;/a&gt;, with one-line front-cover and back-cover texts, and &lt;a href="https://gcc.gnu.org/onlinedocs/gcc-4.4.2/gcc/Funding.html"&gt;an appendix called “Funding Free Software”&lt;/a&gt; as the invariant section. While this might help the FSF’s fundraising goals, it does mean that if I want to clip the &lt;a href="https://gcc.gnu.org/onlinedocs/gcc-4.4.2/gcc/Actual-Bugs.html"&gt;two-line list of known bugs&lt;/a&gt; for a list of errata included with my distribution, or adapt GCC’s &lt;a href="https://gcc.gnu.org/onlinedocs/gcc-4.4.2/gcc/Hex-Floats.html"&gt;description of C99 hex floats&lt;/a&gt; into a slide for a class on C, I can’t get by with simply putting my errata list or my slide deck under the GFDL. I have to include the two cover phrases and the two pages on “Funding Free Software” somewhere in those documents, no matter how little of the source document I’m excerpting. Debian in fact &lt;a href="https://www.debian.org/vote/2006/vote_001"&gt;considers GFDL-licensed documents with invariant sections&lt;/a&gt; not to be free. Surprisingly enough, one of the alternative proposals suggested that a satisfactory solution to the matter of invariant sections was the ability to counter their politics with a new invariant section of your own! While Debian picked the correct answer here, that there is insufficient difference between free software and free documentation that the latter should have different standards, it’s worrisome to see people completely forgetting the importance of free works being free to be reused in different works.&lt;/p&gt;
&lt;p&gt;This is why the attitude of Debian project members who dislike the existence of Ubuntu, a distribution that regularly updates to the latest Debian packages for almost all its software, particularly bothers me. People interested in making a free distribution should want to see their work reused in other free systems. An attitude of a &lt;a href="http://web.archive.org/web/20070402050524/http://people.debian.org/~daniel/documents/ubuntu.html"&gt;complete lack of interest in helping Ubuntu&lt;/a&gt; unless the problem can be phrased as helping Debian itself, or &lt;a href="https://sandrotosi.blogspot.com/2009/11/things-that-make-me-angry.html"&gt;anger at people using ubuntu.com e-mail addresses to contribute to Debian&lt;/a&gt;, shows that somehow the person is not quite committed to what it means to make a free operating system. In the words of Debian’s founder, &lt;a href="https://archive.is/oK5P0"&gt;“If Ubuntu is part of the Debian family, then we all win if Ubuntu is a success.”&lt;/a&gt; I don’t mean to say there aren’t valid reasons for only paying attention to one’s own direct work: one of those alluded to in the first link in this paragraph, a simple lack of time to understand systems other than Debian, is perfectly understandable. A couple of systems I maintain or know of at MIT, while technically free software, were written with so much of MIT’s infrastructure tacitly assumed at every step that bringing it even to another university is a nontrivial task. But this is something that we want to see, someday, when we have the time to generalize the system or can convince someone else to try.&lt;/p&gt;
&lt;p&gt;Because people who develop free software and believe in the principles of free software should do so with not just an expectation but a hope that they will find their work reused in places that they never imagined.&lt;/p&gt;</content><category term="misc"></category></entry></feed>