Job Object Insanity

Job Objects were introduced to Windows in Windows XP/Windows Server 2003 to allow an application to manage a group of processes.

One of the limitations of Job Objects is that a process can only belong to a single Job object.  This becomes an issue when you are attempting to manipulate a process which is already associated with a Job Object.  A process can be associated with a Job object through inheritance or via assignment (AssignProcessToJobObject API).  If you call AssignProcessToJobObject() to assign a Job to your process and it is already associated with a Job Object, the API will fail with error code 5 or "Access Denied".  (Note, error code 5 could have another meaning).

It turns out that Windows uses Job Objects for various scenarios such as:

  • A process launched via the Run As Command (This is implemented by calling CreateProcessWithLogonW. CreateProcessWithTokenW() is a similar API except for it uses a token for the user's identity)
  • Remote Desktop Client setting (mstsc.exe), "Start a Program"
  • The Task Scheduler

Based on the way Job Objects are designed, it may not be possible to disassociate a process from a Job.  (This is referred to as BREAKING AWAY)

If the Job wasn't created with JOB_OBJECT_LIMIT_SILENT_BREAKAWAY_OK or if the child wasn't launched with CREATE_BREAKAWAY_FROM_JOB + JOB_OBJECT_LIMIT_BREAKAWAY_OK, the process will not be able to disassociate from a Job.

If you can obtain a handle to the the Job Object, you could change the future behavior of the child process so that it could be broken away.  This requires the Job object to be named and the caller has to have the permissions to modify the Job object.  (This may not always be possible).

To address this limitation on Windows 8/Windows Server 2012, you can associate a process with more than 1 Job via a Nested Job.

See the following for more information on Nested Jobs:

https://msdn.microsoft.com/en-us/library/windows/desktop/hh448388(v=vs.85).aspx