mod_mono group initialization patch

About a month back I installed the latest mono release on on one of my servers. A friend of a friend needed a place to do some ASP.Net development. He’d previously had an account with a Windows ASP.Net web host but wasn’t happy with the support he was getting and was trying to cut costs (as everyone always is).

I had the space and the know how to get him up and running so I pointed him to the mono-project ASP.Net page and told him to be sure all of the .Net features he was using were supported by Mono. On my end I installed all of the necessary mono stuff from source which, on Debian 5.0 (Lenny) was very simple. I then set him up with an account just like everyone else that uses this system.

Typically I use Unix DAC Groups to separate users from eachother on the shared host. I create a group for each user (call it www-username) and add both the user and the apache user to this group. This way users can make files they wish to be served up by the web server readable by this group. Nothing fancy, standard DAC stuff.

Funny thing though: this set-up works for static web pages, php scripts etc but didn’t work for the mod-mono-server. The apache error logs showed a stack trace leading back to a permission denied exception on the directory serving up the test ASP web page I was using. This directory had the following permissions as showed by ls -l

drwxr-s--- 3 username    www-username 4096 2009-11-01 16:50 web_dir

The DAC permissions are set up to keep everyone out except the owner and the web server. The server is given read access through the shared group and I’ve also set the sticky bit on the directory to keep files created by the user readable by this group. This last bit isn’t relevant to the denial but it’s useful and apparent in the output above.

Time to debug! We know the apache user (www-data) is in this group and can access files owned by the shared group (www-username) but why not mono? First off the Apache2 server only starts the mono server, it doesn’t process the ASP.Net pages itself. Through the modules interface Apache2 forks off the mod-mono-server2 process which it then feeds requests for the ASP.Net pages. Looking at the output of ps we can check to see that the mod-mono-server2 process has the right effective user and group (which were both correct) but I don’t know of a tool to inspect the supplementary groups for a running process. So we turn to the mod_mono source code for details. Note: Wikipedia has a good explanation of what Unix supplementary groups are if you need more background.

I’m a pretty good C coder but I’ve never looked at the mod_mono code in my life and I know nothing about writing modules for Apache2. But to debug this all I needed was a basic understanding of Unix DAC users and groups. The first thing I looked for was the place in the code where the mono server is started: either a fork or an exec system call is where we should start. These calls are both made in a function called ‘fork_mod_mono_server’ in the mod_mono.c file … yeah that’s probably where we should start looking.

This function also makes calls to setuid and setgid which is the forked process dropping the root privileges of its parent and taking on the identity of a lesser privileged user and group (specified in the apache configuration). On Debian this is the www-data user and group. As I say above we’ve already verified that the uid and gid are being set properly, it’s the supplementary groups that seem to be missing. We can check to see what group membership the forked process has by calling getgroups. Add a few debug statements (ouput the group ids from getgroups to the apache log file), rebuild the module, install it and restart the server and we can see that our suspicions have been confirmed: the only group id returned is 0, the root group?

Yeah, that’s not right. After flipping through a few man pages it looks like the initgroups has the functionality we’re looking for. All we need to do now is pass it the group name for the apache group and it does all the hard work for us. A quick test shows that after rebuilding the module and restarting the server it now has the expected behavior: the mod-mono-server2 process is able to access files that are readable by this shared group!

Now that the problem’s been fixed we want to contribute the it back to the Mono project. I’ve never submitted a patch to a project as high profile as Mono before so I was very conscious about making this patch clean and easy. This wasn’t hard since it was only one system call 🙂 Still it’s important to use formatting and logging statements that are consistent with the rest of the code. After looking at the code around my small fix I added a debug statement to output some information about the group membership initialization and some error handling to output an error message should the system call fail.

After running this fix on two of my servers for a few days I sent the patch to the mono-devel mailing list. Kinda sucks that the mail archive thinks the attachment is a binary. ::shrug:: Either way I got an off-list reply the same day from Marek Harbersack saying that the patch had bee accepted and applied to the mod_mono svn tree! The patch is revision #145618 and they even gave me credit in the svn log!


New Macneil Cranks

My bike spent the better part of the summer down in the basement. I bought a pair of Demolition Medial cranks for it last summer and rode on them for a while but they were never right. The threads were machined a bit funny which made getting a puller on difficult. The face on the crank arm where the chain wheel attached was a bit crooked too. I didn’t notice the later defect till it had ruined a great HTP 25T chain wheel and broke a chain. Here’s the culprit:


Either way I got pissed and took the whole bottom bracket apart then left it sitting on the stand for a few months. The summer was super busy so I kept putting it off but eventually I couldn’t take the sad sight of it any longer:

Bike with no Bearings

I picked up a set of Macneil Conjoined cranks with bearings to match the 19mm spindle. The Macneil hubs I’m running now are great so I figured I’d make a safe bet and give their cranks a go. Paid off so far:

Macneil Conjoined Crank Arm

I still can’t figure out why all of the threads are painted. I didn’t take a picture of the threads for the pedals but they were painted a few millimeters deep like the opening for the spindle. Likely it’s just cheaper to make them that way but it makes the first installation a pain.

So now that all the parts were together, next was pressing the bottom bracket. With the right tools this doesn’t take much effort. At one point I had made a cup press from a long threaded bolt with washers and nuts at each end. It did the trick but eventually I bought the Park Tools equivalent. It’s pretty much the same thing but with handles on each end coated in blue plastic with “Park Tools” stamped on it (I’m guessing that’s why they cost $60, not worth it!):

Cartridge bearings and spacer lined up on press.

This is the whole bottom bracket kit lined up on the cup press. Crappy thing about this press is that the handles can’t clear the frames chain stay completely so you end up with about 2 millimeters of bearing stuck out when the press can’t be turned any further:

Press Clearance
Not pressed completely

That’s why we keep a stack of extra washers around. Stack these on either end of the cup press between the plates and you’ll get enough clearance to press the bearings flush:

washers to the rescue
bearings pressed flush

Once the bearings are pressed it’s just a matter of putting the new spindle in and fitting the cranks on with a chain wheel. It’s always a pain to get the spacers right so that the cranks clear the chain stays and the chain line is straight. I’m pretty anal about this so I always end up taking the drive side crank arm off and putting it back on a few times. It’s a curse. In the end when it’s all back together it looks something like this:


I’m pretty happy with the Conjoined cranks so far. I’ve been riding on them for a few weeks now and they’re as solid as any cranks I’ve had in the past. I wouldn’t consider this much of a stress test though since I pretty much just roll around and try to keep from hurting myself so YMMV.

I’m still pretty pissed about losing that 25T chain wheel caus of the Demolition cranks being crappy. I picked it up at an Easter Boarder shop out in Massachusetts. There’s this guy out there that machines them himself under the name “Home Town Products”. Last time I was out that way he said he wasn’t making them anymore so that’s a loss.

In the background of the first picture you can see a yellow road bike frame sitting on my basement floor. That’s a my winter project. It spent the past year+ sitting outside on a sort-of covered porch so it’s in need of some rehab. More on this later.