OK, that's it for setting and querying restrictions. Now let's get back to my StartRestrictedProcess function. After I place some restrictions on the job, I spawn the process that I intend to place in the job by calling CreateProcess. However, notice that I use the CREATE_SUSPENDED flag when calling CreateProcess. This creates the new process but doesn't allow it to execute any code. Since the StartRestrictedProcess function is being executed from a process that is not part of a job, the child process will also not be part of a job. If I were to allow the child process to immediately start executing code, it would run out of my sandbox and could successfully do things that I want to restrict it from doing. So after I create the child process and before I allow it to start running, I must explicitly place the process in my newly created job by calling the following:
BOOL AssignProcessToJobObject( HANDLE hJob, HANDLE hProcess); |
This function tells the system to treat the process (identified by hProcess) as part of an existing job (identified by hJob). Note that this function allows only a process that is not assigned to any job to be assigned to a job. Once a process is part of a job, it cannot be moved to another job and it cannot become jobless (so to speak). Also note that when a process that is part of job spawns another process, the new process is automatically made part of the parent's job. However, you can alter this behavior in the following ways:
As for my StartRestrictedProcess function, after I call AssignProcessToJobObject, my new process is part of my restricted job. I then call ResumeThread so that the process's thread can execute code under the job's restrictions. At this point, I also close the handle to the thread since I no longer need it.