Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F156891652
D19282.id54184.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
7 KB
Referenced Files
None
Subscribers
None
D19282.id54184.diff
View Options
Index: sbin/bectl/bectl_jail.c
===================================================================
--- sbin/bectl/bectl_jail.c
+++ sbin/bectl/bectl_jail.c
@@ -40,95 +40,36 @@
#include <unistd.h>
#include <be.h>
-
#include "bectl.h"
-static void jailparam_grow(void);
static void jailparam_add(const char *name, const char *val);
static int jailparam_del(const char *name);
static bool jailparam_addarg(char *arg);
static int jailparam_delarg(char *arg);
+static int bectl_cmd_jail_background(void);
+static int bectl_cmd_jail_exec(void);
static int bectl_search_jail_paths(const char *mnt);
static int bectl_locate_jail(const char *ident);
-/* We'll start with 8 parameters initially and grow as needed. */
-#define INIT_PARAMCOUNT 8
+static int nvlist_to_jailparam(struct jailparam **jp);
-static struct jailparam *jp;
-static int jpcnt;
static int jpused;
static char mnt_loc[BE_MAXPATHLEN];
+static nvlist_t *jailparams;
-static void
-jailparam_grow(void)
-{
-
- jpcnt *= 2;
- jp = realloc(jp, jpcnt * sizeof(*jp));
- if (jp == NULL)
- err(2, "realloc");
-}
static void
jailparam_add(const char *name, const char *val)
{
- int i;
-
- for (i = 0; i < jpused; ++i) {
- if (strcmp(name, jp[i].jp_name) == 0)
- break;
- }
-
- if (i < jpused)
- jailparam_free(&jp[i], 1);
- else if (jpused == jpcnt)
- /* The next slot isn't allocated yet */
- jailparam_grow();
-
- if (jailparam_init(&jp[i], name) != 0)
- return;
- if (jailparam_import(&jp[i], val) != 0)
- return;
- ++jpused;
+ jpused++;
+ nvlist_add_string(jailparams, name, val);
}
static int
jailparam_del(const char *name)
{
- int i;
- char *val;
-
- for (i = 0; i < jpused; ++i) {
- if (strcmp(name, jp[i].jp_name) == 0)
- break;
- }
-
- if (i == jpused)
- return (ENOENT);
-
- for (; i < jpused - 1; ++i) {
- val = jailparam_export(&jp[i + 1]);
-
- jailparam_free(&jp[i], 1);
- /*
- * Given the context, the following will really only fail if
- * they can't allocate the copy of the name or value.
- */
- if (jailparam_init(&jp[i], jp[i + 1].jp_name) != 0) {
- free(val);
- return (ENOMEM);
- }
- if (jailparam_import(&jp[i], val) != 0) {
- jailparam_free(&jp[i], 1);
- free(val);
- return (ENOMEM);
- }
- free(val);
- }
-
- jailparam_free(&jp[i], 1);
- --jpused;
+ nvlist_remove_all(jailparams, name);
return (0);
}
@@ -145,7 +86,7 @@
arg);
return (false);
}
-
+
*val++ = '\0';
if (strcmp(name, "path") == 0) {
if (strlen(val) >= BE_MAXPATHLEN) {
@@ -176,21 +117,61 @@
return (jailparam_del(name));
}
+/* Convert our nvlist to a jailparam struct*/
+static int
+nvlist_to_jailparam(struct jailparam **jpp)
+{
+ int rc, i, jpidx;
+ char *name, *value;
+ struct jailparam *jp;
+ nvpair_t *cur;
+
+ jp = malloc(jpused * sizeof(*jp));
+ if (jp == NULL)
+ err(2, "malloc");
+
+ cur = nvlist_next_nvpair(jailparams, NULL);
+ for(i = jpidx = 0; i < jpused; i++){
+ name = nvpair_name(cur);
+ nvpair_value_string(cur, &value);
+
+ fprintf(stderr, "bectl jail: import jailparam: '%s'='%s'\n", name, value);
+ if ((rc = jailparam_init(&jp[jpidx], name)) != 0) {
+ continue;
+ }
+
+ if ((rc = jailparam_import(&jp[jpidx], value)) != 0 ){
+ continue;
+ }
+ jpidx++;
+ cur = nvlist_next_nvpair(jailparams, cur);
+ }
+
+ if (jpidx != jpused) {
+ //resize jp with the new size.
+ fprintf(stderr, "one of our params wasnt added. should resize here");
+ }
+
+ *jpp = jp;
+ return (0);
+}
+
int
bectl_cmd_jail(int argc, char *argv[])
{
char *bootenv, *mountpoint;
- int jid, mntflags, opt, ret;
+ int mntflags, opt, ret;
bool default_hostname, interactive, unjail;
- pid_t pid;
/* XXX TODO: Allow shallow */
mntflags = BE_MNT_DEEP;
default_hostname = interactive = unjail = true;
- jpcnt = INIT_PARAMCOUNT;
- jp = malloc(jpcnt * sizeof(*jp));
- if (jp == NULL)
- err(2, "malloc");
+
+ ret = nvlist_alloc(&jailparams, NV_UNIQUE_NAME, 0);
+ if (ret) {
+ fprintf(stderr, "nvlist_alloc() failed\n");
+ return (ret);
+ }
jailparam_add("persist", "true");
jailparam_add("allow.mount", "true");
@@ -242,6 +223,16 @@
return (usage(false));
}
+ if (argc > 1) {
+ if ( nvlist_exists(jailparams, "command") ||
+ nvlist_exists(jailparams, "exec.start") ){
+ fprintf(stderr, "command is defined more than once");
+ return (1);
+ }
+ jailparam_add("command", argv[1]);
+ }
+
+
bootenv = argv[0];
/*
@@ -266,7 +257,37 @@
*/
if (mountpoint == NULL)
jailparam_add("path", mnt_loc);
- /* Create the jail for now, attach later as-needed */
+
+ if (!interactive){
+ ret = bectl_cmd_jail_background();
+ } else {
+ ret = bectl_cmd_jail_exec();
+ }
+
+ if (ret || unjail)
+ be_unmount(be, bootenv, 0);
+
+ return (ret);
+}
+
+/*
+ * Convert our nvlist to a jailparam pointer and create the jail
+ * using jailparam_set. This limits us to only using jailparams and
+ * not any pseudo ones, such as 'mount.devfs'.
+ *
+ * This function frees the jailparams nvlist.
+ */
+static int
+bectl_cmd_jail_background()
+{
+ struct jailparam *jp;
+ int jid;
+
+ if( nvlist_to_jailparam(&jp) != 0 ){
+ nvlist_free(jailparams);
+ return (1);
+ }
+
jid = jailparam_set(jp, jpused, JAIL_CREATE);
if (jid == -1) {
fprintf(stderr, "unable to create jail. error: %d\n", errno);
@@ -274,11 +295,71 @@
}
jailparam_free(jp, jpused);
+ nvlist_free(jailparams);
free(jp);
- /* We're not interactive, nothing more to do here. */
- if (!interactive)
- return (0);
+ return (0);
+}
+
+/*
+ * Fork into the system's jail command so that it can handle the
+ * pesudo jailparams.
+ */
+static int
+bectl_cmd_jail_exec(){
+ char **args, *name, *value, buf[4096];
+ char **argpos; // do we need this if we have args?
+ int total;
+ pid_t pid;
+ nvpair_t *cur;
+
+ // Basically we shove everything into our buffer, while
+ // incrementing our pointer.
+ total = 0;
+
+ args = malloc( (jpused + 3) * sizeof(char *));
+ if (args == NULL) {
+ err(2, "malloc");
+ }
+
+ // bufarg keeps track of our position on the buffer,
+ argpos = args;
+
+ // our first argument starts at the adress of the
+ // buffer
+ *argpos++ = buf;
+
+ // write our jail command and, flags to the buffer
+ // we add a +1 so the null terminator exists in our buffer
+ total += sprintf(buf + total, "/usr/sbin/jail") + 1;
+ *argpos++ = buf + total;
+
+ total += sprintf(buf + total, "-c") + 1;
+ *argpos++ = buf + total;
+
+ cur = nvlist_next_nvpair(jailparams, NULL);
+ while(cur != NULL){
+ name = nvpair_name(cur);
+ nvpair_value_string(cur, &value);
+ // TODO: add range checking here to exit when we go over the
+ // buffer? or if the number returned == 1 (meaning we
+ // didnt write anything )
+ total += snprintf(buf + total, 4096 + total, "%s=%s", name, value) + 1;
+ *argpos++ = buf + total;
+
+ cur = nvlist_next_nvpair(jailparams, cur);
+ }
+
+ //*argpos = NULL;
+ args[jpused+2] = NULL;
+ nvlist_free(jailparams);
+
+ for (int i = 0; i < (jpused + 3); i++){
+ if (args[i] == NULL)
+ fprintf(stderr, "arg[%d]: NULL\n", i);
+ else
+ fprintf(stderr, "arg[%d]: %s\n", i, args[i]);
+ }
pid = fork();
switch(pid) {
@@ -286,29 +367,16 @@
perror("fork");
return (1);
case 0:
- jail_attach(jid);
- /* We're attached within the jail... good bye! */
- chdir("/");
- if (argc > 1)
- execve(argv[1], &argv[1], NULL);
- else
- execl("/bin/sh", "/bin/sh", NULL);
- fprintf(stderr, "bectl jail: failed to execute %s\n",
- (argc > 1 ? argv[1] : "/bin/sh"));
- _exit(1);
+ execvp(args[0], args);
default:
- /* Wait for the child to get back, see if we need to unjail */
waitpid(pid, NULL, 0);
}
- if (unjail) {
- jail_remove(jid);
- be_unmount(be, bootenv, 0);
- }
-
+ free(args);
return (0);
}
+
static int
bectl_search_jail_paths(const char *mnt)
{
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Mon, May 18, 3:17 AM (7 h, 42 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
33231184
Default Alt Text
D19282.id54184.diff (7 KB)
Attached To
Mode
D19282: bectl(8): change jail command to execute jail(8)
Attached
Detach File
Event Timeline
Log In to Comment