[launchd-dev] Securing Launch Agents

Damien Sorresso dsorresso at apple.com
Fri May 1 11:27:56 PDT 2009


On May 1, 2009, at 4:53 AM, Dave Keck wrote:
> Hey list,
>
> I've been writing some security software, part of which is a
> system-wide agent (stored in /Library/LaunchAgents). I've almost got
> it working to the point that I'm satisfied for a 1.0 release. That
> was, until I realized two show-stopping facts. With a short trip to
> the terminal, any user is able to:
>
> 1. Kill the agent
> 2. Unload the agent using launchctl

Agents run on a per-user basis, so they run as the user. This  
shouldn't surprise anyone.

> Well, duh, you might say. When I started out, I assumed that since the
> write privileges of /Library/LaunchAgents are root:whell, the agents
> loaded from that directory could only be affected by a user with
> administrator credentials. Unfortunately for me, that simply ain't so.
> (Granted, a non-privileged user can only temporarily disable the
> agent, as it will be reloaded when they logout and back in. But for my
> purposes, this is still unacceptable.)

This will change in SnowLeopard. Users will be able to permanently  
disable agents residing in /System/Library/LaunchAgents and /Library/ 
LaunchAgents.

> (Also I should mention that I can't write a daemon because the
> software must display a UI, and the UI itself is part of what
> shouldn't be killed without admin credentials.)
>
> To me, what I'm trying to do seems reasonable. It'd be nice if the
> UserName key was respected for agents installed in the system-wide
> LaunchAgents directory, so the agent would run in the GUI context of a
> certain user, but would be out-of-reach (to unprivileged users) as far
> as unloading or killing the process. On the other hand, I suppose
> respecting the UserName key conflicts with the whole notion of
> LaunchAgents running on behalf of the current user. Is my request
> reasonable or am I missing something?

What you're trying to do is reasonable. The way you think it ought to  
be accomplished is not. The per-user launchd runs as the user, so  
having it setuid(2) its children won't work. And we're not going to  
have it run as root.

You're attempting to enforce restrictions on your particular part of  
an otherwise completely open environment. You need to enforce  
restrictions from a secure environment, not from the environment  
you're trying to restrict. You should store sensitive and privileged  
data in your daemon and vend it to the agent after it has had the user  
jump through the necessary hoops.

> I'll also say that I've found a way to do what I need, but it directly
> violates the 10 Commandments of Launchd Agents. I would be eternally
> grateful if someone could suggest semi-rule-abiding way to secure a
> LaunchAgent from being controlled without authorization.

It would help if we knew why the GUI portion of your architecture is  
sacrosanct and must be secured, rather than being just a security  
interface. I'm reminded of many action movies where the hero must  
break through a door, so he smashes the numeric keypad controlling  
access to it, and somehow that opens the door. That's the kind of  
security architecture I'm seeing here.

As an example, on Mac OS X, SecurityAgent runs as the user, and the  
user can kill it if he wishes. We have no problems with this. It just  
means that the user won't get the rights that he is requesting from  
the daemon. The daemon (which runs as root) is secured and can't be  
manipulated by the user.
-- 
Damien Sorresso
BSD Engineering
Apple Inc.

-------------- next part --------------
A non-text attachment was scrubbed...
Name: smime.p7s
Type: application/pkcs7-signature
Size: 2425 bytes
Desc: not available
URL: <http://lists.macosforge.org/pipermail/launchd-dev/attachments/20090501/938980e1/attachment.bin>


More information about the launchd-dev mailing list