WhatsApp is secure

Recently the Guardian published a story falsely claiming the existence of a “backdoor” in WhatsApp. They have since edited the article to instead refer to the behavior in question as a “vulnerability”, but even this is only true in a very specific and limited sense—a nuance absent from the paper’s bombshell presentation of the finding and which, unfortunately, much of the story’s audience will not understand.

This article risks grossly misleading people into abandoning an end-to-end encrypted and forward secure messaging app in favor of materially less-secure alternatives, so I feel it is important to point out:

  1. WhatsApp is among the most secure mainstream options for messaging.
  2. For the vast majority of users, the behavior described in the Guardian’s story does not detract from the real-world benefits of WhatsApp’s implementation of the Signal protocol.
  3. Sending messages over WhatsApp is strictly more secure than SMS.

Zeynep Tufekci wrote a wonderful open letter explaining the problems with the Guardian’s story and calling for its retraction. This letter is signed by more than 60 leading cryptography and security researchers and professionals, and is well worth a read if you’re interested in why this story is so dangerously misleading.

I also recommend reading Moxie Marlinspike’s rebuttal to the Guardian’s story to settle any lingering doubts. The bottom line: if you’re using WhatsApp, this presents absolutely no reason for you to stop.


I finally got around to modernizing this old site, which has included moving from WordPress to a statically-generated, Amazon-hosted site based on Pelican and Bootstrap 3.

I’ll write more about the site’s implementation later because I ended up diving into different areas I think are worth documenting, such as extending Pelican via plugins and some specific issues with hosting a static site on top of Amazon AWS. For now, suffice it to say that if you find any files missing please let me know, as this is probably something I’ve simply forgotten to copy over to the new site.

(Support for IE 8 and older is right out, on the other hand; use IE 10 or better to preserve your sanity.)

Debugging the OpenBSD kernel via QEMU

Recently I had to track down a minor bug in the OpenBSD kernel. I tapped QEMU and GDB as debugging tools for the task, running on Ubuntu 12.04 as the host OS. This combination worked extremely well, so for the record here’s how I set it all up.

OpenBSD comes equipped with two kernel debugging mechanisms: ddb and kgdb. ddb(4) is an in-kernel debugger, enabled by default in the GENERIC kernel, and can be invoked either explicitly from the console or automatically in the event of a panic. It is analogous to the Linux debugger kdb in that it can be used to set breakpoints and examine the stack or register state, but (like kdb) it is not a source-level debugger.

For source debugging there is kgdb(7), which offers the ability to remotely debug the kernel by way of a GDB stub running over a serial port; this is similar to the Linux debugger kgdboc. However, kgdb it is not available in the GENERIC kernel, and it imposes an additional set of configurations and debugger latencies on the user. If your debugging task is amenable to running OpenBSD within a virtual machine, as mine was, then there is an easier and better way…read more

Keyboard navigation in Emacs GDB mode

I love Emacs GDB mode, but I always found it annoying that there is no given key binding (or function which could be directly mapped into a key binding) for switching between the different views given by gdb-many-windows. The usual window and buffer switching functions are insufficient because the GDB windows are flagged as dedicated (so switch-buffer refuses to swap them in place), and in the case of the Locals/Registers and Breakpoints/Threads windows, the buffer you want to visit doesn’t necessarily even exist until you click that button.

This went from mildly annoying to a major headache when I needed to run the debugger in a remote Emacs session, over SSH from Mac OS X’s Terminal.app which does not support xterm mouse emulation. So I wrote this gdb-select-window function and corresponding key bindings to finally get the desired behavior…

;; For the consistency of gdb-select-window's calling convention...
(defun gdb-comint-buffer-name ()
  (buffer-name gud-comint-buffer))
(defun gdb-source-buffer-name ()
  (buffer-name (window-buffer gdb-source-window)))

(defun gdb-select-window (header)
  "Switch directly to the specified GDB window.
Moves the cursor to the requested window, switching between
`gdb-many-windows' \"tabs\" if necessary in order to get there.

Recognized window header names are: 'comint, 'locals, 'registers,
'stack, 'breakpoints, 'threads, and 'source."

  (interactive "Sheader: ")

  (let* ((header-alternate (case header
                             ('locals      'registers)
                             ('registers   'locals)
                             ('breakpoints 'threads)
                             ('threads     'breakpoints)))
         (buffer (intern (concat "gdb-" (symbol-name header) "-buffer")))
         (buffer-names (mapcar (lambda (header)
                                 (funcall (intern (concat "gdb-"
                                                          (symbol-name header)
                               (if (null header-alternate)
                                   (list header)
                                 (list header header-alternate))))
         (window (if (eql header 'source)
                   (or (get-buffer-window (car buffer-names))
                       (when (not (null (cadr buffer-names)))
                         (get-buffer-window (cadr buffer-names)))))))

    (when (not (null window))
      (let ((was-dedicated (window-dedicated-p window)))
        (select-window window)
        (set-window-dedicated-p window nil)
        (when (member header '(locals registers breakpoints threads))
          (switch-to-buffer (gdb-get-buffer-create buffer))
          (setq header-line-format (gdb-set-header buffer)))
        (set-window-dedicated-p window was-dedicated))

;; Use global keybindings for the window selection functions so that they
;; work from the source window too...
(mapcar (lambda (setting)
          (lexical-let ((key    (car setting))
                        (header (cdr setting)))
            (global-set-key (concat "\C-c\C-g" key) #'(lambda ()
                                                        (gdb-select-window header)))))
        '(("c" . comint)
          ("l" . locals)
          ("r" . registers)
          ("u" . source)
          ("s" . stack)
          ("b" . breakpoints)
          ("t" . threads)))

Put this in your ~/.emacs.el or init.el and fire up gdb-many-windows, and then you’ll be able to quickly switch between the GDB windows with the following keyboard shortcuts:

  • C-c C-g c — comint (GDB command) buffer
  • C-c C-g l — locals buffer
  • C-c C-g r — registers buffer
  • C-c C-g u — source window
  • C-c C-g s — stack buffer
  • C-c C-g b — breakpoints buffer
  • C-c C-g t — threads buffer

Both true and false: a Zen moment with C

Additional discussion: Hacker News, Reddit

I ran into a really fun bug at work yesterday, where I discovered that my C program was branching down logically inconsistent code paths. After drinking another cup of coffee and firing up GDB I realized that somehow, a boolean variable in my code was simultaneously testing as both true and not true.

While I cannot reproduce the actual source code here, the effect was that code like

bool p;

/* ... */

if ( p )
    puts("p is true");

if ( ! p )
    puts("p is false");

would produce the output:

p is true
p is false

So what’s going on here?read more

Pointfree style in Python

Additional discussion: Hacker News

I’ve been getting back into Python lately… I just wrote a small module that provides support for pointfree style programming with a combination of automatic partial function/method application and operator overloading for function composition:

from pointfree import *
from operator import add

fn = pfmap(len) \
  >> pfmap(lambda n: n**2) \
  >> pfreduce(add, initial=0)

fn(["foo", "barr", "bazzz"]) # == 50

See the overview for a lengthier introduction. You can install the pointfree module from the Python Package Index:

$ pip install pointfree