Post

Replies

Boosts

Views

Activity

utmpx reports several session for the same user
Hello, My app (daemon) time to time need to know list of GUI login sessions. According to the recommendation, I am using getutxent(). https://developer.apple.com/library/archive/qa/qa1133/_index.html However, I have faced with unclear behaviour in case of running "Migration Assistant". It can be re-created without my app. Steps to recreate: login as 'user #1' start "Migration Assistant" quit "Migration Assistant" new login prompt will be opened login as 'user #2' In spite the session of 'user #1' is closed, the command line tool "who", which gathers information from /var/run/utmpx, reports opened sessions of 'user #1'. Is it bug or feature? Thank you in advance!
7
0
319
Jul ’25
Issue to reset "Privacy & Security" permissions
Hello, I am working on a script to update an application which bundle ID changed. Only the bundle ID was modified; all other aspects remain unchanged. This application requires access to "Screen & System Audio Recording" permissions, which are currently granted to the old bundle ID. The script performs the following steps: launchctl bootout gui/$(id -u) /Library/LaunchAgents/com.my_agent_1.plist pkgutil --forget com.my_agent_1 tccutil reset All com.my_agent_1 rm /Library/LaunchAgents/com.my_agent_1.plist rm -rf </path/to/com_my_agent_1> installer -dumplog -allowUntrusted -pkg </path/to/com_my_agent_2.pkg> -target / ... When running steps #1-6 without a restart between steps #5 and #6, the old bundle ID (com.my_agent_1) remains visible in TCC.db (verified via SQL queries). Looks like this is the reason why "com.my_agent_2" is not automatically added to the permission list (requiring manual add). Moreover, "tccutil reset All com.my_agent_1" does not work anymore, the error: tccutil: No such bundle identifier "com.my_agent_1": The operation couldn’t be completed. (OSStatus error -10814.) Is there any way to completely clear the "Privacy & Security" permissions without requiring a system restart? Thank you a lot for your help in advance!
0
0
279
Jun ’25
get Wi-Fi controller info
Hello, I'm trying to get a list of all network devices (device audit for DLP system). CFMutableDictionaryRef matchingDictionary = IOServiceMatching(kIONetworkControllerClass); if (matchingDictionary == nullptr) { std::cerr << "IOServiceMatching() returned empty matching dictionary" << std::endl; return 1; } io_iterator_t iter; if (kern_return_t kr = IOServiceGetMatchingServices(kIOMasterPortDefault, matchingDictionary, &iter); kr != KERN_SUCCESS) { std::cerr << "IOServiceGetMatchingServices() failed" << std::endl; return 1; } io_service_t networkController; while ((networkController = IOIteratorNext(iter)) != IO_OBJECT_NULL) { std::cout << "network device: "; if (CFDataRef cfIOMACAddress = (CFDataRef) IORegistryEntryCreateCFProperty(networkController, CFSTR(kIOMACAddress), kCFAllocatorDefault, kNilOptions); cfIOMACAddress != nullptr) { std::vector<uint8_t> data(CFDataGetLength(cfIOMACAddress)); CFDataGetBytes(cfIOMACAddress, CFRangeMake(0, data.size()), data.data()); std::cout << std::hex << std::setfill('0') << std::setw(2) << (short)data[0] << ":" << std::hex << std::setfill('0') << std::setw(2) << (short) data[1] << ":" << std::hex << std::setfill('0') << std::setw(2) << (short) data[2] << ":" << std::hex << std::setfill('0') << std::setw(2) << (short) data[3] << ":" << std::hex << std::setfill('0') << std::setw(2) << (short) data[4] << ":" << std::hex << std::setfill('0') << std::setw(2) << (short) data[5]; CFRelease(cfIOMACAddress); } std::cout << std::endl; IOObjectRelease(networkController); } IOObjectRelease(iter); The Wi-Fi controller shows up in I/O Registry Explorer, but IOServiceGetMatchingServices() does not return any information about it. Any way to retrieve Wi-Fi controller info in daemon code? Thank you in advance!
3
0
229
Jun ’25
public API which allows to get information about APFS
Hello, I am working on a daemon which collects information about disk space usage on macOS. APFS has quite complex structure and there is a challenge to get detailed info. My application must provide disk usage by APFS containers. Are there any recommended way to get space usage by particular APFS volume? Are there any recommended way to get free space on particular APFS container? Are there any recommended way to enumerate APFS containers and volumes? I am using Disk Arbitration to get APFS info. However, I get restricted info about space usage because I get get disk usage for mounted volumes only. Are there any public API (daemon-safe) which allows to easily get disk space usage on macOS? Thank you in advance, Pavel
6
0
252
May ’25
get space which is used on an APFS volume
Hello, I am trying to get space which is consumed by APFS volume. The call getattrlist() works fine on macOS 15 (Apple silicon). However, it returns EINVAL on macOS 11.7.10 (Intel) if ATTR_VOL_SPACEUSED is defined. struct VolAttrBuf { u_int32_t length; off_t spaceUsed; } __attribute__((aligned(4), packed)); int64_t GetVolumeSpaceUsed(const std::string& mountPath) { struct attrlist attrList; std::memset(&attrList, 0, sizeof(attrList)); attrList.bitmapcount = ATTR_BIT_MAP_COUNT; attrList.volattr = ATTR_VOL_INFO | ATTR_VOL_SPACEUSED; VolAttrBuf attrBuf; if (getattrlist(mountPath.c_str(), &attrList, &attrBuf, sizeof(attrBuf), 0) || attrBuf.length > sizeof(attrBuf)) { std::cout << "getattrlist() failed with errno (" << errno << ")" << std::endl; return -1; } return attrBuf.spaceUsed; } Is it bug or ATTR_VOL_SPACEUSED is unsupported on macOS 11? Are there any other way to get space which is used on an APFS volume? (C++) Thank you in advance, Pavel
2
0
242
May ’25
synchronize a file's state with that on disk
Hello Dev, The App, which I am working on, uses fcopyfile() to copy file from external storage (USB, thunderbolt) to internal disk. Looks like this call provides the best performance. fcopyfile(from, to, nullptr, COPYFILE_DATA); I need to be sure the data is copied after the call. Are there any necessity to synchronize a file's state with that on disk the data? (e.g. call fsync()) Thank you in advance! Pavel
2
0
293
Mar ’25
extract file system type from es_event_mount_t
Hello, es_event_mount_t includes statfs structure. This structure has the field 'f_type' which defines type of filesystem. However, man page says nothing about possible values of this field. What is the best way to define file system type? Can I use 'f_type' or 'f_fstypename'? If so, are there any constants in header files which can be used? Thank you for your help!
4
0
487
Feb ’25
Monitoring file modification events by Endpoint Security
Hello, My app needs to report whether a file, which is located on usb volume, is modified by specific application. I use Endpoint Security framework and I know about "Inferring High-Level Semantics from Low-Level Operations" problem. However, in spite of this limitation, I need to implement app which reports as much info as possible. I faced with some unclear behaviour of TestEdit. The scenario is: Open a file, which is located on usb volume, by TextEdit /dev/disk4s2 on /Volumes/USBVol (msdos, local, nodev, nosuid, noowners, noatime, fskit) Modify and save it Endpoint Security reports open and close events only (modified flag is false) ES_EVENT_TYPE_AUTH_COPYFILE, ES_EVENT_TYPE_AUTH_CLONE, ES_EVENT_TYPE_NOTIFY_UTIMES and ES_EVENT_TYPE_NOTIFY_WRITE are not reported by Endpoint Security (monitored all processes in system). (Looks like the same behaviour for Xcode) I am stuck in this moment. Are there any way to monitor file modification if user do it by TextEdit? Thank you in advance!
2
0
545
Jan ’25
st_dev of mount point directory is different to device ID of device-file
I have NTFS which is mounted on '/Volumes/usb_vol' #mount Filesystem Mounted on /dev/disk5s1 /Volumes/usb_vol The following simple code reports different values of device Id for device-file and mount point directory struct stat buf; for (int i = 1; i < argc; i++) { std::cout << argv[i] << std::endl; if (stat(argv[i], &buf) < 0) { continue; } if (S_ISBLK(buf.st_mode)) { std::cout << "st_rdev (" << major(buf.st_rdev) << "/" << minor(buf.st_rdev) << ") hex: " << std::hex << buf.st_rdev << std::endl; } else { std::cout << "st_dev (" << major(buf.st_dev) << "/" << minor(buf.st_dev) << ") hex: " << std::hex << buf.st_dev << std::endl; } } Output: /dev/disk5s1 st_rdev (1/22) hex: 1000016 /Volumes/usb_vol st_dev (48/119) hex: 30000077 I believe this is expected but I have not found any explanation of this behaviour. Are there any explanation of difference these values? I can assume the stat() will report (48/119) for all objects which are located on this file system. Is it correct? Thank you for the help!
7
0
663
Jan ’25
Kernel sends SIGKILL to process which is subscribed on ES_EVENT_TYPE_AUTH_OPEN
The kernel sends SIGKILL to application if it handles ES_EVENT_TYPE_AUTH_OPEN and lldb is attached to this process. App: int main(int /*argc*/, char** /*argv*/) { es_client_t *pEpClient = nullptr; es_new_client_result_t result = es_new_client(&pEpClient, ^(es_client_t *pClient, const es_message_t *pMessage) { switch (pMessage->event_type) { case ES_EVENT_TYPE_AUTH_OPEN: { uint32_t authorizedFlags = pMessage->event.open.fflag; if ((authorizedFlags & FREAD) || (authorizedFlags & FWRITE)) { std::filesystem::path filePath = std::string(pMessage->event.open.file->path.data, pMessage->event.open.file->path.length); std::string fileName = filePath.filename(); if (fileName == "test.txt") { std::cout << "blocked fileName: " << filePath.filename() << std::endl; authorizedFlags &= ~FWRITE; authorizedFlags &= ~FREAD; } } if (es_respond_flags_result(pClient, pMessage, authorizedFlags, false) != ES_RESPOND_RESULT_SUCCESS) { std::cout << "es_respond_flags_result() failed with error " << std::endl; } } break; default: break; } }); if (result != ES_NEW_CLIENT_RESULT_SUCCESS) { std::cout << "es_new_client() failed." << std::endl; return 1; } es_event_type_t eventsList[] = { ES_EVENT_TYPE_AUTH_OPEN }; if (es_subscribe(pEpClient, eventsList, 1) == ES_RETURN_ERROR) { std::cout << "es_subscribe() failed." << std::endl; } // wait int i = 0; std::cin >> i; if (es_delete_client(pEpClient) == ES_RETURN_ERROR) { std::cout << "es_delete_client() failed." << std::endl; } return 0; } (lldb) process attach --pid 61127 .... (lldb) c Process 61127 resuming Process 61127 exited with status = 9 (0x00000009) Terminated due to signal 9 System log: Allowing set_exception_ports from [debugserver] on [ep_sample] for entitled process/debugger Client did not respond in appropriate amount of time (client pid: 61127), sent SIGKILL
2
0
835
Oct ’24
WindowServer daemon crashes
The scenario is quite simple run an application which uses [SCShareableContent getShareableContentExcludingDesktopWindows] and invoke captureImageWithFilter in completionHandler. delay invoking captureImageWithFilter for several seconds and switch user session before call it. The WindowServer crashes if app runs in inactive session. How to manage this issue correctly? Are there any way to avoid this crash?
1
0
757
Aug ’24
utmpx reports several session for the same user
Hello, My app (daemon) time to time need to know list of GUI login sessions. According to the recommendation, I am using getutxent(). https://developer.apple.com/library/archive/qa/qa1133/_index.html However, I have faced with unclear behaviour in case of running "Migration Assistant". It can be re-created without my app. Steps to recreate: login as 'user #1' start "Migration Assistant" quit "Migration Assistant" new login prompt will be opened login as 'user #2' In spite the session of 'user #1' is closed, the command line tool "who", which gathers information from /var/run/utmpx, reports opened sessions of 'user #1'. Is it bug or feature? Thank you in advance!
Replies
7
Boosts
0
Views
319
Activity
Jul ’25
Issue to reset "Privacy & Security" permissions
Hello, I am working on a script to update an application which bundle ID changed. Only the bundle ID was modified; all other aspects remain unchanged. This application requires access to "Screen & System Audio Recording" permissions, which are currently granted to the old bundle ID. The script performs the following steps: launchctl bootout gui/$(id -u) /Library/LaunchAgents/com.my_agent_1.plist pkgutil --forget com.my_agent_1 tccutil reset All com.my_agent_1 rm /Library/LaunchAgents/com.my_agent_1.plist rm -rf </path/to/com_my_agent_1> installer -dumplog -allowUntrusted -pkg </path/to/com_my_agent_2.pkg> -target / ... When running steps #1-6 without a restart between steps #5 and #6, the old bundle ID (com.my_agent_1) remains visible in TCC.db (verified via SQL queries). Looks like this is the reason why "com.my_agent_2" is not automatically added to the permission list (requiring manual add). Moreover, "tccutil reset All com.my_agent_1" does not work anymore, the error: tccutil: No such bundle identifier "com.my_agent_1": The operation couldn’t be completed. (OSStatus error -10814.) Is there any way to completely clear the "Privacy & Security" permissions without requiring a system restart? Thank you a lot for your help in advance!
Replies
0
Boosts
0
Views
279
Activity
Jun ’25
block keyboard and camera due to security reason
Hello, As part of developing a DLP system, I need to block input devices upon detection of data leakage. Could you advise if it's possible to temporarily disable the built-in keyboard and camera? Thank you in advance, Pavel
Replies
4
Boosts
0
Views
589
Activity
Jun ’25
get Wi-Fi controller info
Hello, I'm trying to get a list of all network devices (device audit for DLP system). CFMutableDictionaryRef matchingDictionary = IOServiceMatching(kIONetworkControllerClass); if (matchingDictionary == nullptr) { std::cerr << "IOServiceMatching() returned empty matching dictionary" << std::endl; return 1; } io_iterator_t iter; if (kern_return_t kr = IOServiceGetMatchingServices(kIOMasterPortDefault, matchingDictionary, &iter); kr != KERN_SUCCESS) { std::cerr << "IOServiceGetMatchingServices() failed" << std::endl; return 1; } io_service_t networkController; while ((networkController = IOIteratorNext(iter)) != IO_OBJECT_NULL) { std::cout << "network device: "; if (CFDataRef cfIOMACAddress = (CFDataRef) IORegistryEntryCreateCFProperty(networkController, CFSTR(kIOMACAddress), kCFAllocatorDefault, kNilOptions); cfIOMACAddress != nullptr) { std::vector<uint8_t> data(CFDataGetLength(cfIOMACAddress)); CFDataGetBytes(cfIOMACAddress, CFRangeMake(0, data.size()), data.data()); std::cout << std::hex << std::setfill('0') << std::setw(2) << (short)data[0] << ":" << std::hex << std::setfill('0') << std::setw(2) << (short) data[1] << ":" << std::hex << std::setfill('0') << std::setw(2) << (short) data[2] << ":" << std::hex << std::setfill('0') << std::setw(2) << (short) data[3] << ":" << std::hex << std::setfill('0') << std::setw(2) << (short) data[4] << ":" << std::hex << std::setfill('0') << std::setw(2) << (short) data[5]; CFRelease(cfIOMACAddress); } std::cout << std::endl; IOObjectRelease(networkController); } IOObjectRelease(iter); The Wi-Fi controller shows up in I/O Registry Explorer, but IOServiceGetMatchingServices() does not return any information about it. Any way to retrieve Wi-Fi controller info in daemon code? Thank you in advance!
Replies
3
Boosts
0
Views
229
Activity
Jun ’25
public API which allows to get information about APFS
Hello, I am working on a daemon which collects information about disk space usage on macOS. APFS has quite complex structure and there is a challenge to get detailed info. My application must provide disk usage by APFS containers. Are there any recommended way to get space usage by particular APFS volume? Are there any recommended way to get free space on particular APFS container? Are there any recommended way to enumerate APFS containers and volumes? I am using Disk Arbitration to get APFS info. However, I get restricted info about space usage because I get get disk usage for mounted volumes only. Are there any public API (daemon-safe) which allows to easily get disk space usage on macOS? Thank you in advance, Pavel
Replies
6
Boosts
0
Views
252
Activity
May ’25
get space which is used on an APFS volume
Hello, I am trying to get space which is consumed by APFS volume. The call getattrlist() works fine on macOS 15 (Apple silicon). However, it returns EINVAL on macOS 11.7.10 (Intel) if ATTR_VOL_SPACEUSED is defined. struct VolAttrBuf { u_int32_t length; off_t spaceUsed; } __attribute__((aligned(4), packed)); int64_t GetVolumeSpaceUsed(const std::string& mountPath) { struct attrlist attrList; std::memset(&attrList, 0, sizeof(attrList)); attrList.bitmapcount = ATTR_BIT_MAP_COUNT; attrList.volattr = ATTR_VOL_INFO | ATTR_VOL_SPACEUSED; VolAttrBuf attrBuf; if (getattrlist(mountPath.c_str(), &attrList, &attrBuf, sizeof(attrBuf), 0) || attrBuf.length > sizeof(attrBuf)) { std::cout << "getattrlist() failed with errno (" << errno << ")" << std::endl; return -1; } return attrBuf.spaceUsed; } Is it bug or ATTR_VOL_SPACEUSED is unsupported on macOS 11? Are there any other way to get space which is used on an APFS volume? (C++) Thank you in advance, Pavel
Replies
2
Boosts
0
Views
242
Activity
May ’25
get display name and vendor info by IOKit framework
Hello, What is the best and Apple recommended way to get display name and its vendor information? The CoreGraphics framework provides ModelNumber and VendorNumber only. Looks like IOKit does not provide any documented way at all. Are there any daemon safe way to get such information? Thank you in advance, Pavel
Replies
4
Boosts
0
Views
225
Activity
Apr ’25
synchronize a file's state with that on disk
Hello Dev, The App, which I am working on, uses fcopyfile() to copy file from external storage (USB, thunderbolt) to internal disk. Looks like this call provides the best performance. fcopyfile(from, to, nullptr, COPYFILE_DATA); I need to be sure the data is copied after the call. Are there any necessity to synchronize a file's state with that on disk the data? (e.g. call fsync()) Thank you in advance! Pavel
Replies
2
Boosts
0
Views
293
Activity
Mar ’25
extract file system type from es_event_mount_t
Hello, es_event_mount_t includes statfs structure. This structure has the field 'f_type' which defines type of filesystem. However, man page says nothing about possible values of this field. What is the best way to define file system type? Can I use 'f_type' or 'f_fstypename'? If so, are there any constants in header files which can be used? Thank you for your help!
Replies
4
Boosts
0
Views
487
Activity
Feb ’25
Monitoring file modification events by Endpoint Security
Hello, My app needs to report whether a file, which is located on usb volume, is modified by specific application. I use Endpoint Security framework and I know about "Inferring High-Level Semantics from Low-Level Operations" problem. However, in spite of this limitation, I need to implement app which reports as much info as possible. I faced with some unclear behaviour of TestEdit. The scenario is: Open a file, which is located on usb volume, by TextEdit /dev/disk4s2 on /Volumes/USBVol (msdos, local, nodev, nosuid, noowners, noatime, fskit) Modify and save it Endpoint Security reports open and close events only (modified flag is false) ES_EVENT_TYPE_AUTH_COPYFILE, ES_EVENT_TYPE_AUTH_CLONE, ES_EVENT_TYPE_NOTIFY_UTIMES and ES_EVENT_TYPE_NOTIFY_WRITE are not reported by Endpoint Security (monitored all processes in system). (Looks like the same behaviour for Xcode) I am stuck in this moment. Are there any way to monitor file modification if user do it by TextEdit? Thank you in advance!
Replies
2
Boosts
0
Views
545
Activity
Jan ’25
character encoding in Endpoint Security events
Hello, My app is handling ES_EVENT_TYPE_AUTH_OPEN. Which character encoding is used in Endpoint Security events? (es_file_t) Thank you in advance, Pavel
Replies
2
Boosts
0
Views
463
Activity
Jan ’25
st_dev of mount point directory is different to device ID of device-file
I have NTFS which is mounted on '/Volumes/usb_vol' #mount Filesystem Mounted on /dev/disk5s1 /Volumes/usb_vol The following simple code reports different values of device Id for device-file and mount point directory struct stat buf; for (int i = 1; i < argc; i++) { std::cout << argv[i] << std::endl; if (stat(argv[i], &buf) < 0) { continue; } if (S_ISBLK(buf.st_mode)) { std::cout << "st_rdev (" << major(buf.st_rdev) << "/" << minor(buf.st_rdev) << ") hex: " << std::hex << buf.st_rdev << std::endl; } else { std::cout << "st_dev (" << major(buf.st_dev) << "/" << minor(buf.st_dev) << ") hex: " << std::hex << buf.st_dev << std::endl; } } Output: /dev/disk5s1 st_rdev (1/22) hex: 1000016 /Volumes/usb_vol st_dev (48/119) hex: 30000077 I believe this is expected but I have not found any explanation of this behaviour. Are there any explanation of difference these values? I can assume the stat() will report (48/119) for all objects which are located on this file system. Is it correct? Thank you for the help!
Replies
7
Boosts
0
Views
663
Activity
Jan ’25
How to find relationship between logged-in users and processes?
Hello, Let's say I have several opened user sessions in parallel. Endpoint Security notify about executing a process (ES_EVENT_TYPE_NOTIFY_EXEC) and provide audit token. The goal is to find relationship between logged-in users and new process. Can I use audit user ID for this? Thank you in advance.
Replies
6
Boosts
0
Views
729
Activity
Dec ’24
Kernel sends SIGKILL to process which is subscribed on ES_EVENT_TYPE_AUTH_OPEN
The kernel sends SIGKILL to application if it handles ES_EVENT_TYPE_AUTH_OPEN and lldb is attached to this process. App: int main(int /*argc*/, char** /*argv*/) { es_client_t *pEpClient = nullptr; es_new_client_result_t result = es_new_client(&pEpClient, ^(es_client_t *pClient, const es_message_t *pMessage) { switch (pMessage->event_type) { case ES_EVENT_TYPE_AUTH_OPEN: { uint32_t authorizedFlags = pMessage->event.open.fflag; if ((authorizedFlags & FREAD) || (authorizedFlags & FWRITE)) { std::filesystem::path filePath = std::string(pMessage->event.open.file->path.data, pMessage->event.open.file->path.length); std::string fileName = filePath.filename(); if (fileName == "test.txt") { std::cout << "blocked fileName: " << filePath.filename() << std::endl; authorizedFlags &= ~FWRITE; authorizedFlags &= ~FREAD; } } if (es_respond_flags_result(pClient, pMessage, authorizedFlags, false) != ES_RESPOND_RESULT_SUCCESS) { std::cout << "es_respond_flags_result() failed with error " << std::endl; } } break; default: break; } }); if (result != ES_NEW_CLIENT_RESULT_SUCCESS) { std::cout << "es_new_client() failed." << std::endl; return 1; } es_event_type_t eventsList[] = { ES_EVENT_TYPE_AUTH_OPEN }; if (es_subscribe(pEpClient, eventsList, 1) == ES_RETURN_ERROR) { std::cout << "es_subscribe() failed." << std::endl; } // wait int i = 0; std::cin >> i; if (es_delete_client(pEpClient) == ES_RETURN_ERROR) { std::cout << "es_delete_client() failed." << std::endl; } return 0; } (lldb) process attach --pid 61127 .... (lldb) c Process 61127 resuming Process 61127 exited with status = 9 (0x00000009) Terminated due to signal 9 System log: Allowing set_exception_ports from [debugserver] on [ep_sample] for entitled process/debugger Client did not respond in appropriate amount of time (client pid: 61127), sent SIGKILL
Replies
2
Boosts
0
Views
835
Activity
Oct ’24
WindowServer daemon crashes
The scenario is quite simple run an application which uses [SCShareableContent getShareableContentExcludingDesktopWindows] and invoke captureImageWithFilter in completionHandler. delay invoking captureImageWithFilter for several seconds and switch user session before call it. The WindowServer crashes if app runs in inactive session. How to manage this issue correctly? Are there any way to avoid this crash?
Replies
1
Boosts
0
Views
757
Activity
Aug ’24