Skip to content

Commit

Permalink
[sb2] Add support for posix_spawn(). Fixes JB#49495
Browse files Browse the repository at this point in the history
  • Loading branch information
vigejolla committed Sep 16, 2020
1 parent 3a025e1 commit 4a98861
Show file tree
Hide file tree
Showing 5 changed files with 200 additions and 1 deletion.
90 changes: 89 additions & 1 deletion scratchbox2/execs/sb_exec.c
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2006,2007 Lauri Leukkunen <lle@rahina.org>
* Copyright (C) 2020 Open Mobile Platform LLC.
*
* Licensed under LGPL version 2.1
*/
Expand All @@ -11,7 +12,8 @@
* Brief description of the algorithm follows:
*
* 0. When an application wants to execute another program, it makes a call
* to one of execl(), execle(), execlp(), execv(), execve() or execvp().
* to one of execl(), execle(), execlp(), execv(), execve(), execvp() or
* posix_spawn().
* That call will be handled by one of the gate functions in
* preload/libsb2.c. Eventually, the gate function will call "do_exec()"
* from this file; do_exec() calls prepare_exec() and that is the place
Expand Down Expand Up @@ -1765,6 +1767,92 @@ int do_exec(int *result_errno_ptr,
return(result);
}

int do_posix_spawn(int *result_errno_ptr,
const char *exec_fn_name, pid_t *pid, const char *orig_path,
const posix_spawn_file_actions_t *file_actions,
const posix_spawnattr_t *attrp,
char *const *orig_argv, char *const *orig_envp)
{
char *new_path = NULL;
char **new_argv = NULL;
char **new_envp = NULL;
int result;
PROCESSCLOCK(clk1)

START_PROCESSCLOCK(SB_LOGLEVEL_INFO, &clk1, "do_posix_spawn");
if (getenv("SBOX_DISABLE_MAPPING")) {
/* just run it, don't worry, be happy! */
} else {
int r;
char **my_envp_copy = NULL; /* used only for debug log */
char *tmp, *binaryname;
enum binary_type type;

tmp = strdup(orig_path);
binaryname = strdup(basename(tmp)); /* basename may modify *tmp */
free(tmp);

if (SB_LOG_IS_ACTIVE(SB_LOGLEVEL_DEBUG)) {
char *buf = strvec_to_string(orig_argv);

SB_LOG(SB_LOGLEVEL_DEBUG,
"SPAWN/Orig.args: %s : %s", orig_path, buf);
free(buf);

/* create a copy of intended environment for logging,
* before preprocessing */
my_envp_copy = prepare_envp_for_do_exec(orig_path,
binaryname, orig_envp);
}

new_envp = prepare_envp_for_do_exec(orig_path, binaryname, orig_envp);

r = prepare_exec(exec_fn_name, NULL/*exec_policy_name: not yet known*/,
orig_path, 0, orig_argv, orig_envp,
&type, &new_path, &new_argv, &new_envp);

if (SB_LOG_IS_ACTIVE(SB_LOGLEVEL_DEBUG)) {
int saved_errno = errno;
/* find out and log if preprocessing did something */
compare_and_log_strvec_changes("argv", orig_argv, new_argv);
compare_and_log_strvec_changes("envp", my_envp_copy, new_envp);
errno = saved_errno;
}

if (r < 0) {
*result_errno_ptr = errno;
SB_LOG(SB_LOGLEVEL_DEBUG,
"EXEC denied by prepare_exec(), %s", orig_path);
STOP_AND_REPORT_PROCESSCLOCK(SB_LOGLEVEL_INFO, &clk1, "Exec denied");
return(r); /* exec denied */
}

if (check_envp_has_ld_preload_and_ld_library_path(
new_envp ? new_envp : orig_envp) == 0) {

SB_LOG(SB_LOGLEVEL_ERROR,
"exec(%s) failed, internal configuration error: "
"LD_LIBRARY_PATH and/or LD_PRELOAD were not set "
"by exec mapping logic", orig_path);
*result_errno_ptr = EINVAL;
STOP_AND_REPORT_PROCESSCLOCK(SB_LOGLEVEL_INFO, &clk1, "Config error");
return(-1);
}
}

errno = *result_errno_ptr; /* restore to orig.value */
STOP_AND_REPORT_PROCESSCLOCK(SB_LOGLEVEL_INFO, &clk1, orig_file);
result = sb_next_posix_spawn(pid,
(new_path ? new_path : orig_path),
file_actions, attrp,
(new_argv ? new_argv : orig_argv),
(new_envp ? new_envp : orig_envp));
*result_errno_ptr = errno;
SB_LOG(SB_LOGLEVEL_DEBUG,
"EXEC failed (%s), errno=%d", orig_path, *result_errno_ptr);
return(result);
}

/* ----- EXPORTED from interface.master: ----- */
int sb2show__execve_mods__(
char *file,
Expand Down
14 changes: 14 additions & 0 deletions scratchbox2/include/sb2.h
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2006,2007 Lauri Leukkunen <lle@rahina.org>
* Copyright (C) 2020 Open Mobile Platform LLC.
*
* Licensed under LGPL version 2.1, see top level LICENSE file for details.
*/
Expand Down Expand Up @@ -28,6 +29,8 @@
#include <dmalloc.h>
#endif

#include <spawn.h>

/* "sb2context" used to be called "lua_instance", but
* was renamed because it is now used for other purposes,
* too, and can even be used without activating Lua system
Expand Down Expand Up @@ -189,6 +192,17 @@ extern int sb_next_execve(const char *filename, char *const argv [],
extern int do_exec(int *result_errno_ptr, const char *exec_fn_name, const char *file,
char *const *argv, char *const *envp);

extern int sb_next_posix_spawn(pid_t* pid, const char *path,
const posix_spawn_file_actions_t *file_actions,
const posix_spawnattr_t *attrp, char *const argv [],
char *const envp[]);

extern int do_posix_spawn(int *result_errno_ptr,
const char *exec_fn_name, pid_t *pid, const char *orig_path,
const posix_spawn_file_actions_t *file_actions,
const posix_spawnattr_t *attrp,
char *const *orig_argv, char *const *orig_envp);

extern time_t get_sb2_timestamp(void);

extern char *procfs_mapping_request(const char *path);
Expand Down
89 changes: 89 additions & 0 deletions scratchbox2/preload/execgates.c
Expand Up @@ -3,6 +3,7 @@
* (also contains GATEs for the setrlimit() functions)
*
* Copyright (C) 2006,2007 Lauri Leukkunen <lle@rahina.org>
* Copyright (C) 2020 Open Mobile Platform LLC.
* parts contributed by
* Riku Voipio <riku.voipio@movial.com>
* Toni Timonen <toni.timonen@movial.com>
Expand Down Expand Up @@ -124,6 +125,75 @@ int sb_next_execve(const char *file, char *const *argv, char *const *envp)
return next_execve(file, argv, envp);
}

static int (*next_posix_spawn) (pid_t* pid, const char *path,
const posix_spawn_file_actions_t *file_actions,
const posix_spawnattr_t *attrp, char *const argv [],
char *const envp[]) = NULL;

int sb_next_posix_spawn(pid_t* pid, const char *path,
const posix_spawn_file_actions_t *file_actions,
const posix_spawnattr_t *attrp, char *const argv [],
char *const envp[])
{
if (next_posix_spawn == NULL) {
next_posix_spawn = sbox_find_next_symbol(1, "posix_spawn");
}

if (SB_LOG_IS_ACTIVE(SB_LOGLEVEL_DEBUG)) {
char *buf = strvec_to_string(argv);

if (buf) {
SB_LOG(SB_LOGLEVEL_DEBUG, "EXEC: file:%s argv:%s", path, buf);
free(buf);
} else {
SB_LOG(SB_LOGLEVEL_DEBUG,
"EXEC: %s (failed to print argv)", path);
}
}
if (SB_LOG_IS_ACTIVE(SB_LOGLEVEL_NOISE)) {
char *buf = strvec_to_string(envp);

if (buf) {
SB_LOG(SB_LOGLEVEL_NOISE, "EXEC/env: %s", buf);
free(buf);
} else {
SB_LOG(SB_LOGLEVEL_NOISE,
"EXEC: (failed to print env)");
}
}

switch (restore_stack_before_exec) {
case 1:
SB_LOG(SB_LOGLEVEL_DEBUG, "EXEC: need to restore stack limit");

if (setrlimit(RLIMIT_STACK, &stack_limits_for_exec) < 0) {
SB_LOG(SB_LOGLEVEL_ERROR,
"setrlimit(stack) failed, "
"failed to restore limits before exec");
}
break;
#ifndef __APPLE__
case 64:
SB_LOG(SB_LOGLEVEL_DEBUG, "EXEC: need to restore stack limit");

if (setrlimit64(RLIMIT_STACK, &stack_limits64_for_exec) < 0) {
SB_LOG(SB_LOGLEVEL_ERROR,
"setrlimit64(stack) failed, "
"failed to restore limits before exec");
}
break;
#endif
}

/* NOTE: Following SB_LOG() call is used by the log
* postprocessor script "sb2-logz". Do not change
* without making a corresponding change to the script!
*/
SB_LOG(SB_LOGLEVEL_INFO, "EXEC: i_pid=%d path='%s'",
sb_log_initial_pid__, path);
return next_posix_spawn(pid, path, file_actions, attrp, argv, envp);
}


/* collect exec arguments from a varargs list to an array.
* returns an allocated array (use free() to free it if exec fails)
Expand Down Expand Up @@ -442,6 +512,25 @@ int execvpe_gate(
return do_execvep(result_errno_ptr, realfnname, file, argv, envp);
}

int posix_spawn_gate(
int *result_errno_ptr,
int (*real_posix_spawn_ptr)(pid_t *pid, const char *path,
const posix_spawn_file_actions_t *file_actions,
const posix_spawnattr_t *attrp,
char *const argv[], char *const envp[]),
const char *realfnname,
pid_t *pid,
const char *path,
const posix_spawn_file_actions_t *file_actions,
const posix_spawnattr_t *attrp,
char *const argv[],
char *const envp[])
{
(void)real_posix_spawn_ptr;
return do_posix_spawn(result_errno_ptr, realfnname, pid, path,
file_actions, attrp, argv, envp);
}

/* SETRLIMIT_ARG1_TYPE is defined in interface.master */

int setrlimit_gate(
Expand Down
2 changes: 2 additions & 0 deletions scratchbox2/preload/gen-interface.pl
Expand Up @@ -3,6 +3,7 @@
# gen-wrappers.pl -- an interface generator for scratchbox2 preload library
#
# Copyright (C) 2007 Lauri T. Aarnio
# Copyright (C) 2020 Open Mobile Platform LLC.
#
#
# This script is an interface generator for scratchbox 2. Based on
Expand Down Expand Up @@ -1018,6 +1019,7 @@ sub create_call_to_gate_fn {
#include <string.h>
#include <glob.h>
#include <utime.h>
#include <spawn.h>
#ifdef HAVE_FTS_H
#include <fts.h>
#endif
Expand Down
6 changes: 6 additions & 0 deletions scratchbox2/preload/interface.master
Expand Up @@ -7,6 +7,7 @@
-- see gen-interface.pl for details.
--
-- Copyright (C) 2007 Lauri T. Aarnio
-- Copyright (C) 2020 Open Mobile Platform LLC.

@MAN: .SH NAME
@MAN: libsb2_interface, list of functions defined in the scratchbox2 preload library
Expand Down Expand Up @@ -110,6 +111,11 @@ GATE: int execve (const char *filename, char *const argv [], char *const envp[])
GATE: int execvp (const char *file, char *const argv [])
GATE: int execvpe(const char *file, char *const argv[], char *const envp[])

GATE: int posix_spawn (pid_t *pid, const char *path, \
const posix_spawn_file_actions_t *file_actions, \
const posix_spawnattr_t *attrp, \
char *const argv[], char *const envp[])

GATE: char * getcwd (char *buf, size_t size) : \
returns_string create_nomap_nolog_version
GATE: char *__getcwd_chk (char *buf, size_t size, size_t buflen) : \
Expand Down

0 comments on commit 4a98861

Please sign in to comment.