问题
I want to Authorize USB/CD on Mac OS X. Now i am using DiskArbitration framework to get MountApprovalCallback in user mode. But the problem with this callback is that there is no assurance of it.
And if i'll get callback i am using CFUserNotificationReceiveResponse()
to accept password from user.
But when prompt is shown at the same time user can open DiskUtility and can mount a device
So,
- Is there any other way to get mount approval callback or to authorize a device?
- How i can handle it in kernel mode?
Thanks in advance.
回答1:
In a kext, you can get an authorisation callback for file system mount callbacks via the mpo_mount_check_mount
callback in the MAC (TrustedBSD) policy framework. You can decide whether the mount should go ahead or not in there. I suspect you won't get any information about the logged-in user from the cred
argument, as the mount syscall is probably initiated by the daemon running as root. I don't know what you're actually trying to do, so this might not be the best way to approach the problem for your specific case.
/**
@brief Access control check for mounting a file system
@param cred Subject credential
@param vp Vnode that is to be the mount point
@param vlabel Label associated with the vnode
@param cnp Component name for vp
@param vfc_name Filesystem type name
Determine whether the subject identified by the credential can perform
the mount operation on the target vnode.
@return Return 0 if access is granted, otherwise an appropriate value for
errno should be returned.
*/
typedef int mpo_mount_check_mount_t(
kauth_cred_t cred,
struct vnode *vp,
struct label *vlabel,
struct componentname *cnp,
const char *vfc_name
);
Note that this is an unsupported KPI, so Apple says it might go away or break in a future release. Indeed, the policy callback function signatures frequently change between major OS X releases, so you may need to check OS X version at runtime and use different functions for different versions. You'll also need to stay up to date with any betas that Apple releases, to see if they break your code.
With that out of the way, here's how you actually use it:
- You'll need to link against the MAC framework KPI, so add
com.apple.kpi.dsep
to your kext's OSBundleLibraries dictionary. (it uses darwin versioning, so use the same version as for the other com.apple.kpi.* bundles) - #include <security/mac_policy.h> in your code (it's already provided in Kernel.framework)
- Create a global variable, or allocate some memory on startup to hold a
struct mac_policy_ops
, and initialise any of the function pointer fields you're interested in, e.g.mpo_mount_check_mount
. - When your kext starts up, register your policy using
mac_policy_register()
and save the handle it returns. You'll need to configure your policy using amac_policy_conf
struct, where you setmpc_ops
to point to your policy struct,mpc_loadtime_flags
toMPC_LOADTIME_FLAG_UNLOADOK
,mpc_name
to a reverse-DNS identifier for your kext,mpc_fullname
to a human-readable string, and zero-initialise everything else. - You will immediately start receiving calls to your callbacks, possibly concurrently from many threads and processes, so be sure to make your callbacks threadsafe.
- Before unloading, your kext needs to deregister using
mac_policy_unregister()
and the handle you received frommac_policy_register()
.
A lot more information can be found in the header file.
来源:https://stackoverflow.com/questions/27702967/mount-approval-callback-on-mac-os-x