common,w32: Breakaway detached childs when in job

* common/exechelp-w32.c (gnupg_spawn_process_detached): Add
CREATE_BREAKAWAY_FROM_JOB creation flag if required.

--
When the gpg process is assigned to a W32 "Job" the
child processes are killed once the Job is finished.
As we want our detached processes to linger e.g.
gpg-agent the breakaway flag is required in
that case.

GnuPG-Bug-Id: T4333

Thanks to Jan Echternach for reporting this and providing
a patch.

Signed-off-by: Andre Heinecke <aheinecke@gnupg.org>
This commit is contained in:
Andre Heinecke 2019-04-29 08:54:39 +02:00
parent 874bc970ba
commit 03df28b18b
No known key found for this signature in database
GPG Key ID: 2978E9D40CBABA5C
1 changed files with 45 additions and 0 deletions

View File

@ -856,6 +856,7 @@ gnupg_spawn_process_detached (const char *pgmname, const char *argv[],
STARTUPINFO si;
int cr_flags;
char *cmdline;
BOOL in_job = FALSE;
/* We don't use ENVP. */
@ -884,6 +885,50 @@ gnupg_spawn_process_detached (const char *pgmname, const char *argv[],
| GetPriorityClass (GetCurrentProcess ())
| CREATE_NEW_PROCESS_GROUP
| DETACHED_PROCESS);
/* Check if we were spawned as part of a Job.
* In a job we need to add CREATE_BREAKAWAY_FROM_JOB
* to the cr_flags, otherwise our child processes
* are killed when we terminate. */
if (!IsProcessInJob (GetCurrentProcess(), NULL, &in_job))
{
log_error ("IsProcessInJob() failed: %s\n", w32_strerror (-1));
in_job = FALSE;
}
if (in_job)
{
/* Only try to break away from job if it is allowed, otherwise
* CreateProcess() would fail with an "Access is denied" error. */
JOBOBJECT_EXTENDED_LIMIT_INFORMATION info;
if (!QueryInformationJobObject (NULL, JobObjectExtendedLimitInformation,
&info, sizeof info, NULL))
{
log_error ("QueryInformationJobObject() failed: %s\n",
w32_strerror (-1));
}
else if ((info.BasicLimitInformation.LimitFlags &
JOB_OBJECT_LIMIT_BREAKAWAY_OK))
{
log_debug ("Using CREATE_BREAKAWAY_FROM_JOB flag\n");
cr_flags |= CREATE_BREAKAWAY_FROM_JOB;
}
else if ((info.BasicLimitInformation.LimitFlags &
JOB_OBJECT_LIMIT_SILENT_BREAKAWAY_OK))
{
/* The child process should automatically detach from the job. */
log_debug ("Not using CREATE_BREAKAWAY_FROM_JOB flag; "
"JOB_OBJECT_LIMIT_SILENT_BREAKAWAY_OK is set\n");
}
else
{
/* It seems that the child process must remain in the job.
* This is not necessarily an error, although it can cause premature
* termination of the child process when the job is closed. */
log_debug ("Not using CREATE_BREAKAWAY_FROM_JOB flag\n");
}
}
/* log_debug ("CreateProcess(detached), path='%s' cmdline='%s'\n", */
/* pgmname, cmdline); */
if (!CreateProcess (pgmname, /* Program to start. */