Unverified Commit e20cdd87 by 2xsec Committed by Christian Brauner

tools: lxc-attach: add default log priority & cleanups

Signed-off-by: 's avatar2xsec <dh48.jeong@samsung.com>
parent 4c61817d
...@@ -45,6 +45,21 @@ ...@@ -45,6 +45,21 @@
lxc_log_define(lxc_attach, lxc); lxc_log_define(lxc_attach, lxc);
static int my_parser(struct lxc_arguments *args, int c, char *arg);
static int add_to_simple_array(char ***array, ssize_t *capacity, char *value);
static bool stdfd_is_pty(void);
static int lxc_attach_create_log_file(const char *log_file);
static int elevated_privileges;
static signed long new_personality = -1;
static int namespace_flags = -1;
static int remount_sys_proc;
static lxc_attach_env_policy_t env_policy = LXC_ATTACH_KEEP_ENV;
static char **extra_env;
static ssize_t extra_env_size;
static char **extra_keep;
static ssize_t extra_keep_size;
static const struct option my_longopts[] = { static const struct option my_longopts[] = {
{"elevated-privileges", optional_argument, 0, 'e'}, {"elevated-privileges", optional_argument, 0, 'e'},
{"arch", required_argument, 0, 'a'}, {"arch", required_argument, 0, 'a'},
...@@ -60,43 +75,60 @@ static const struct option my_longopts[] = { ...@@ -60,43 +75,60 @@ static const struct option my_longopts[] = {
LXC_COMMON_OPTIONS LXC_COMMON_OPTIONS
}; };
static int elevated_privileges = 0; static struct lxc_arguments my_args = {
static signed long new_personality = -1; .progname = "lxc-attach",
static int namespace_flags = -1; .help = "\
static int remount_sys_proc = 0; --name=NAME [-- COMMAND]\n\
static lxc_attach_env_policy_t env_policy = LXC_ATTACH_KEEP_ENV; \n\
static char **extra_env = NULL; Execute the specified COMMAND - enter the container NAME\n\
static ssize_t extra_env_size = 0; \n\
static char **extra_keep = NULL; Options :\n\
static ssize_t extra_keep_size = 0; -n, --name=NAME NAME of the container\n\
-e, --elevated-privileges=PRIVILEGES\n\
static int add_to_simple_array(char ***array, ssize_t *capacity, char *value) Use elevated privileges instead of those of the\n\
{ container. If you don't specify privileges to be\n\
ssize_t count = 0; elevated as OR'd list: CAP, CGROUP and LSM (capabilities,\n\
cgroup and restrictions, respectively) then all of them\n\
if (!array) will be elevated.\n\
return -1; WARNING: This may leak privileges into the container.\n\
Use with care.\n\
if (*array) -a, --arch=ARCH Use ARCH for program instead of container's own\n\
for (; (*array)[count]; count++); architecture.\n\
-s, --namespaces=FLAGS\n\
/* we have to reallocate */ Don't attach to all the namespaces of the container\n\
if (count >= *capacity - 1) { but just to the following OR'd list of flags:\n\
ssize_t new_capacity = ((count + 1) / 32 + 1) * 32; MOUNT, PID, UTSNAME, IPC, USER or NETWORK.\n\
char **new_array = realloc((void*)*array, sizeof(char *) * new_capacity); WARNING: Using -s implies -e with all privileges\n\
if (!new_array) elevated, it may therefore leak privileges into the\n\
return -1; container. Use with care.\n\
memset(&new_array[count], 0, sizeof(char*)*(new_capacity - count)); -R, --remount-sys-proc\n\
*array = new_array; Remount /sys and /proc if not attaching to the\n\
*capacity = new_capacity; mount namespace when using -s in order to properly\n\
} reflect the correct namespace context. See the\n\
lxc-attach(1) manual page for details.\n\
if (!(*array)) --clear-env Clear all environment variables before attaching.\n\
return -1; The attached shell/program will start with only\n\
container=lxc set.\n\
(*array)[count] = value; --keep-env Keep all current environment variables. This\n\
return 0; is the current default behaviour, but is likely to\n\
} change in the future.\n\
-L, --pty-log=FILE\n\
Log pty output to FILE\n\
-v, --set-var Set an additional variable that is seen by the\n\
attached program in the container. May be specified\n\
multiple times.\n\
--keep-var Keep an additional environment variable. Only\n\
applicable if --clear-env is specified. May be used\n\
multiple times.\n\
-f, --rcfile=FILE\n\
Load configuration file FILE\n\
",
.options = my_longopts,
.parser = my_parser,
.checker = NULL,
.log_priority = "ERROR",
.log_file = "none",
};
static int my_parser(struct lxc_arguments *args, int c, char *arg) static int my_parser(struct lxc_arguments *args, int c, char *arg)
{ {
...@@ -160,65 +192,45 @@ static int my_parser(struct lxc_arguments *args, int c, char *arg) ...@@ -160,65 +192,45 @@ static int my_parser(struct lxc_arguments *args, int c, char *arg)
return 0; return 0;
} }
static struct lxc_arguments my_args = { static int add_to_simple_array(char ***array, ssize_t *capacity, char *value)
.progname = "lxc-attach", {
.help = "\ ssize_t count = 0;
--name=NAME [-- COMMAND]\n\
\n\ if (!array)
Execute the specified COMMAND - enter the container NAME\n\ return -1;
\n\
Options :\n\ if (*array)
-n, --name=NAME NAME of the container\n\ for (; (*array)[count]; count++);
-e, --elevated-privileges=PRIVILEGES\n\
Use elevated privileges instead of those of the\n\ /* we have to reallocate */
container. If you don't specify privileges to be\n\ if (count >= *capacity - 1) {
elevated as OR'd list: CAP, CGROUP and LSM (capabilities,\n\ ssize_t new_capacity = ((count + 1) / 32 + 1) * 32;
cgroup and restrictions, respectively) then all of them\n\
will be elevated.\n\ char **new_array = realloc((void*)*array, sizeof(char *) * new_capacity);
WARNING: This may leak privileges into the container.\n\ if (!new_array)
Use with care.\n\ return -1;
-a, --arch=ARCH Use ARCH for program instead of container's own\n\
architecture.\n\ memset(&new_array[count], 0, sizeof(char*)*(new_capacity - count));
-s, --namespaces=FLAGS\n\
Don't attach to all the namespaces of the container\n\ *array = new_array;
but just to the following OR'd list of flags:\n\ *capacity = new_capacity;
MOUNT, PID, UTSNAME, IPC, USER or NETWORK.\n\ }
WARNING: Using -s implies -e with all privileges\n\
elevated, it may therefore leak privileges into the\n\ if (!(*array))
container. Use with care.\n\ return -1;
-R, --remount-sys-proc\n\
Remount /sys and /proc if not attaching to the\n\ (*array)[count] = value;
mount namespace when using -s in order to properly\n\ return 0;
reflect the correct namespace context. See the\n\ }
lxc-attach(1) manual page for details.\n\
--clear-env Clear all environment variables before attaching.\n\
The attached shell/program will start with only\n\
container=lxc set.\n\
--keep-env Keep all current environment variables. This\n\
is the current default behaviour, but is likely to\n\
change in the future.\n\
-L, --pty-log=FILE\n\
Log pty output to FILE\n\
-v, --set-var Set an additional variable that is seen by the\n\
attached program in the container. May be specified\n\
multiple times.\n\
--keep-var Keep an additional environment variable. Only\n\
applicable if --clear-env is specified. May be used\n\
multiple times.\n\
-f, --rcfile=FILE\n\
Load configuration file FILE\n\
",
.options = my_longopts,
.parser = my_parser,
.checker = NULL,
};
static bool stdfd_is_pty(void) static bool stdfd_is_pty(void)
{ {
if (isatty(STDIN_FILENO)) if (isatty(STDIN_FILENO))
return true; return true;
if (isatty(STDOUT_FILENO)) if (isatty(STDOUT_FILENO))
return true; return true;
if (isatty(STDERR_FILENO)) if (isatty(STDERR_FILENO))
return true; return true;
...@@ -240,23 +252,19 @@ static int lxc_attach_create_log_file(const char *log_file) ...@@ -240,23 +252,19 @@ static int lxc_attach_create_log_file(const char *log_file)
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
int ret = -1, r; int ret = -1;
int wexit = 0; int wexit = 0;
struct lxc_log log; struct lxc_log log;
pid_t pid; pid_t pid;
lxc_attach_options_t attach_options = LXC_ATTACH_OPTIONS_DEFAULT; lxc_attach_options_t attach_options = LXC_ATTACH_OPTIONS_DEFAULT;
lxc_attach_command_t command = (lxc_attach_command_t){.program = NULL}; lxc_attach_command_t command = (lxc_attach_command_t){.program = NULL};
r = lxc_caps_init(); if (lxc_caps_init())
if (r)
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
r = lxc_arguments_parse(&my_args, argc, argv); if (lxc_arguments_parse(&my_args, argc, argv))
if (r)
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
/* Only create log if explicitly instructed */
if (my_args.log_file || my_args.log_priority) {
log.name = my_args.name; log.name = my_args.name;
log.file = my_args.log_file; log.file = my_args.log_file;
log.level = my_args.log_priority; log.level = my_args.log_priority;
...@@ -266,14 +274,12 @@ int main(int argc, char *argv[]) ...@@ -266,14 +274,12 @@ int main(int argc, char *argv[])
if (lxc_log_init(&log)) if (lxc_log_init(&log))
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
}
if (geteuid()) { if (geteuid())
if (access(my_args.lxcpath[0], O_RDONLY) < 0) { if (access(my_args.lxcpath[0], O_RDONLY) < 0) {
ERROR("You lack access to %s", my_args.lxcpath[0]); ERROR("You lack access to %s", my_args.lxcpath[0]);
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
}
struct lxc_container *c = lxc_container_new(my_args.name, my_args.lxcpath[0]); struct lxc_container *c = lxc_container_new(my_args.name, my_args.lxcpath[0]);
if (!c) if (!c)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment