This is an application to execute nsjail for testing nsjail in Tizen application Environment.
Use build script "build_test_runner.sh" to build. You need to install Tizen CLI to build.
You can execute the app like following.
- $> aul_test launch test_runner execute /usr/bin/nsjail_test/jail_mem_syscall_test
--- /dev/null
+pipeline {
+ agent none
+ options { buildDiscarder(logRotator(artifactNumToKeepStr: "10")) }
+ stages {
+ stage("Build") {
+ parallel {
+ stage("Debug") {
+ agent { label "ses-latest" }
+ environment {
+ ARCH = "arm"
+ BUILD_TYPE = "Debug"
+ }
+ steps {
+ script {
+ sh """
+ wget --no-cache https://github.sec.samsung.net/pages/SES/Tools/bin/ses-build.py
+ chmod +x ./ses-build.py
+ ./ses-build.py -f -i /home/developer/bin
+ """
+ }
+ script {
+ sh "./ses-build.py -f -r ${BUILD_TYPE}"
+ }
+ }
+ post {
+ always {
+ archiveArtifacts artifacts: "artifacts/**", fingerprint: true
+ cleanWs deleteDirs: true
+ dir("${env.WORKSPACE}@tmp") {
+ deleteDir()
+ }
+ dir("${env.WORKSPACE}@libs") {
+ deleteDir()
+ }
+ dir("${env.WORKSPACE}@script") {
+ deleteDir()
+ }
+ dir("${env.WORKSPACE}@script@tmp") {
+ deleteDir()
+ }
+ }
+ }
+ }
+ stage("Release") {
+ agent { label "ses-latest" }
+ environment {
+ ARCH = "arm"
+ BUILD_TYPE = "Release"
+ }
+ steps {
+ script {
+ sh """
+ wget --no-cache https://github.sec.samsung.net/pages/SES/Tools/bin/ses-build.py
+ chmod +x ./ses-build.py
+ ./ses-build.py -f -i /home/developer/bin
+ """
+ }
+ script {
+ sh "./ses-build.py -f -r ${BUILD_TYPE}"
+ }
+ }
+ post {
+ always {
+ archiveArtifacts artifacts: "artifacts/**", fingerprint: true
+ cleanWs deleteDirs: true
+ dir("${env.WORKSPACE}@tmp") {
+ deleteDir()
+ }
+ dir("${env.WORKSPACE}@libs") {
+ deleteDir()
+ }
+ dir("${env.WORKSPACE}@script") {
+ deleteDir()
+ }
+ dir("${env.WORKSPACE}@script@tmp") {
+ deleteDir()
+ }
+ }
+ }
+ }
+ }
+ }
+ stage("Sign") {
+ agent any
+ steps {
+ script {
+ DOWNSTREAM_JOB = build job: "mde-enabler-signer/master", parameters: [ booleanParam(name: 'DO_KUEP_SIGN', value: true) ]
+ DOWNSTREAM_BUILD_NUM = DOWNSTREAM_JOB.getNumber().toString()
+ }
+ }
+ post {
+ always {
+ step([
+ $class: "CopyArtifact",
+ filter: "artifacts/**/*.tpk",
+ projectName: "mde-enabler-signer/master",
+ selector: [
+ $class: "SpecificBuildSelector",
+ buildNumber: DOWNSTREAM_BUILD_NUM
+ ]
+ ])
+ archiveArtifacts artifacts: "artifacts/**", fingerprint: true
+ cleanWs deleteDirs: true
+ dir("${env.WORKSPACE}@tmp") {
+ deleteDir()
+ }
+ dir("${env.WORKSPACE}@libs") {
+ deleteDir()
+ }
+ dir("${env.WORKSPACE}@script") {
+ deleteDir()
+ }
+ dir("${env.WORKSPACE}@script@tmp") {
+ deleteDir()
+ }
+ }
+ }
+ }
+ }
+}
+
--- /dev/null
+#!/bin/bash -e
+#
+
+BIN_ROOT=test_runner
+
+ARCH=${1}
+REL=${2}
+RS_VER=${3}
+RS=${4}
+
+if [ -z "${ARCH}" ]
+then
+ ARCH="arm"
+fi
+
+if [ -z "${REL}" ]
+then
+ REL="Debug"
+fi
+
+if [ -z "${RS_VER}" ]
+then
+ RS_VER="6.0"
+fi
+
+if [ -z "${RS}" ]
+then
+ RS="mde-6.0-device.core.public"
+fi
+
+PrjList=(
+ ${BIN_ROOT}
+)
+
+Usage() {
+ echo "usage)./build_test_runner.sh {arm|x86} {Debug|Release} {rootstrap_version} {rootstrap_name}"
+ exit
+}
+
+Clean() {
+ if [ "z$1" = "z" ]; then
+ echo "Missing build directory"
+ exit
+ fi
+
+ if [ -e $1"/"${REL} ]; then
+ rm -r $1"/"${REL}
+ fi
+}
+
+CleanAll() {
+ for it in ${PrjList[@]}
+ do
+ Clean $it
+ done
+}
+
+Build() {
+ if [ "z$1" = "z" ]; then
+ echo "Missing build directory"
+ exit
+ fi
+
+ echo "tizen build-native -C ${REL} -c gcc -a ${ARCH} -r ${RS} -j 8 -- $1"
+ tizen build-native -C ${REL} -c gcc -a ${ARCH} -r ${RS} -j 8 -- $1
+ if [ "$?" != "0" ]; then
+ echo "Failed to make " $1
+ exit
+ fi
+}
+
+BuildAll() {
+ for it in ${PrjList[@]}
+ do
+ Build $it
+ done
+}
+
+if [ "${1}" == "clean" ]; then
+ echo "#### Clean perftool : ${REL} ####"
+ CleanAll
+ rm -rf ./artifacts/${REL}/*.tpk
+ exit
+fi
+
+if [ "${ARCH}" != "arm" ]; then
+ if [ "${ARCH}" != "aarch64" ]; then
+ if [ "${ARCH}" != "x86" ]; then
+ if [ "${ARCH}" != "x86_64" ]; then
+ echo "Warning: Failed to get correct architecture"
+ Usage
+ fi
+ fi
+ fi
+fi
+
+if [ "${REL}" != "Debug" ]; then
+ if [ "${REL}" != "Release" ]; then
+ echo "Warning: Failed to get correct release mode"
+ Usage
+ fi
+fi
+
+tizen list rootstrap | grep ${RS}
+if [ "$?" != "0" ]; then
+ echo "Warning: Failed to get correct rootstrap. Must install the rootstrap : ${RS}"
+ Usage
+fi
+
+# Clean All Project
+CleanAll
+
+# Build All Project
+BuildAll
+
+# Create package
+tizen package -t tpk -- ${BIN_ROOT}/${REL}
+
+# Create artifacts directory
+mkdir -p ./artifacts/${REL}/
+
+# Put output to artifacts directory
+cp -a ${BIN_ROOT}/${REL}/*.tpk ./artifacts/${REL}/
+
--- /dev/null
+{
+ "description" : "Test Runner Build Specification",
+
+ "build" : {
+ "6.0" : {
+ "archlist" : [ "arm" ],
+ "script" : [
+ "#!/bin/bash -e",
+ "./build_test_runner.sh {arch} {rel} {rs_ver} {rs}"
+ ]
+ }
+ }
+}
--- /dev/null
+{
+ global: main;
+};
--- /dev/null
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * PROPRIETARY/CONFIDENTIAL
+ *
+ * This software is the confidential and proprietary information of
+ * Samsung Electronics Co., Ltd. ("Confidential Information").
+ * You shall not disclose such Confidential Information and shall
+ * use it only in accordance with the terms of the license agreement
+ * you entered into with Samsung Electronics Co., Ltd. ("SAMSUNG").
+ *
+ * SAMSUNG MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY
+ * OF THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT
+ * LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR
+ * A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. SAMSUNG SHALL NOT BE
+ * LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING,
+ * MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES.
+ */
+
+#ifndef __TEST_RUNNER_H__
+#define __TEST_RUNNER_H__
+
+#include <dlog.h>
+
+#ifdef LOG_TAG
+#undef LOG_TAG
+#endif
+#define LOG_TAG "TEST_RUNNER"
+
+#define LOGI(fmt, arg...) dlog_print(DLOG_INFO, LOG_TAG, "%s (%d) %s : " fmt, __FILE__, __LINE__, __FUNCTION__, ##arg)
+#define LOGD(fmt, arg...) dlog_print(DLOG_DEBUG, LOG_TAG, "%s (%d) %s : " fmt, __FILE__, __LINE__, __FUNCTION__, ##arg)
+#define LOGE(fmt, arg...) dlog_print(DLOG_ERROR, LOG_TAG, "%s (%d) %s : " fmt, __FILE__, __LINE__, __FUNCTION__, ##arg)
+#define LOGW(fmt, arg...) dlog_print(DLOG_WARN, LOG_TAG, "%s (%d) %s : " fmt, __FILE__, __LINE__, __FUNCTION__, ##arg)
+
+#if !defined(PACKAGE)
+#define PACKAGE "test_runner"
+#endif
+
+bool spawn(char *const av[], char *const ev[], pid_t *childpid, int *childfd, int *exit_code);
+
+#endif /* __TEST_RUNNER_H__ */
+
--- /dev/null
+
+# Project Name
+APPNAME = test_runner
+
+# Project Type
+type = app
+
+# Project Profile
+profile = wearable-4.0
+
+# C/CPP Sources
+USER_SRCS = src/*.c
+
+# EDC Sources
+USER_EDCS =
+
+# PO Sources
+USER_POS =
+
+# User Defines
+USER_DEFS =
+USER_CPP_DEFS =
+
+# User Undefines
+USER_UNDEFS =
+USER_CPP_UNDEFS =
+
+# User Libraries
+USER_LIBS =
+
+# User Objects
+USER_OBJS =
+
+# User Includes
+## C Compiler
+USER_C_INC_DIRS = inc
+USER_INC_FILES =
+## C++ Compiler
+USER_CPP_INC_DIRS =
+USER_CPP_INC_FILES =
+
+USER_INC_DIRS = $(USER_C_INC_DIRS) $(USER_CPP_INC_DIRS)
+
+# User Library Path
+USER_LIB_DIRS = lib
+
+# EDC Resource Path
+USER_EDCS_IMAGE_DIRS = ${OUTPUT_DIR}
+USER_EDCS_SOUND_DIRS = ${OUTPUT_DIR}
+USER_EDCS_FONT_DIRS = ${OUTPUT_DIR}
+
+# EDC Flags
+USER_EXT_EDC_KEYS =
+
+# Resource Filter
+USER_RES_INCLUDE =
+USER_RES_EXCLUDE =
+
+USER_C_OPTS = -fdiagnostics-color
+USER_CPP_OPTS = -fdiagnostics-color
--- /dev/null
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * PROPRIETARY/CONFIDENTIAL
+ *
+ * This software is the confidential and proprietary information of
+ * Samsung Electronics Co., Ltd. ("Confidential Information").
+ * You shall not disclose such Confidential Information and shall
+ * use it only in accordance with the terms of the license agreement
+ * you entered into with Samsung Electronics Co., Ltd. ("SAMSUNG").
+ *
+ * SAMSUNG MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY
+ * OF THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT
+ * LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR
+ * A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. SAMSUNG SHALL NOT BE
+ * LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING,
+ * MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES.
+ */
+
+#include <glib.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include <app_control.h>
+#include <app_manager.h>
+#include <service_app.h>
+
+#include "test_runner.h"
+
+static bool service_app_create(void *data)
+{
+ LOGI("test_runner is created");
+
+ return true;
+}
+
+static void service_app_terminate(void *data)
+{
+ LOGI("test_runner is terminated");
+
+ return;
+}
+
+static void service_app_control(app_control_h app_control, void *data)
+{
+ int ret;
+ char *value;
+
+ pid_t childpid;
+ char *av[] = {"/usr/bin/nsjail", "--config", "/usr/share/runner-sandbox.cfg", "--", NULL, NULL};
+
+ ret = app_control_get_extra_data(app_control, "execute", &value);
+ switch (ret) {
+ case APP_CONTROL_ERROR_NONE:
+ av[4]=value;
+ LOGI("Runner Command is %s",value);
+ spawn(av, NULL, &childpid, NULL, NULL);
+ LOGI("Child pid is %d",childpid);
+ break;
+ case APP_CONTROL_ERROR_KEY_NOT_FOUND:
+ LOGE("Invalid command");
+ break;
+ default:
+ LOGE("Failed to get argument (%d)", ret);
+ service_app_exit();
+ break;
+ }
+}
+
+int main(int argc, char **argv)
+{
+ char ad[50] = {0, };
+ service_app_lifecycle_callback_s event_callback;
+
+ event_callback.create = service_app_create;
+ event_callback.terminate = service_app_terminate;
+ event_callback.app_control = service_app_control;
+
+ return service_app_main(argc, argv, &event_callback, ad);
+}
--- /dev/null
+#include <stdbool.h>
+#include <sys/types.h>
+#include <stdarg.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <string.h>
+#include <assert.h>
+#include <sys/wait.h>
+
+#include "test_runner.h"
+
+/* This function is supposed to accept same data as passed to execve
+ * (argv and envp), which can be arrays of strings as well as NULL
+ * pointer.
+ */
+char *concatenate(char *const vec[])
+{
+ size_t length = 0;
+ for (char *const *p = vec; p && *p; p++)
+ length += strlen(*p) + 1;
+
+ if (length == 0)
+ return strdup("");
+
+ char *str = (char *)malloc(length);
+ if (!str)
+ return NULL;
+
+ char *destp = str;
+ char *const *vecp = vec;
+ while (*vecp) {
+ destp = stpcpy(destp, *(vecp++));
+ if (*vecp)
+ destp = stpcpy(destp, " ");
+ }
+
+ return str;
+}
+
+static int spawn_child(char *const av[], char *const ev[])
+{
+ static const int spawn_error = 127;
+
+ execve(av[0], av, ev);
+ return spawn_error;
+}
+
+bool wait_for_pid(pid_t pid, int *exit_code)
+{
+ int status = 0;
+ int r = 0;
+ bool is_ok;
+
+ if (pid < 0)
+ return false;
+
+ do {
+ r = waitpid(pid, &status, 0);
+ is_ok = r >= 0;
+ } while (!is_ok && errno == EINTR);
+
+ if (!is_ok) {
+ LOGE("Error while waiting for child %d status: %m", (int)pid);
+ return false;
+ }
+
+ /* child has terminated */
+ if (WIFEXITED(status))
+ r = WEXITSTATUS(status);
+ else if (WIFSIGNALED(status))
+ r = WTERMSIG(status);
+ else if (WIFSTOPPED(status))
+ r = WSTOPSIG(status);
+
+ LOGD("Child with pid %d terminated with exit code %d", (int)pid, r);
+ if (exit_code)
+ *exit_code = r;
+
+ return true;
+}
+
+bool spawn(char *const av[], char *const ev[], pid_t *childpid, int *childfd, int *exit_code)
+{
+ int pipefd[2];
+ if (pipe(pipefd) < 0) {
+ LOGE("pipe: %m");
+ return false;
+ }
+
+ pid_t pid = fork();
+ if (pid < 0) {
+ LOGE("fork: %m");
+ close(pipefd[0]);
+ close(pipefd[1]);
+ return false;
+ } else if (pid == 0) {
+ close(pipefd[0]);
+ _exit(spawn_child(av, ev));
+ }
+ close(pipefd[1]);
+
+ char *cmd = concatenate(av);
+ char *env = concatenate(ev);
+ LOGD("Spawned child with pid %d to execute command <%s> with environment <%s>", (int)pid, cmd, env);
+ free(cmd);
+ free(env);
+
+ // parent
+ if (childpid)
+ *childpid = pid;
+
+ if (childfd) {
+ LOGD("Leaving childfd status descriptor %d open for child status notification", pipefd[0]);
+ *childfd = pipefd[0];
+ } else
+ close(pipefd[0]);
+
+ if(childpid && exit_code)
+ wait_for_pid(*childpid, exit_code);
+
+ return true;
+}
+
+
+
+
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<manifest xmlns="http://tizen.org/ns/packages" api-version="4.0" package="test_runner" version="0.0.1">
+ <service-application appid="test_runner" exec="test_runner" type="capp" multiple="false" nodisplay="true">
+ <label>test_runner</label>
+ <icon>test_runner.png</icon>
+ </service-application>
+ <privileges>
+ </privileges>
+</manifest>