2006-03-29

How many setuid binaries on Mac OS?

I've complained a few times about the number of setuid binaries on Mac OS. Various things that Linux manages to do via /proc, for example, Mac OS does via root-only API, and ships setuid binaries as helpers for those programs (such as Activity Monitor) that need the API nonetheless.

Here's the complete list of setuid binaries on my more-or-less default Ubuntu installation:

/lib/dhcp3-client/call-dhclient-script
/usr/bin/newgrp
/usr/bin/chfn
/usr/bin/chsh
/usr/bin/gpasswd
/usr/bin/passwd
/usr/bin/sudo
/usr/bin/at
/usr/bin/mtr
/usr/bin/pmount
/usr/bin/pumount
/usr/bin/lppasswd
/usr/bin/fping
/usr/bin/fping6
/usr/lib/pt_chown
/usr/lib/eject/dmcrypt-get-device
/usr/lib/openssh/ssh-keysign
/usr/sbin/arping
/usr/sbin/traceroute6
/usr/sbin/pppd
/usr/X11R6/bin/X
/bin/su
/bin/mount
/bin/umount
/bin/ping
/bin/ping6

More than I'd like to see, and something like X seems like way too much program to be running as root. (I'm a fairly nervous type, by nature.)

My Debian box at work, which has pretty much every piece of junk in the (testing/unstable) universe installed, has a few more setuid files than that, but not many. (The only things that stick out are /usr/lib/libfakeroot-tcp.so and /usr/lib/libfakeroot-sysv.so, both of which are shared libraries, and aren't executable. Is there some meaning for the setuid bit on a shared library that I'm unaware of? Google doesn't seem to think so, so I guess it's a mistake in that package.)

Here's Mac OS 10.4.5's list. Deep breath now:

/Applications/System Preferences.app/Contents/Resources/installAssistant
/Applications/Utilities/Activity Monitor.app/Contents/Resources/pmTool
/Applications/Utilities/Keychain Access.app/Contents/Resources/kcproxy
/Applications/Utilities/ODBC Administrator.app/Contents/Resources/iodbcadmintool
/bin/ps
/bin/rcp
/sbin/launchd
/sbin/mount_nfs
/sbin/mount_smbfs
/sbin/ping
/sbin/ping6
/sbin/restore
/sbin/route
/sbin/rrestore
/sbin/umount
/System/Library/CoreServices/Classic Startup.app/Contents/Resources/TruBlueEnvironment
/System/Library/CoreServices/Finder.app/Contents/Resources/OwnerGroupTool
/System/Library/CoreServices/RemoteManagement/ARDAgent.app/Contents/MacOS/ARDAgent
/System/Library/CoreServices/SecurityFixer.app/Contents/Resources/securityFixerTool
/System/Library/Extensions/webdav_fs.kext/Contents/Resources/load_webdav
/System/Library/Filesystems/AppleShare/afpLoad
/System/Library/Filesystems/AppleShare/check_afp.app/Contents/MacOS/check_afp
/System/Library/Frameworks/ApplicationServices.framework/Versions/A/Frameworks/PrintCore.framework/Versions/A/Resources/PrinterSharingTool
/System/Library/Frameworks/JavaVM.framework/Versions/1.3.1/Commands/update_sharing
/System/Library/Frameworks/JavaVM.framework/Versions/1.4.2/Commands/update_sharing
/System/Library/Frameworks/JavaVM.framework/Versions/1.5.0/Commands/update_sharing
/System/Library/PreferencePanes/DateAndTime.prefPane/Contents/Resources/TimeZone.prefPane/Contents/Resources/TimeZoneSettingTool
/System/Library/Printers/IOMs/LPRIOM.plugin/Contents/MacOS/LPRIOMHelper
/System/Library/Printers/Libraries/aehelper
/System/Library/Printers/Libraries/csregprinter
/System/Library/PrivateFrameworks/Admin.framework/Versions/A/Resources/readconfig
/System/Library/PrivateFrameworks/Admin.framework/Versions/A/Resources/writeconfig
/System/Library/PrivateFrameworks/Apple80211.framework/Versions/A/Resources/AirPortNetworkPrefs.bundle/Contents/Resources/AirPortCfgTool
/System/Library/PrivateFrameworks/DesktopServicesPriv.framework/Versions/A/Resources/Locum
/System/Library/PrivateFrameworks/DiskManagement.framework/Versions/A/Resources/DiskManagementTool
/System/Library/PrivateFrameworks/Install.framework/Versions/A/Resources/runner
/System/Library/PrivateFrameworks/NetworkConfig.framework/Versions/A/Resources/NetCfgTool
/usr/bin/at
/usr/bin/atq
/usr/bin/atrm
/usr/bin/batch
/usr/bin/chfn
/usr/bin/chpass
/usr/bin/chsh
/usr/bin/crontab
/usr/bin/login
/usr/bin/lppasswd
/usr/bin/passwd
/usr/bin/quota
/usr/bin/rlogin
/usr/bin/rsh
/usr/bin/setregion
/usr/bin/smbutil
/usr/bin/su
/usr/bin/sudo
/usr/bin/top
/usr/lib/sa/sadc
/usr/libexec/authopen
/usr/libexec/chkpasswd
/usr/libexec/load_hdi
/usr/libexec/pt_chown
/usr/libexec/security_authtrampoline
/usr/libexec/security_privportserver
/usr/libexec/ssh-keysign
/usr/libexec/utmp_update
/usr/libexec/xgrid/IdleTool
/usr/sbin/netstat
/usr/sbin/pppd
/usr/sbin/scselect
/usr/sbin/traceroute
/usr/sbin/traceroute6
/usr/sbin/vpnd

[There was also ~/.netprefs which I complained about last year but evidently forgot to remove until now. Comcast's crappy "installation" program did that to me. (And for no good reason, other than that the guy they sent out had connected the wrong cables downstairs and wouldn't believe that it wasn't my fault for using a Mac until I ran his crapware.) Gone now, but embarrassing to have left it so long.]

The question of how many setuid binaries we Mac OS users have on our systems came to me as I read through Apple's About Security Update 2006-001 and noticed "The passwd program is vulnerable to temporary file attacks. This could lead to privilege elevation. This update addresses the issue by anticipating a hostile environment and by creating temporary files securely."

The updated passwd(1) anticipates a hostile environment? That is, a setuid-root binary only now anticipates a hostile environment? That's good of it.

Apple explicitly recommends running setuid helpers in Performing Privileged Operations With Authorization Services: Scenarios where they present a couple of other alternatives which I agree are worse.

I just worry about the lack of minimization of the amount of code that's run as root. wc(1) reckons there's 4921128 bytes of setuid code on Mac OS 10.4.5, and that (slightly exaggerated because of hard links in /usr/bin/ for the "at" and "ch" families) seems like far too much to me. Especially when you compare against the good example set by Linux.

I hope 10.5 makes some progress in this area.

2006-03-19

Samsung SyncMaster 740BF

I got a better display for the Ultra 20 the other day. A Samsung SyncMaster 740BF. The box said 1280x1024 at 75Hz, but Ubuntu came up at 60Hz because xorg.conf still had the details of the CRT I'd been using. Turning to the instruction leaflet that came with the LCD, I found this section about Linux configuration:

To execute X-Window, you need to make the X86Config file, which is a type of system setting file.

1) Press Enter at the first and the second screen after executing the X86Config file.
2) The third screen is for setting your mouse.
3) Set a mouse for your computer.
4) The next screen is for selecting a keyboard.
5) Set a Keyboard for your computer.
6) The next screen is for setting your monitor.
7) First of all, set a horizontal frequency for your monitor. (You can enter the frequency directly.)
8) Set a vertical frequency for your monitor. (You can enter the frequency directly.)
9) Enter the model name of your monitor. This information will not affect the actual execution of X-Window.
10) You have finished setting up your monitor. Execute X-Window after setting other requested hardware.

What? Gibberish! And missing the vital details of what to enter as the hsync and vrefresh values. There's another section in the leaflet that says that the recommended rate for "vertical frequency" is 60Hz . But that's all the detail you're going to get from the bumf in the box.

Luckily, the device itself is more intelligent. What you really want to do is have a "Monitor" section like this, with no manually-supplied information:

Section "Monitor"
Identifier "Generic Monitor"
Option "DPMS"
EndSection

That way Xorg will use the EDID-supplied data from the display itself, which is much more complete and accurate than the useless leaflet, and you'll get the promised 1280x1024 at 75Hz.

The 60Hz mentioned on the leaflet? Not what the display itself reports. More evidence, as if any were needed, that devices should be self-identifying, and humans should be cut out of the loop. All they do is introduce error.

One warning: the display is really bright. They clearly advertise this, and I did notice that its claimed brightness was significantly higher than the other displays on offer, but the default brightness is roughly equivalent to staring directly at the sun. The used area of the display goes right up to the bezel, too, unlike Apple's displays which have a small dead area. It turns out that Apple don't just do this because it looks nice: it also prevents the display from reflecting off the plastic bevel. It's not really a problem in X11, but if you were planning on making a lot of use of the Linux console, this might be something you want to pay attention to when selecting a display.

Anyway, it's a huge improvement on the CRT I was using, and it's reclaimed a huge amount of desk space. Time to set up Synergy, now the Ultra's display can be right next to the Mac's...

2006-03-12

Another Mac OS "universal binary" success story

I don't have an Intel Mac. I'm not likely to get one in the near future, either, because I don't have any particular need for another machine right now. I also don't write software for the Mac for a living, and most of what I write in my own time is Java anyway. So despite all the admonitions from Cupertino to get ready for Intel Macs over the last year, I've paid little attention.

One of the things I work on in my spare time, Terminator, has a JNI component to it. This week a user reported that "Terminator doesn't work on Intel Macs". The distribution only had a PowerPC jnilib (the Mac term for a JNI .so). If the user had been building from source, there would have been no problem. If the user had been trying to use one of the other projects that just has a helper native executable or two, there would have been no problem: Rosetta should be able to take care of that, at some performance cost. But Rosetta can't help the JVM with a PowerPC JNI library.

Now we had someone who could test the result, three lines went in to our make rules, based on Apple's "Compiling for Multiple Architectures":

universal_binary_flags := -isysroot /Developer/SDKs/MacOSX10.4u.sdk -arch ppc -arch i386
C_AND_CXX_FLAGS.Darwin += $(universal_binary_flags)
LDFLAGS.Darwin += $(universal_binary_flags)

And that's it. We now have "universal" (a.k.a. "fat") executables and jnilibs for Intel and PowerPC. Our code had been running on 32- and 64-bit big- and little-endian hardware with various instruction sets for a long time, so we weren't expecting any porting difficulties, and didn't have any.

All the same, I'm still pretty impressed at how little work needed doing. Apple's not usually good like that. Mac OS is full of Apple-specific hoops, and they expect you to jump through them to show that you care. Sure, there are things that you have to do differently to fit in on Mac OS, but there are plenty of places where they could do more automatically so that people who're developing on other platforms wouldn't have to put so much effort into Mac arcana. And even the things that are fundamentally different (applications continuing to run when all their windows are closed, having a single screen menu bar rather than per-window menu bars) could stand some Apple-supplied assistance.

I don't know why Apple chose fat binaries from the various solutions for multi-architecture support, but it's a great choice from the point of view of developers for whom Mac OS support isn't a priority. And it works out pretty well even for those of us who do care.

[I won't mention the hassle I had to go through to get Xcode 2.2 to install properly; how bad the installer's errors were; how annoying it is that even when the installer fails with an error, you have to know that there's an option on one of its menus to ask to see the detail of the error; or that failing to install Java 1.4.2 documentation (for reasons that remain unclear) is enough to halt the installer rather than just make it skip the documentation (despite that being an optional install).]

2006-03-05

Ultra 20, NVIDIA, Ubuntu, and Java 6

For a long time I said I wouldn't have a Linux box at home until it got to the point that you just plug in a display, boot, and it works. All the way to an X11 desktop. Somehow, though, I ended up spending this evening playing with xorg.conf and restarting the X11 server.

I have two problems, you see, with the default Ubuntu installation on my Ultra 20 with its NVIDIA Quadro NVS 280. (Xorg claims it's an FX 330. lspci(1) says it's an unknown device.) The first problem is that I'm stuck using a loaned CRT because it can't drive my 23" Apple Cinema Display. The second problem is that Java 6 is pretty much unusable because certain Swing GTK LAF operations (like changing tabs in a JTabbedPane) take 4 s.

Seriously. 4 s. To change tab.

I submitted Sun bug 6381475 about a month ago, after giving up expecting that it would be fixed in the next build, which I'd been doing for months.

So, anyway, I'm increasingly keen to get an LCD to replace the CRT the Ultra's connected to, so I thought I'd have another go at driving the Apple display. A quick Google turned up HOWTO: Get Apple Cinema 23" Display working using Nvidia drivers on an Ubuntu web site, which seemed like a good place to start. That in turn linked to HOWTO: Latest NVIDIA drivers on the same site.

I followed the instructions on the latter page, copied the Modeline from the former page, restarted gdm(1), and plugged the Apple display in instead of the CRT. I didn't get the 1920x1200 I'd have preferred, but I did get 1280x800, which was better than a kick in the plums. Feeling lucky, I tried rebooting, but ended up pulling the plug and re-connecting the CRT. So no real joy there.

What I have found, though, is that life on the CRT is now much better than before. The binary NVIDIA drivers make a huge difference to OpenGL, and Java 6 is now as usable as Java 5. (I don't really do anything sufficiently graphically intensive on that machine to see any benefit over Java 5.)

So now I could actually consider doing some development on the Ultra, using Edit and Terminator as I do everywhere else.

(Other things I learned during this evening's numerous reboots are that you can edit /etc/gdm/gdm.conf to get a 24-hour clock on the gdm(1) login screen, but you can't get an ISO date, and that F2 at the Sun logo gets you into the BIOS setup screen, where you can turn off the Sun logo.)