I noticed today that Adobe Desktop Services is constantly monitoring /etc/passwd.

enter image description here

Would would be the point? Passwords are not stored in /etc/passwd so why would an app monitor /etc/passwd? What info might they be trying to monitor?


Adobe Desktop Service wasn’t looking at your /etc/passwd. Apple’s system library was.

Apple’s system library wanted to know your username so it can find your home directory. It then decided the best way to figure out your username was to look it up in /etc/passwd. Adobe Desktop Service just wanted to know the path to your home directory, and (correctly) used the CoreFoundation framework for that. That’s why the call appears under Adobe’s process.


In your screenshot, the Caller entry says something like _fsi_get_user. This is the symbol of a private subroutine in one of macOS’s system libraries, libsystem_info.dylib, located in /usr/lib/system.

The public source code of the _fsi_get_user function reveals the following logic:

if (geteuid() == 0)
  // […]
  f = fopen(_PATH_PASSWD, "r");
  _fsi_get_validation(si, VALIDATION_PASSWD, _PATH_PASSWD, f, &va, &vb);
  fmt = 1;

Looking at the decompiled code in libsystem_info.dylib (for example, using Hopper Disassembler) confirms that _PATH_PASSWD is indeed the file name /etc/passwd. (The source code further down in file_module.c also explains why there’s a call to fstat immediately after the fopen: the implementation of _fsi_get_validation does that to figure out the last modification time of your /etc/passwd.)

In other words: Adobe wasn’t looking at your passwd file; Apple’s system library was.

Connecting the dots

There are many possible call stacks that may connect Adobe Desktop Service’s code to the _fsi_get_user function. A bit of static analysis suggests the most plausible candidate would be NSHomeDirectory, a utility class in Foundation.framework.

Looking at Adobe Desktop Service’s binary reveals that it indeed calls [NSHomeDirectory UTF8String]:

*100032ac4   call   imp___stubs__NSHomeDirectory
*100032ac9   mov    rsi, qword [0x10008a178]  ; "UTF8String"
*100032ad0   mov    rdi, rax
*100032ad3   call   qword [_objc_msgSend_100088350]

Apple’s implementation of NSHomeDirectory will then lead us to /etc/passwd fairly quickly. My educated guess on the most likely chain of function calls would be:

Adobe Desktop Service → [NSHomeDirectory UTF8String] (in Foundation.framework) → NSHomeDirectoryForUserCFCopyHomeDirectoryURLForUser (in CoreFoundation.framework) → _CFCopyHomeDirURLForUsergetpwuid (in libsystem_info.dylib, re-exported via libSystem.B.dylib) → si_user_byuid (this is where Apple decides at runtime which source it’s going to use. For example, if your user ID is between 1 and 499, your /etc/passwd will be consulted instead of Directory Services.) → file_user_byuid_fsi_get_user.

To be extra sure, I further analyzed the binary Adobe Desktop Service and as expected, it contains no single reference to /etc/passwd. (I haven’t checked whether or not Adobe Desktop Service does other shady things, though.)

The whole analysis would have been a little easier if you had actually clicked on one of the entries before you created the screenshot. Your app would then have shown the relevant stack trace in the bottom right corner (it’s the lines where it says Stack Trace). But hey, I had a lot of fun figuring it out, and I’ve learned a lot that way!


To confirm that my analysis is correct, you may want to click on one of the /etc/passwd entries in your Instruments app and find the terms NSHomeDirectory and file_user_byuid somewhere in the stack trace.

| improve this answer | |

From the information in your screenshot, the program is not trying to "monitor" the contents of the file. It is instead repeatedly asking for the metadata about the file (i.e. does the file exists, how large is it, when was it created, etc).

Only Adobe can tell you why they have coded their program the way they did.

However note that there are multiple logical explanations of why they did what they did - that does not involve any "spying" or "nefarious" activities.

For example this particular daemon program (i.e. background service) might constantly check for the existence of /etc/password in order to determine that it is (a) not sandboxed, and (b) not stripped of its permissions so that it is forbidden to examine that file.

| improve this answer | |
  • The funny part is that it seems to close the file before calling fstat(). But this may be just a side effect of Instruments. – nohillside Dec 3 '18 at 12:04
  • @nohillside No it doesn’t. You must have misread the screenshot. Take a look again and you’ll see clearly that it opens, fstats and closes. You cannot call fstat() on a closed filedescriptor. – jksoegaard Dec 3 '18 at 12:40
  • 1
    Isn't the first column the sequence number, with the calls going from bottom to top? – nohillside Dec 3 '18 at 13:28

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .