From df357a03357bc921a786705cd43957bee9bc7363 Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Mon, 17 Apr 2023 14:10:00 +0900 Subject: [PATCH] Fix use of GNUPG_PROCESS_DETACHED. Signed-off-by: NIIBE Yutaka --- common/asshelp.c | 5 +---- common/exechelp-posix.c | 43 ++++++++++++++++-------------------- common/exechelp-w32.c | 48 +++++++++++++++++++---------------------- g13/be-encfs.c | 4 +--- scd/app.c | 5 +---- 5 files changed, 44 insertions(+), 61 deletions(-) diff --git a/common/asshelp.c b/common/asshelp.c index 41ba1796f..2053c55e6 100644 --- a/common/asshelp.c +++ b/common/asshelp.c @@ -524,10 +524,7 @@ start_new_service (assuan_context_t *r_ctx, { #ifdef HAVE_W32_SYSTEM err = gnupg_process_spawn (program? program : program_name, argv, - (GNUPG_PROCESS_DETACHED - |GNUPG_PROCESS_STDIN_NULL - |GNUPG_PROCESS_STDOUT_NULL - |GNUPG_PROCESS_STDERR_NULL), + GNUPG_PROCESS_DETACHED, NULL, NULL, NULL); #else /*!W32*/ err = gnupg_process_spawn (program? program : program_name, argv, diff --git a/common/exechelp-posix.c b/common/exechelp-posix.c index af79aab3e..363936068 100644 --- a/common/exechelp-posix.c +++ b/common/exechelp-posix.c @@ -1034,8 +1034,7 @@ my_exec (const char *pgmname, const char *argv[], struct spawn_cb_arg *sca) } static gpg_err_code_t -spawn_detached (gnupg_process_t process, - const char *pgmname, const char *argv[], +spawn_detached (const char *pgmname, const char *argv[], void (*spawn_cb) (struct spawn_cb_arg *), void *spawn_cb_arg) { gpg_err_code_t ec; @@ -1044,7 +1043,6 @@ spawn_detached (gnupg_process_t process, /* FIXME: Is this GnuPG specific or should we keep it. */ if (getuid() != geteuid()) { - xfree (process); xfree (argv); return GPG_ERR_BUG; } @@ -1052,7 +1050,6 @@ spawn_detached (gnupg_process_t process, if (access (pgmname, X_OK)) { ec = gpg_err_code_from_syserror (); - xfree (process); xfree (argv); return ec; } @@ -1064,7 +1061,6 @@ spawn_detached (gnupg_process_t process, { ec = gpg_err_code_from_syserror (); log_error (_("error forking process: %s\n"), gpg_strerror (ec)); - xfree (process); xfree (argv); return ec; } @@ -1101,12 +1097,6 @@ spawn_detached (gnupg_process_t process, else post_syscall (); - process->pid = (pid_t)-1; - process->fd_in = -1; - process->fd_out = -1; - process->fd_err = -1; - process->wstatus = -1; - process->terminated = 1; return 0; } @@ -1156,6 +1146,24 @@ gnupg_process_spawn (const char *pgmname, const char *argv1[], for (i=0, j=1; argv1[i]; i++, j++) argv[j] = argv1[i]; + if ((flags & GNUPG_PROCESS_DETACHED)) + { + if ((flags & GNUPG_PROCESS_STDFDS_SETTING)) + { + xfree (argv); + return GPG_ERR_INV_FLAG; + } + + /* In detached case, it must be no R_PROCESS. */ + if (r_process) + { + xfree (argv); + return GPG_ERR_INV_ARG; + } + + return spawn_detached (pgmname, argv, spawn_cb, spawn_cb_arg); + } + process = xtrycalloc (1, sizeof (struct gnupg_process)); if (process == NULL) { @@ -1166,19 +1174,6 @@ gnupg_process_spawn (const char *pgmname, const char *argv1[], process->pgmname = pgmname; process->flags = flags; - if ((flags & GNUPG_PROCESS_DETACHED)) - { - if ((flags & GNUPG_PROCESS_STDFDS_SETTING)) - { - xfree (process); - xfree (argv); - return GPG_ERR_INV_FLAG; - } - - *r_process = process; - return spawn_detached (process, pgmname, argv, spawn_cb, spawn_cb_arg); - } - if ((flags & GNUPG_PROCESS_STDINOUT_SOCKETPAIR)) { ec = do_create_socketpair (fd_in); diff --git a/common/exechelp-w32.c b/common/exechelp-w32.c index dfbb3a155..48aa98487 100644 --- a/common/exechelp-w32.c +++ b/common/exechelp-w32.c @@ -1096,8 +1096,7 @@ post_syscall (void) static gpg_err_code_t -spawn_detached (gnupg_process_t process, - const char *pgmname, char *cmdline, +spawn_detached (const char *pgmname, char *cmdline, void (*spawn_cb) (struct spawn_cb_arg *), void *spawn_cb_arg) { SECURITY_ATTRIBUTES sec_attr; @@ -1113,7 +1112,6 @@ spawn_detached (gnupg_process_t process, ec = gnupg_access (pgmname, X_OK); if (ec) { - xfree (process); xfree (cmdline); return ec; } @@ -1191,13 +1189,6 @@ spawn_detached (gnupg_process_t process, CloseHandle (pi.hThread); CloseHandle (pi.hProcess); - - process->hProcess = INVALID_HANDLE_VALUE; - process->hd_in = INVALID_HANDLE_VALUE; - process->hd_out = INVALID_HANDLE_VALUE; - process->hd_err = INVALID_HANDLE_VALUE; - process->exitcode = -1; - process->terminated = 1; return 0; } @@ -1238,14 +1229,32 @@ gnupg_process_spawn (const char *pgmname, const char *argv[], check_syscall_func (); - if (r_process) - *r_process = NULL; - /* Build the command line. */ ec = build_w32_commandline (pgmname, argv, &cmdline); if (ec) return ec; + if ((flags & GNUPG_PROCESS_DETACHED)) + { + if ((flags & GNUPG_PROCESS_STDFDS_SETTING)) + { + xfree (cmdline); + return GPG_ERR_INV_FLAG; + } + + /* In detached case, it must be no R_PROCESS. */ + if (r_process) + { + xfree (cmdline); + return GPG_ERR_INV_ARG; + } + + return spawn_detached (pgmname, cmdline, spawn_cb, spawn_cb_arg); + } + + if (r_process) + *r_process = NULL; + process = xtrymalloc (sizeof (struct gnupg_process)); if (process == NULL) { @@ -1256,19 +1265,6 @@ gnupg_process_spawn (const char *pgmname, const char *argv[], process->pgmname = pgmname; process->flags = flags; - if ((flags & GNUPG_PROCESS_DETACHED)) - { - if ((flags & GNUPG_PROCESS_STDFDS_SETTING)) - { - xfree (process); - xfree (cmdline); - return GPG_ERR_INV_FLAG; - } - - *r_process = process; - return spawn_detached (process, pgmname, cmdline, spawn_cb, spawn_cb_arg); - } - if ((flags & GNUPG_PROCESS_STDINOUT_SOCKETPAIR)) { xfree (process); diff --git a/g13/be-encfs.c b/g13/be-encfs.c index 9adb1e092..c7873816b 100644 --- a/g13/be-encfs.c +++ b/g13/be-encfs.c @@ -82,9 +82,7 @@ run_umount_helper (const char *mountpoint) args[2] = NULL; err = gnupg_process_spawn (pgmname, args, - (GNUPG_PROCESS_DETACHED | GNUPG_PROCESS_STDIN_NULL - | GNUPG_PROCESS_STDOUT_NULL - | GNUPG_PROCESS_STDERR_NULL), + GNUPG_PROCESS_DETACHED, NULL, NULL, NULL); if (err) log_error ("failed to run '%s': %s\n", diff --git a/scd/app.c b/scd/app.c index 74944c8ed..3ca9e3a04 100644 --- a/scd/app.c +++ b/scd/app.c @@ -2374,10 +2374,7 @@ report_change (int slot, int old_status, int cur_status) fname = make_filename (gnupg_homedir (), "scd-event", NULL); err = gnupg_process_spawn (fname, args, - (GNUPG_PROCESS_DETACHED - | GNUPG_PROCESS_STDIN_NULL - | GNUPG_PROCESS_STDOUT_NULL - | GNUPG_PROCESS_STDERR_NULL), + GNUPG_PROCESS_DETACHED, setup_env, envstr, NULL); if (err && gpg_err_code (err) != GPG_ERR_ENOENT) log_error ("failed to run event handler '%s': %s\n",