Hacking, the good kind

I could write about the election here, but citizen905 already summed it up pretty well. So instead, here’s what I’ve been breaking in the Linux kernel lately:

  • My final patch count for 2.6.27 was 14, I think. Enough, anyway, that I can stop counting and just deal with all the work I’ve created for myself.
  • I added myself to MAINTAINERS for ath5k, which felt like a pretty ridiculous notoriety grab, but Nick asked me to do so twice, so there.
  • I have some fixes for ath5k for 2.6.28, nothing major but an oops should be fixed, and a WARN_ON removed. The oops fix, incidentally, had an obvious bug despite 3 sign-offs. I suck.
  • Also committed but to-be-reverted for suckiness is a patch to remove beaconing in STA mode. Turns out ath9k, from which I stole this idea, was just busted. The new plan is to use the beacon miss interrupt; until then, your wireless card has to wake up the CPU about 100 times a second.
  • For 2.6.29, I have added hardware encryption to ath5k and hopefully will get some time to hack on the suspend/resume support for mac80211. Then I have some omfs patches I’ve been sitting on for months.

Hacked

So my wife received a spam from herself. At first I thought it was one of those spams where the “From:” was forged to be the same as the recipient, but a closer look revealed that it was actually from her hotmail to her yahoo account and to another dozen of her friends. Uh-oh.

So what happened? Was this a cross-site request forgery (CSRF) attack? She wasn’t logged into hotmail at the time that the email was sent. However, that doesn’t necessarily mean anything: there have been various CSRF attacks where the account is backdoored to send mail elsewhere, and a subsequent password reminder request could then give the attacker the goods. Or her session could have still been active even though the tab was long gone.

Was it spyware? Windows Defender didn’t find any, and we run XP apps in unprivileged user mode (which is a huge PITA, but that’s another story). It probably was not a dictionary attack, since her password is reasonably strong. It could be the case that her password was simply stolen, possibly from another site where the password was reused.

I’m late to the party, but I imagine CSRF and related attacks are still very under-appreciated at the moment, and that’s particularly worrisome with all of the Web 2.0 applications about. Hotmail should know the score, but who knows. As my mind mulls over the possibilities of such a bug in gmail, and the fact that I have three sessions open in it from various computers at the moment, I’m glad I have nothing of value in my gmail account and still use my own domain with mutt for official email. Stories like this one will only become more common. What if your confidential documents, stored on Google Docs, get surreptitiously emailed to everyone you’ve ever done business with?

So, I guess the moral is: get thee a password generator, and remember to log out of webmail!

Open, sorta

I’m glad to see that the not-so-openness of Android is finally getting some press. As someone whose code is included in the phones’ firmware (though surely compiled out, heh), I very much agree with Harald Welte in the first linked article. And that guy bluest on lifehacker sure has really smart comments.

Oh well. I’ll wait for someone to hack it.

SYSRQ on MacBook

Lately I’ve really needed SysRq in situations where /proc/sysrq-trigger just doesn’t do the job, and my MacBook is missing lots of crusty old XT-era keys. Finally, I know how to do this!

/* includes and error handling omitted for brevity... */
#define USAGE_CODE 0x070044 /* USB hid for F11 */

int main() 
{
int codes[2];
int fd = open("/dev/input/by-id/usb-Apple_Computer_Apple_"
"Internal_Keyboard_._Trackpad-event-kbd", O_NONBLOCK);

codes[0] = USAGE_CODE;
codes[1] = KEY_SYSRQ;  /* from linux/input.h */
ioctl(fd, EVIOCSKEYCODE, codes);
}

Awesome. Supposedly, a tool called keyfuzz is also efficacious.

Old soldiers

I had the good fortune to attend a free DC ACM-sponsored lecture by Tony Hoare last week. Hoare is the inventor of quicksort as well as the man behind two of my favorite Computing-related quotes:

Premature optimization is the root of all evil. (via Knuth)

There are two ways of constructing a software design: one way is to make it so simple there are obviously no deficiencies and the other way is to make it so complicated that there are no obvious deficiencies.

He gave a fairly dry talk on the importance of program correctness and how CS-the-science hopes to eventually figure out proof methods and tools that will some day help CS-the-discipline. But, he notes, we’re still a long way off.

I’m still not a member, but good things are coming out of the local ACM chapter. This is the same series that brought Brian Kernighan earlier in the year. Next month there is a black tie affair with Bjarne Stroustrup as the keynote.

OSS, I has it

I just sat in on a conference call as a representative (by default, since no one else called in) of the Linux ath5k community, with Atheros, makers of my MacBook’s wireless ethernet card. Atheros have really done a 180 for supporting the community, first by releasing ath9k, then by releasing the source to their previously-closed HAL last week. Thanks to that, 6 patches have already gone out fixing various problems. BTW, conference calls are just as pointless in the OSS community as they are in real life. But at least I did learn that it is pronounced “uh-THERE-ose”, not “ATH-er-ose.”

Buy laptops with Atheros wireless cards!

Turing

I’ve been going over a lot of old textbooks while studying for my upcoming CS GRE. I forgot how good the Hennessy and Patterson books are. Also I’ve read the dragon book cover-to-cover for the first time (the new edition with the lame CGI dragon on the cover), various parts of TAOCP, and Sedgewick’s Graph Algorithms in C. Time will tell whether I’ve digested any of that.

When I was in the bookstore the other day, I saw Petzold’s The Annotated Turing. I still blame Petzold for the worst book in my computing library, Programming Windows 95. But I needed to fill in some gaps on formal logic and it was 30% off so I thought I’d give it a go. One nice thing is that it presents in full the paper “On Computable Numbers, with an Application to the Entscheidungsproblem,” with corrections inline. I found a number of the annotations on the machines themselves to be superfluous to the original, while the background on Cantor sets and formal logic were absolutely worthwhile. The main problem is that the book sometimes cites large sections of material from another work, which just makes me wish I had read the other work instead. Conspicuously absent from citation but appearing in the bibliography is the mind-altering but lengthy Gödel, Escher, Bach, which in my opinion better tackles the philosophical angles. I give The Annotated Turing a B: nice explanation of the paper but Chuck loses a letter grade for citing his own book twice and for having a Windows tattoo.

This post encrypted with the one-time-pad of all zeros

I only made 770 (67th percentile) on the practice GRE CS subject exam I took today. I guess I need to study up on graph theory and grammars over the next month. The computer architecture questions were all fun though.

Stupidest question of the exam, which I “missed”:

Which is the closest to a perfectly secure encryption scheme:
a) Caesar cipher (heh)
b) DES
c) Enigma
d) One time pad
e) RSA

I take issue with the supposedly correct answer of “D”, since yes, in principle, it is perfect encryption, but in practice, it sucks. Knowing OTP is flawed has to be more useful than knowing that it could be perfect in circumstances that are never true. If only there were an option in the list which provided good encryption and also solved the key distribution problem!

The engineer in me is at times in conflict with the “computer science == astronomy” crowd (yeah, I’m looking at you Dijkstra). Which is why every time I read someone’s article on here’s-how-to-do-X-in-unreadable-haskell my eyes glaze over. Maybe I’m not smart enough, but I would take the fact that there are now a zillion blogs trying to explain monads as evidence that the functional people made pipes too confusing.

Oh, by the way, here’s a secret: CPUs are imperative!

Oops

I am finally getting the hang of debugging kernel crashes. None too soon as I got my first OOPS report from the -rc kernel with OMFS, from a gentleman who is intentionally corrupting his FS (“fuzzing” in the infosec lingo). After a frustrating weekend in which I had inadvertantly fixed the bug but didn’t realize it because I was testing the wrong module, I can now claim success. One down, several more to go.

Detective work after the jump if you care for the nerdy stuff.
Oops report:


BUG: unable to handle kernel paging request at c978e004
IP: [(c032298e)] omfs_readdir+0x18e/0x32f
Oops: 0000 [#1] PREEMPT DEBUG_PAGEALLOC
[...]
EIP: 0060:[(c032298e)] EFLAGS: 00010287 CPU: 0
EIP is at omfs_readdir+0x18e/0x32f
EAX: c978d000 EBX: 00000000 ECX: cbfcfaf8 EDX: cb2cf100
ESI: 00001000 EDI: 00000800 EBP: cb2d3f68 ESP: cb2d3f0c
DS: 007b ES: 007b FS: 0000 GS: 0033 SS: 0068
[...]
[(c018a820)] ? filldir64+0x0/0xcd
[(c018a9f2)] ? vfs_readdir+0x56/0x82
[(c018a820)] ? filldir64+0x0/0xcd
[(c018aa7c)] ? sys_getdents64+0x5e/0xa0
[(c01038bd)] ? sysenter_do_call+0x12/0x31
=======================
Code: 00 89 f0 89 f3 0f ac f8 14 81 e3 ff ff 0f 00 48 8d
14 c5 b8 01 00 00 89 45 cc 89 55 f0 e9 8c 01 00 00 8b 4d c8 8b 75 f0 8b
41 18 (8b) 54 30 04 8b 04 30 31 f6 89 5d dc 89 d1 8b 55 b8 0f c8 0f c9

First step is to look at the faulting instruction. Running the “Code:” part through ~/linux/scripts/decodecode yields the disassembly:


8b 4d c8             	mov    -0x38(%ebp),%ecx
8b 75 f0             	mov    -0x10(%ebp),%esi
8b 41 18             	mov    0x18(%ecx),%eax
8b 54 30 04          	mov    0x4(%eax,%esi,1),%edx <=== here
8b 04 30             	mov    (%eax,%esi,1),%eax
31 f6                	xor    %esi,%esi

So the instruction is dereferencing the address [(eax+esi)*1+4]. From the register dump, EAX=c978d000. That looks like a pointer. ESI is 00001000, which is probably the index to an array. 0x1000 happens to be PAGE_SIZE which explains the page fault (kernel paging request) at the top of the oops.

Next, let’s look at the C code. There are two ways:


$ gdb omfs.ko
(gdb) l *(omfs_readdir+0x18e)

Or (and I find this a little more obvious since it has mixed C and assembly):


$ objdump -S omfs.ko > foo.S
# now look for instruction opcodes in foo.S: "8b 54 30 04"

From the output of the above commands, it’s apparent that the +4 index in the instruction comes from be64_to_cpu() converting a 64-bit big-endian number to little-endian. And we do that when reading directory pointers in omfs_readdir, specifically:


fsblock = be64_to_cpu(*((__be64 *) &bh->b_data[offset]));

EAX is bh->b_data so ESI must be offset. I happen to know it should never be above 2048, but it is 4096 in the register dump. Since the range is ultimately controlled by the directory inode size, I immediately suspected that that size got corrupted. For some reason I chased a bunch of other dead ends until I finally did look at the disk image and saw that the directory size was all wrong. Rule one of debugging: go with your gut.

Oh well. I guess all that assembly coding from years ago was useful after all.