After reading that paper more carefully, I found the problem. I wasn't taking the model view matrix into account.
This:
double m[16];
glGetDoublev(GL_PROJECTION_MATRIX, m);
// ... derive t, r, b, and l from m
Should be this:
double vm[16], pm[16], m[16];
glGetDoublev(GL_MODELVIEW_MATRIX, vm);
glGetDoublev(GL_PROJECTION_MATRIX, pm);
matrix_mul(vm, pm, m); // m = vm * pm
// ... derive t, r, b, and l from m