macOS Mojave Startup Daemons and Agents – Beyond the GUI
For a couple days now I’ve been getting an annoying startup message from an Adobe app that launches at boot time on my MacBook Pro. After I log in and the GUI appears, I get a message that an Adobe application isn’t optimized for my Mac and that it needs to be updated. Uh, ok. If there’s one thing I hate it’s applications that secretly slip a bunch of applications or services in to your machine that launch at system startup or user login. It slows boot time / login time, and at best, these are “helper” applications for applications that you may or may not use during that session. At worst, they’re little tattle-tale phone-home apps that gather information that you don’t really want to share, but somehow agreed to share because you accepted a 200 page EULA that you didn’t read.
First thing I did was what anyone else would do in this scenario. System Preferences > Users and Groups > Login Items.
Hmm. No Adobe apps here, but I know that they’re launching either when the OS loads, or when I log in (or both).
After doing some digging I found out that there are two ways to see everything that loads at either startup and/or user login. The first way is to install one of my “cleaner” apps that will show these items to you via a GUI and let you disable them. These solutions range from free to around $50, but after seeing the uninstallation instructions for a few of them, it seemed that they scattered more garbage across the OS than what I was trying to remove. Not to mention that traditionally apps like this have been known to contain all sorts of malware. No thanks.
The second involves the command line. macOS is one of the closest OS’ we have today to what traditional UNIX was (BSD > NextStep > OSX > macOS), so I’m thankful for that. A system process called launchd loads specifically formatted .plist files, which are essentially XML files that specify applications to launch under certain specific circumstances. The contents of these .plist files could specify that an application launch and run in the background, launch at specified intervals, or run as a result of a specific system event. Applications launched via .plist file can launch with either user permissions or root permissions depending on what is needed. There are a total of five directories where these .plist files are located. They are broken down in to two groups – User and System.
- /Library/LaunchDaemons – Launch when the system boots and runs as root
- /Library/LaunchAgents – Loads when any user logs in and runs as that user
- /Users/username/Library/LaunchAgents – Loads when that user logs in and runs as that user
- /System/Library/LaunchDaemons – Launch when the system boots and runs as root
- /System/Library/LaunchAgents – Loads when any user logs in and runs as that user
You should not remove or edit .plist files that exist in either of the System locations. These files are required for the OS to work properly. After a clean install, with the exception of one or two .com.apple.*.plist files, the User locations are empty, and will slowly populate with scripts as you install new applications. Some of these scripts are important for the applications to function, and some are not.
Security Regarding .plist Files
Let’s take a look at the contents of one. This is a .plist file for VirtualBox that’s located in /Library/LaunchDaemons. It was placed there after installation VirtualBox.
Given the location of this file we known that it will launch when the system starts up, and it will run as the root user. Looking at the XML, we can see that it has a description, is not disabled, will run at load, will run once and then terminate, and the actual action taken is to run a VirtualBoxStartup.sh script that’s located in /Library/Application Support/VirtualBox/LaunchDaemons/VirtualBoxStartup.sh.
I know what some of you are thinking – “Here’s a script that runs as root at system startup. What fun things could we add to that script?” And you’d be right. If the wrong group or user is given permission to modify this file, this could be a security risk. Let’s check permissions on the script, just to make sure.
As we can see here, the owner of the file has read, write and execute permissions. All other users only have read and execute, not write. This is good, as a regular as system user wouldn’t be able to modify this script and therefore be able to run commands as root by simply restarting the system and having the script run. As a good measure though, if you are really concerned about the security of your system, you should be aware of what .plist files are in the /Library/LaunchDaemons and check the permissions of any script that is run by these .plist files to ensure that permissions are set correctly. It could easily happen that a lazy developer of a third party application not set permissions correctly and open your system up to a potential vulnerability very easily. /Library/LaunchDaemons is much more important than /Library/LaunchAgents or /User/username/Library/LaunchAgents, since the latter two run scripts with only user permissions, not as root.
Cleaning Up Startup Items
Now that you know how .plist files work and what they do, it shouldn’t be difficult to weed out any application scripts that you don’t want. You’ll need to su to escalate privileges before you edit .plist files in their default locations, as the root user is the owner of all of them and is the only user who has write access. I would recommend moving files from their default location and in to a backup folder so they can be replaced if it turns out that removing them breaks applications, as opposed to just deleting them and hoping for the best. For the couple of Adobe CS applications I have installed, removing all of the com.adobe.* files from the above User locations didn’t affect any of those applications’ ability to load and work properly.
If you enjoyed this tutorial and would like to see more, please feel free to share this article on social media, comment below letting me know what else you’d like to see, and follow me on Twitter @JROlmstead.