diff --git a/cmdline.c b/cmdline.c index 39b2b53..41a4c72 100644 --- a/cmdline.c +++ b/cmdline.c @@ -795,8 +795,10 @@ bool cmdlineParse(int argc, char *argv[], struct nsjconf_t * nsjconf) return false; } - nsjconf->argv = &argv[optind]; - if (nsjconf->argv[0] == NULL) { + if (argv[optind]) { + nsjconf->argv = &argv[optind]; + } + if (nsjconf->argv == NULL || nsjconf->argv[0] == NULL) { LOG_E("No command provided"); cmdlineUsage(argv[0]); return false; diff --git a/config.c b/config.c index ec12513..648a084 100644 --- a/config.c +++ b/config.c @@ -228,6 +228,16 @@ static bool configParseInternal(struct nsjconf_t *nsjconf, Nsjail__NsJailConfig nsjconf->iface_vs_nm = utilStrDup(njc->macvlan_vs_nm); nsjconf->iface_vs_gw = utilStrDup(njc->macvlan_vs_gw); + if (njc->exec_bin) { + char **argv = utilCalloc(sizeof(const char *) * (njc->exec_bin->n_arg + 2)); + argv[0] = utilStrDup(njc->exec_bin->path); + for (size_t i = 0; i < njc->exec_bin->n_arg; i++) { + argv[i + 1] = utilStrDup(njc->exec_bin->arg[i]); + } + argv[njc->exec_bin->n_arg + 1] = NULL; + nsjconf->argv = argv; + } + return true; } diff --git a/config.example b/config.example index 4667015..096dac0 100644 --- a/config.example +++ b/config.example @@ -10,7 +10,7 @@ port: 31337 time_limit: 100 daemon: false -keep_env: true +keep_env: false silent: false skip_setsid: false pass_fd: 100 @@ -85,3 +85,8 @@ seccomp_string: " } USE example DEFAULT ALLOW " + +exec_bin { + path: "/usr/bin/id" + arg: "root" +} diff --git a/config.pb-c.c b/config.pb-c.c index b482766..6dc6330 100644 --- a/config.pb-c.c +++ b/config.pb-c.c @@ -69,6 +69,36 @@ void nsjail__mount_pt__free_unpacked(Nsjail__MountPt * message, ProtobufCAllocat protobuf_c_message_free_unpacked((ProtobufCMessage *) message, allocator); } +void nsjail__exe__init(Nsjail__Exe * message) { + static Nsjail__Exe init_value = NSJAIL__EXE__INIT; + *message = init_value; +} + +size_t nsjail__exe__get_packed_size(const Nsjail__Exe * message) { + assert(message->base.descriptor == &nsjail__exe__descriptor); + return protobuf_c_message_get_packed_size((const ProtobufCMessage *)(message)); +} + +size_t nsjail__exe__pack(const Nsjail__Exe * message, uint8_t * out) { + assert(message->base.descriptor == &nsjail__exe__descriptor); + return protobuf_c_message_pack((const ProtobufCMessage *)message, out); +} + +size_t nsjail__exe__pack_to_buffer(const Nsjail__Exe * message, ProtobufCBuffer * buffer) { + assert(message->base.descriptor == &nsjail__exe__descriptor); + return protobuf_c_message_pack_to_buffer((const ProtobufCMessage *)message, buffer); +} + +Nsjail__Exe *nsjail__exe__unpack(ProtobufCAllocator * allocator, size_t len, const uint8_t * data) { + return (Nsjail__Exe *) + protobuf_c_message_unpack(&nsjail__exe__descriptor, allocator, len, data); +} + +void nsjail__exe__free_unpacked(Nsjail__Exe * message, ProtobufCAllocator * allocator) { + assert(message->base.descriptor == &nsjail__exe__descriptor); + protobuf_c_message_free_unpacked((ProtobufCMessage *) message, allocator); +} + void nsjail__ns_jail_config__init(Nsjail__NsJailConfig * message) { static Nsjail__NsJailConfig init_value = NSJAIL__NS_JAIL_CONFIG__INIT; *message = init_value; @@ -304,6 +334,58 @@ const ProtobufCMessageDescriptor nsjail__mount_pt__descriptor = { NULL, NULL, NULL /* reserved[123] */ }; +static const ProtobufCFieldDescriptor nsjail__exe__field_descriptors[2] = { + { + "path", + 1, + PROTOBUF_C_LABEL_REQUIRED, + PROTOBUF_C_TYPE_STRING, + 0, /* quantifier_offset */ + offsetof(Nsjail__Exe, path), + NULL, + NULL, + 0, /* flags */ + 0, NULL, NULL /* reserved1,reserved2, etc */ + }, + { + "arg", + 2, + PROTOBUF_C_LABEL_REPEATED, + PROTOBUF_C_TYPE_STRING, + offsetof(Nsjail__Exe, n_arg), + offsetof(Nsjail__Exe, arg), + NULL, + NULL, + 0, /* flags */ + 0, NULL, NULL /* reserved1,reserved2, etc */ + }, +}; + +static const unsigned nsjail__exe__field_indices_by_name[] = { + 1, /* field[1] = arg */ + 0, /* field[0] = path */ +}; + +static const ProtobufCIntRange nsjail__exe__number_ranges[1 + 1] = { + {1, 0}, + {0, 2} +}; + +const ProtobufCMessageDescriptor nsjail__exe__descriptor = { + PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC, + "nsjail.Exe", + "Exe", + "Nsjail__Exe", + "nsjail", + sizeof(Nsjail__Exe), + 2, + nsjail__exe__field_descriptors, + nsjail__exe__field_indices_by_name, + 1, nsjail__exe__number_ranges, + (ProtobufCMessageInit) nsjail__exe__init, + NULL, NULL, NULL /* reserved[123] */ +}; + char nsjail__ns_jail_config__hostname__default_value[] = "NSJAIL"; char nsjail__ns_jail_config__cwd__default_value[] = "/"; char nsjail__ns_jail_config__bindhost__default_value[] = "::"; @@ -349,7 +431,7 @@ static const protobuf_c_boolean nsjail__ns_jail_config__mount_proc__default_valu static const uint64_t nsjail__ns_jail_config__cgroup_mem_max__default_value = 0ull; static const uint64_t nsjail__ns_jail_config__cgroup_pids_max__default_value = 0ull; static const protobuf_c_boolean nsjail__ns_jail_config__iface_no_lo__default_value = 0; -static const ProtobufCFieldDescriptor nsjail__ns_jail_config__field_descriptors[54] = { +static const ProtobufCFieldDescriptor nsjail__ns_jail_config__field_descriptors[55] = { { "mode", 1, @@ -998,6 +1080,18 @@ static const ProtobufCFieldDescriptor nsjail__ns_jail_config__field_descriptors[ 0, /* flags */ 0, NULL, NULL /* reserved1,reserved2, etc */ }, + { + "exec_bin", + 57, + PROTOBUF_C_LABEL_OPTIONAL, + PROTOBUF_C_TYPE_MESSAGE, + 0, /* quantifier_offset */ + offsetof(Nsjail__NsJailConfig, exec_bin), + &nsjail__exe__descriptor, + NULL, + 0, /* flags */ + 0, NULL, NULL /* reserved1,reserved2, etc */ + }, }; static const unsigned nsjail__ns_jail_config__field_indices_by_name[] = { @@ -1019,6 +1113,7 @@ static const unsigned nsjail__ns_jail_config__field_indices_by_name[] = { 4, /* field[4] = cwd */ 9, /* field[9] = daemon */ 17, /* field[17] = disable_no_new_privs */ + 54, /* field[54] = exec_bin */ 38, /* field[38] = gidmap */ 3, /* field[3] = hostname */ 49, /* field[49] = iface_no_lo */ @@ -1060,7 +1155,7 @@ static const unsigned nsjail__ns_jail_config__field_indices_by_name[] = { static const ProtobufCIntRange nsjail__ns_jail_config__number_ranges[2 + 1] = { {1, 0}, {6, 3}, - {0, 54} + {0, 55} }; const ProtobufCMessageDescriptor nsjail__ns_jail_config__descriptor = { @@ -1070,7 +1165,7 @@ const ProtobufCMessageDescriptor nsjail__ns_jail_config__descriptor = { "Nsjail__NsJailConfig", "nsjail", sizeof(Nsjail__NsJailConfig), - 54, + 55, nsjail__ns_jail_config__field_descriptors, nsjail__ns_jail_config__field_indices_by_name, 2, nsjail__ns_jail_config__number_ranges, diff --git a/config.pb-c.h b/config.pb-c.h index 42a4a99..4836269 100644 --- a/config.pb-c.h +++ b/config.pb-c.h @@ -14,6 +14,7 @@ PROTOBUF_C__BEGIN_DECLS #endif typedef struct _Nsjail__IdMap Nsjail__IdMap; typedef struct _Nsjail__MountPt Nsjail__MountPt; +typedef struct _Nsjail__Exe Nsjail__Exe; typedef struct _Nsjail__NsJailConfig Nsjail__NsJailConfig; /* --- enums --- */ @@ -63,6 +64,16 @@ extern char nsjail__mount_pt__options__default_value[]; { PROTOBUF_C_MESSAGE_INIT (&nsjail__mount_pt__descriptor) \ , NULL, NULL, NULL, nsjail__mount_pt__options__default_value, 0, 0, 0,0 } +struct _Nsjail__Exe { + ProtobufCMessage base; + char *path; + size_t n_arg; + char **arg; +}; +#define NSJAIL__EXE__INIT \ + { PROTOBUF_C_MESSAGE_INIT (&nsjail__exe__descriptor) \ + , NULL, 0,NULL } + struct _Nsjail__NsJailConfig { ProtobufCMessage base; Nsjail__Mode mode; @@ -126,6 +137,7 @@ struct _Nsjail__NsJailConfig { char *macvlan_vs_ip; char *macvlan_vs_nm; char *macvlan_vs_gw; + Nsjail__Exe *exec_bin; }; extern char nsjail__ns_jail_config__hostname__default_value[]; extern char nsjail__ns_jail_config__cwd__default_value[]; @@ -139,7 +151,7 @@ extern char nsjail__ns_jail_config__macvlan_vs_nm__default_value[]; extern char nsjail__ns_jail_config__macvlan_vs_gw__default_value[]; #define NSJAIL__NS_JAIL_CONFIG__INIT \ { PROTOBUF_C_MESSAGE_INIT (&nsjail__ns_jail_config__descriptor) \ - , NSJAIL__MODE__ONCE, NULL, 0, nsjail__ns_jail_config__hostname__default_value, nsjail__ns_jail_config__cwd__default_value, 0u, nsjail__ns_jail_config__bindhost__default_value, 0u, 600u, 0, NULL, 0,0, 0, 0, 0, 0,NULL, 0, 0, 512ull, 0ull, 600ull, 1ull, 32ull, 0,0, 0,0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0,NULL, 0,NULL, 0,NULL, 1, NULL, NULL, 0ull, nsjail__ns_jail_config__cgroup_mem_mount__default_value, nsjail__ns_jail_config__cgroup_mem_parent__default_value, 0ull, nsjail__ns_jail_config__cgroup_pids_mount__default_value, nsjail__ns_jail_config__cgroup_pids_parent__default_value, 0, NULL, nsjail__ns_jail_config__macvlan_vs_ip__default_value, nsjail__ns_jail_config__macvlan_vs_nm__default_value, nsjail__ns_jail_config__macvlan_vs_gw__default_value } + , NSJAIL__MODE__ONCE, NULL, 0, nsjail__ns_jail_config__hostname__default_value, nsjail__ns_jail_config__cwd__default_value, 0u, nsjail__ns_jail_config__bindhost__default_value, 0u, 600u, 0, NULL, 0,0, 0, 0, 0, 0,NULL, 0, 0, 512ull, 0ull, 600ull, 1ull, 32ull, 0,0, 0,0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0,NULL, 0,NULL, 0,NULL, 1, NULL, NULL, 0ull, nsjail__ns_jail_config__cgroup_mem_mount__default_value, nsjail__ns_jail_config__cgroup_mem_parent__default_value, 0ull, nsjail__ns_jail_config__cgroup_pids_mount__default_value, nsjail__ns_jail_config__cgroup_pids_parent__default_value, 0, NULL, nsjail__ns_jail_config__macvlan_vs_ip__default_value, nsjail__ns_jail_config__macvlan_vs_nm__default_value, nsjail__ns_jail_config__macvlan_vs_gw__default_value, NULL } /* Nsjail__IdMap methods */ void nsjail__id_map__init(Nsjail__IdMap * message); @@ -157,6 +169,13 @@ size_t nsjail__mount_pt__pack_to_buffer(const Nsjail__MountPt * message, Protobu Nsjail__MountPt *nsjail__mount_pt__unpack (ProtobufCAllocator * allocator, size_t len, const uint8_t * data); void nsjail__mount_pt__free_unpacked(Nsjail__MountPt * message, ProtobufCAllocator * allocator); +/* Nsjail__Exe methods */ +void nsjail__exe__init(Nsjail__Exe * message); +size_t nsjail__exe__get_packed_size(const Nsjail__Exe * message); +size_t nsjail__exe__pack(const Nsjail__Exe * message, uint8_t * out); +size_t nsjail__exe__pack_to_buffer(const Nsjail__Exe * message, ProtobufCBuffer * buffer); +Nsjail__Exe *nsjail__exe__unpack(ProtobufCAllocator * allocator, size_t len, const uint8_t * data); +void nsjail__exe__free_unpacked(Nsjail__Exe * message, ProtobufCAllocator * allocator); /* Nsjail__NsJailConfig methods */ void nsjail__ns_jail_config__init(Nsjail__NsJailConfig * message); size_t nsjail__ns_jail_config__get_packed_size(const Nsjail__NsJailConfig * message); @@ -173,6 +192,8 @@ typedef void (*Nsjail__IdMap_Closure) (const Nsjail__IdMap * message, void *closure_data); typedef void (*Nsjail__MountPt_Closure) (const Nsjail__MountPt * message, void *closure_data); +typedef void (*Nsjail__Exe_Closure) + (const Nsjail__Exe * message, void *closure_data); typedef void (*Nsjail__NsJailConfig_Closure) (const Nsjail__NsJailConfig * message, void *closure_data); @@ -184,6 +205,7 @@ extern const ProtobufCEnumDescriptor nsjail__mode__descriptor; extern const ProtobufCEnumDescriptor nsjail__log_level__descriptor; extern const ProtobufCMessageDescriptor nsjail__id_map__descriptor; extern const ProtobufCMessageDescriptor nsjail__mount_pt__descriptor; +extern const ProtobufCMessageDescriptor nsjail__exe__descriptor; extern const ProtobufCMessageDescriptor nsjail__ns_jail_config__descriptor; PROTOBUF_C__END_DECLS diff --git a/config.proto b/config.proto index 97fe0d1..28119ab 100644 --- a/config.proto +++ b/config.proto @@ -34,6 +34,11 @@ message MountPt { optional bool is_dir = 7; } +message Exe { + required string path = 1; + repeated string arg = 2; +} + message NsJailConfig { required Mode mode = 1 [default = ONCE]; optional string chroot_dir = 2; @@ -100,4 +105,6 @@ message NsJailConfig { required string macvlan_vs_ip = 54 [default = "192.168.0.2"]; required string macvlan_vs_nm = 55 [default = "255.255.255.0"]; required string macvlan_vs_gw = 56 [default = "192.168.0.1"]; + + optional Exe exec_bin = 57; }