In the context of security integration, a sandbox is a mechanism for constraining code with virtual walls to protect it from being damaged by malicious code. You can also use a sandbox to limit the damage done if the code it contains is co-opted by an attacker.
Best practices for security integrators include protecting mountpoints from client access by sandboxing them. Application sandboxing (including third-party applications) can reduce vulnerability to malware. Sandboxes are also a convenient, isolated space for testing your code. Use the procmgr ability _PROCMGR_AID_SANDBOX to create and delete sandboxes, attach a process to a sandbox, and detach a process from a sandbox.
To learn more about procmgr abilities, see the Procmgr abilities chapter of the QNX Neutrino Programmer's Guide.
The following example shows how to use procmgr abilities to create a sandbox, attach a process to the sandbox, and then delete the sandbox:
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <string.h> #include <sandbox.h> #include <signal.h> #include <fcntl.h> #include <errno.h> #include <pthread.h> #include <sys/neutrino.h> #include <sys/iomsg.h> #include <sys/procmsg.h> static const char sandbox_config[] = "[version=1]\n" "/proc/boot\n" "/dev/tty*\n" "/tmp\n" "/root\n" "/usr/lib\n" "!*"; int main(int argc, char *argv[]) { proc_sandbox_create_t msg; iov_t iov[2]; int r; int sbid; fprintf(stderr, "Initializing sandbox configuration\n"); r = sandbox_parse_config(sandbox_config, sizeof(sandbox_config), &iov[1], &msg.i.version); if (r > 0) { fprintf(stderr, "Parse error on line %d\n", r); return 1; } else if (r < 0) { errno = r; perror("sandbox_parse_config"); return 1; } else { fprintf(stderr, "%s:%d - Creating sandbox...\n", __FUNCTION__, __LINE__); msg.i.type = _PROC_SANDBOX; msg.i.subtype = _PROC_SANDBOX_CREATE; msg.i.datalen = iov[1].iov_len; iov[0].iov_base = &msg; iov[0].iov_len = sizeof(msg); if (MsgSendv(PROCMGR_COID, iov, 2, iov, 1) != 0) { perror("MsgSendv(_PROC_SANDBOX_CREATE)"); return 1; } sbid = msg.o.sbid; sandbox_done_config(&iov[1]); } // Start the child process. pid_t pid = fork(); if (pid < 0) { perror("fork"); return 1; } if (pid == 0) { delay(1000); // wait for parent to attach child to sandbox if (execl("/proc/boot/sh", "proc/boot/sh", NULL) < 0) { /* execute the command */ printf("*** ERROR: exec failed errno:%d\n", errno); exit(1); } fprintf(stderr, "%s:%d - execl exitting\n", __FUNCTION__, __LINE__); } fprintf(stderr, "%s:%d\n", __FUNCTION__, __LINE__); r = sandbox_attach(sbid, pid); if (r < 0) { fprintf(stderr, "sandbox_attach: %s\n", strerror(-r)); goto done; } fprintf(stderr, "%s:%d pid=%d r=%d\n", __FUNCTION__, __LINE__, pid, r); waitpid(pid, &r, 0); fprintf(stderr, "%s:%d\n", __FUNCTION__, __LINE__); pid = 0; done: if (sbid != -1) { sandbox_delete(sbid); } return r; }