The function -[Launchd itemObject:] attempts to find the executable by parsing the plist of a newly installed launch agent. The checks on the parsed data are lacking, making it possible to crash the BlockBlock service, thereby bypassing its checks.
The check to make sure that itemBinary is an NSString on line 125 is performed after already calling -length on it on line 118. In addition, the goto bail on line 121 does not nil itemBinary, which means that it will be returned, but without checking its class.
By providing a launchd configuration where Program is an NSData object of length 0 (which also responds to -length), the check on line 118 will cause it to go to bail, which means that the empty NSData object is returned. Then on line 75, -lastPathComponent will be called on an NSData object, causing an exception.
When the BlockBlock service crashes, it stops checking for new or modified launch agents. Unless the user is looking at the Console logs carefully, it is not possible to tell that BlockBlock has crashed. The menu item keeps working and no crash reporter opens.
Recommendation
I recommend:
Check the type of each value read from the plist file before using it.
Make sure that invalid data crashing the BlockBlock service can not be used to hide the installation of a new launch agent. For example, by catching exceptions in the service, restarting it automatically or triggering a notification from the helper when the connection to the service is lost.
The function
-[Launchd itemObject:]
attempts to find the executable by parsing the plist of a newly installed launch agent. The checks on the parsed data are lacking, making it possible to crash the BlockBlock service, thereby bypassing its checks.https://github.com/objective-see/BlockBlock/blob/7e2712e7aeb6a32e3b6b575dde7840f5d3d1ab7e/Daemon/Daemon/Plugins/Launchd.m#L108-L140
The check to make sure that
itemBinary
is anNSString
on line 125 is performed after already calling-length
on it on line 118. In addition, thegoto bail
on line 121 does not nilitemBinary
, which means that it will be returned, but without checking its class.By providing a launchd configuration where
Program
is anNSData
object of length 0 (which also responds to-length
), the check on line 118 will cause it to go tobail
, which means that the emptyNSData
object is returned. Then on line 75,-lastPathComponent
will be called on anNSData
object, causing an exception.For example, the following plist file:
Triggers this exception:
When the BlockBlock service crashes, it stops checking for new or modified launch agents. Unless the user is looking at the Console logs carefully, it is not possible to tell that BlockBlock has crashed. The menu item keeps working and no crash reporter opens.
Recommendation
I recommend: