Re: [lxc-devel] [PATCH 1/3] lxc-attach: Try really hard to determine login shell

2013-03-06 Thread Serge Hallyn
Quoting Christian Seiler (christ...@iwakd.de):
> If no command is specified, and using getpwuid() to determine the login
> shell fails, try to spawn a process that executes the utility 'getent'.
> getpwuid() may fail because of incompatibilities between the NSS
> implementations on the host and in the container.
> 
> Signed-off-by: Christian Seiler 
> ---
>  src/lxc/attach.c |  204 
> ++
>  src/lxc/attach.h |3 +
>  src/lxc/lxc_attach.c |   11 +++
>  3 files changed, 218 insertions(+)
> 
> diff --git a/src/lxc/attach.c b/src/lxc/attach.c
> index af3d7a0..88356e1 100644
> --- a/src/lxc/attach.c
> +++ b/src/lxc/attach.c
> @@ -32,7 +32,9 @@
>  #include 
>  #include 
>  #include 
> +#include 
>  #include 
> +#include 
>  
>  #if !HAVE_DECL_PR_CAPBSET_DROP
>  #define PR_CAPBSET_DROP 24
> @@ -275,3 +277,205 @@ int lxc_attach_drop_privs(struct lxc_proc_context_info 
> *ctx)
>  
>   return 0;
>  }
> +
> +struct passwd *lxc_attach_getpwuid(uid_t uid)
> +{
> + /* static variables for result, we assume that
> +  * 256 is large enough to hold the information

I don't see anything in getpwent or passd(5) man pages
suggesting that's enough, though.  We don't want to
risk overflows or funkiness in a host's privileged
attach user due to malice in a container.

Is there any reason not to just keep char*s for each
field you find in line until you verify pw_uid matches,
and when it does then just strdup the values for the
struct passwd?  (You can set the ':' locations to '\0'
to make strdup work fine).  That should leave the code
a lot simpler.

If we have an actual guarantee that 256 will be enough
then ignore the above - I just don't know where such a
guarantee comes from.

> +  * on username, passwd and gecos. for paths we
> +  * use MAXPATHLEN instead
> +  */
> + static char pwstruct_name[256];
> + static char pwstruct_passwd[256];
> + static char pwstruct_gecos[256];
> + static char pwstruct_dir[MAXPATHLEN];
> + static char pwstruct_shell[MAXPATHLEN];
> + static struct passwd result = {
> + .pw_name = pwstruct_name,
> + .pw_passwd = pwstruct_passwd,
> + .pw_uid = (uid_t) -1,
> + .pw_gid = (gid_t) -1,
> + .pw_gecos = pwstruct_gecos,
> + .pw_dir = pwstruct_dir,
> + .pw_shell = pwstruct_shell,
> + };
> +
> + /* local variables */
> + pid_t pid;
> + int pipes[2];
> + int ret;
> + int fd;
> +
> + /* we need to fork off a process that runs the
> +  * getent program, and we need to capture its
> +  * output, so we use a pipe for that purpose
> +  */
> + ret = pipe(pipes);
> + if (ret < 0)
> + return NULL;
> +
> + pid = fork();
> + if (pid < 0) {
> + close(pipes[0]);
> + close(pipes[1]);
> + return NULL;
> + }
> +
> + if (pid) {
> + /* parent process */
> + FILE *pipe_f;
> + char *line = NULL;
> + size_t line_bufsz = 0;
> + int found = 0;
> + int status;
> +
> + close(pipes[1]);
> +
> + pipe_f = fdopen(pipes[0], "r");
> + while (getline(&line, &line_bufsz, pipe_f) != -1) {
> + char *token;
> + char *saveptr = NULL;
> + long value;
> + char *endptr = NULL;
> + int i;
> +
> + /* if we already found something, just continue
> +  * to read until the pipe doesn't deliver any more
> +  * data, but don't modify the existing data
> +  * structure
> +  */
> + if (found)
> + continue;
> +
> + /* trim line on the right hand side */
> + for (i = strlen(line); line && i > 0 && (line[i - 1] == 
> '\n' || line[i - 1] == '\r'); --i)

is the check for 'line' necessary there?

> + line[i - 1] = '\0';
> +
> + /* split into tokens: first user name */
> + token = strtok_r(line, ":", &saveptr);
> + if (!token)
> + continue;
> + snprintf(pwstruct_name, sizeof(pwstruct_name), "%s", 
> token);
> +
> + /* next: dummy password field */
> + token = strtok_r(NULL, ":", &saveptr);
> + if (!token)
> + continue;
> + snprintf(pwstruct_passwd, sizeof(pwstruct_passwd), 
> "%s", token);
> +
> + /* next: user id */
> + token = strtok_r(NULL, ":", &saveptr);
> + value = token ? strtol(token, &endptr, 10) : 0;
> + if (!token || !endptr || *endptr || value == LONG

Re: [lxc-devel] [PATCH 0/3] lxc-attach improvements

2013-03-06 Thread Serge Hallyn
Quoting Christian Seiler (christ...@iwakd.de):
> Hi Serge,
> 
> here are my patches as emails to the lxc-devel list. The first patch
> implements the getent(1) logic for trying much harder to determine the
> correct login shell of the requested user (but only if getpwuid(3)
> fails), the second patch uses /bin/sh as a fallback if even that fails
> and the third patch tries to detect the user & group id of init when
> attaching to a user namespace.
> 
> The patches can be found in the attach-fixes-1 branch over at github
> 

This was perfect, btw, thanks.

--
Symantec Endpoint Protection 12 positioned as A LEADER in The Forrester  
Wave(TM): Endpoint Security, Q1 2013 and "remains a good choice" in the  
endpoint security space. For insight on selecting the right partner to 
tackle endpoint security challenges, access the full report. 
http://p.sf.net/sfu/symantec-dev2dev
___
Lxc-devel mailing list
Lxc-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/lxc-devel


Re: [lxc-devel] [PATCH 2/3] lxc-attach: Default to /bin/sh if shell cannot be determined or exec'd

2013-03-06 Thread Serge Hallyn
Quoting Christian Seiler (christ...@iwakd.de):
> If getpwuid() fails and also the fallback of spawning of a 'getent'
> process, and the user specified no command to execute, default to
> /bin/sh and only fail if even that is not available. This should ensure
> that unless the container is *really* weird, no matter what, the user
> should always end up with a shell when calling lxc-attach with no
> further arguments.

Acked-by: Serge E. Hallyn 

> ---
>  src/lxc/lxc_attach.c |   16 +++-
>  1 file changed, 11 insertions(+), 5 deletions(-)
> 
> diff --git a/src/lxc/lxc_attach.c b/src/lxc/lxc_attach.c
> index d84c3d8..9c86ffe 100644
> --- a/src/lxc/lxc_attach.c
> +++ b/src/lxc/lxc_attach.c
> @@ -449,15 +449,21 @@ int main(int argc, char *argv[])
>   if (!passwd)
>   passwd = lxc_attach_getpwuid(uid);
>  
> - if (!passwd) {
> - SYSERROR("failed to get passwd "\
> -  "entry for uid '%d'", uid);
> - return -1;
> + if (passwd) {
> + char *const args[] = {
> + passwd->pw_shell,
> + NULL,
> + };
> +
> + (void) execvp(args[0], args);
>   }
>  
> + /* executed if either no passwd entry or execvp fails,
> +  * we will fall back on /bin/sh as a default shell
> +  */
>   {
>   char *const args[] = {
> - passwd->pw_shell,
> + "/bin/sh",
>   NULL,
>   };
>  
> -- 
> 1.7.10.4
> 

--
Symantec Endpoint Protection 12 positioned as A LEADER in The Forrester  
Wave(TM): Endpoint Security, Q1 2013 and "remains a good choice" in the  
endpoint security space. For insight on selecting the right partner to 
tackle endpoint security challenges, access the full report. 
http://p.sf.net/sfu/symantec-dev2dev
___
Lxc-devel mailing list
Lxc-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/lxc-devel


Re: [lxc-devel] [PATCH 1/3] lxc-attach: Try really hard to determine login shell

2013-03-06 Thread Serge Hallyn
Quoting Christian Seiler (christ...@iwakd.de):
> If no command is specified, and using getpwuid() to determine the login
> shell fails, try to spawn a process that executes the utility 'getent'.
> getpwuid() may fail because of incompatibilities between the NSS
> implementations on the host and in the container.

Actually, I think it would be better to have lxc_attach_getpwuid()
become lxc_attach_getpwshell(), and change the caller a bit.
Would shorten up the code quite a bit.  What do you think?

> Signed-off-by: Christian Seiler 
> ---
>  src/lxc/attach.c |  204 
> ++
>  src/lxc/attach.h |3 +
>  src/lxc/lxc_attach.c |   11 +++
>  3 files changed, 218 insertions(+)
> 
> diff --git a/src/lxc/attach.c b/src/lxc/attach.c
> index af3d7a0..88356e1 100644
> --- a/src/lxc/attach.c
> +++ b/src/lxc/attach.c
> @@ -32,7 +32,9 @@
>  #include 
>  #include 
>  #include 
> +#include 
>  #include 
> +#include 
>  
>  #if !HAVE_DECL_PR_CAPBSET_DROP
>  #define PR_CAPBSET_DROP 24
> @@ -275,3 +277,205 @@ int lxc_attach_drop_privs(struct lxc_proc_context_info 
> *ctx)
>  
>   return 0;
>  }
> +
> +struct passwd *lxc_attach_getpwuid(uid_t uid)
> +{
> + /* static variables for result, we assume that
> +  * 256 is large enough to hold the information
> +  * on username, passwd and gecos. for paths we
> +  * use MAXPATHLEN instead
> +  */
> + static char pwstruct_name[256];
> + static char pwstruct_passwd[256];
> + static char pwstruct_gecos[256];
> + static char pwstruct_dir[MAXPATHLEN];
> + static char pwstruct_shell[MAXPATHLEN];
> + static struct passwd result = {
> + .pw_name = pwstruct_name,
> + .pw_passwd = pwstruct_passwd,
> + .pw_uid = (uid_t) -1,
> + .pw_gid = (gid_t) -1,
> + .pw_gecos = pwstruct_gecos,
> + .pw_dir = pwstruct_dir,
> + .pw_shell = pwstruct_shell,
> + };
> +
> + /* local variables */
> + pid_t pid;
> + int pipes[2];
> + int ret;
> + int fd;
> +
> + /* we need to fork off a process that runs the
> +  * getent program, and we need to capture its
> +  * output, so we use a pipe for that purpose
> +  */
> + ret = pipe(pipes);
> + if (ret < 0)
> + return NULL;
> +
> + pid = fork();
> + if (pid < 0) {
> + close(pipes[0]);
> + close(pipes[1]);
> + return NULL;
> + }
> +
> + if (pid) {
> + /* parent process */
> + FILE *pipe_f;
> + char *line = NULL;
> + size_t line_bufsz = 0;
> + int found = 0;
> + int status;
> +
> + close(pipes[1]);
> +
> + pipe_f = fdopen(pipes[0], "r");
> + while (getline(&line, &line_bufsz, pipe_f) != -1) {
> + char *token;
> + char *saveptr = NULL;
> + long value;
> + char *endptr = NULL;
> + int i;
> +
> + /* if we already found something, just continue
> +  * to read until the pipe doesn't deliver any more
> +  * data, but don't modify the existing data
> +  * structure
> +  */
> + if (found)
> + continue;
> +
> + /* trim line on the right hand side */
> + for (i = strlen(line); line && i > 0 && (line[i - 1] == 
> '\n' || line[i - 1] == '\r'); --i)
> + line[i - 1] = '\0';
> +
> + /* split into tokens: first user name */
> + token = strtok_r(line, ":", &saveptr);
> + if (!token)
> + continue;
> + snprintf(pwstruct_name, sizeof(pwstruct_name), "%s", 
> token);
> +
> + /* next: dummy password field */
> + token = strtok_r(NULL, ":", &saveptr);
> + if (!token)
> + continue;
> + snprintf(pwstruct_passwd, sizeof(pwstruct_passwd), 
> "%s", token);
> +
> + /* next: user id */
> + token = strtok_r(NULL, ":", &saveptr);
> + value = token ? strtol(token, &endptr, 10) : 0;
> + if (!token || !endptr || *endptr || value == LONG_MIN 
> || value == LONG_MAX)
> + continue;
> + result.pw_uid = (uid_t) value;
> + /* dummy sanity check: user id matches */
> + if (result.pw_uid != uid)
> + continue;
> +
> + /* next: gid */
> + token = strtok_r(NULL, ":", &saveptr);
> + value = token ? strtol(token, &endptr, 10) : 0;
> + 

Re: [lxc-devel] [PATCH 3/3] lxc-attach: User namespaces: Use init's user & group id when attaching

2013-03-06 Thread Serge Hallyn
Quoting Christian Seiler (christ...@iwakd.de):
> When attaching to a container with a user namespace, try to detect the
> user and group ids of init via /proc and attach as that same user. Only
> if that is unsuccessful, fall back to (0, 0).
> ---
>  src/lxc/attach.c |   53 
> ++
>  src/lxc/attach.h |2 ++
>  src/lxc/lxc_attach.c |   15 ++
>  3 files changed, 66 insertions(+), 4 deletions(-)
> 
> diff --git a/src/lxc/attach.c b/src/lxc/attach.c
> index 88356e1..399ec36 100644
> --- a/src/lxc/attach.c
> +++ b/src/lxc/attach.c
> @@ -479,3 +479,56 @@ struct passwd *lxc_attach_getpwuid(uid_t uid)
>   exit(-1);
>   }
>  }
> +
> +int lxc_attach_get_init_uidgid(uid_t* init_uid, gid_t* init_gid)
> +{
> + FILE *proc_file;
> + char proc_fn[MAXPATHLEN];
> + char *line = NULL;
> + size_t line_bufsz = 0;
> + int ret;
> + long value = -1;
> + uid_t uid = (uid_t)-1;
> + gid_t gid = (gid_t)-1;
> +
> + /* read capabilities */

What does this comment mean?

> + snprintf(proc_fn, MAXPATHLEN, "/proc/%d/status", 1);
> +
> + proc_file = fopen(proc_fn, "r");
> + if (!proc_file)
> + return -1;
> +
> + while (getline(&line, &line_bufsz, proc_file) != -1) {
> + /* format is: real, effective, saved set user, fs
> +  * we only care about real uid
> +  */
> + ret = sscanf(line, "Uid: %ld", &value);
> + if (ret != EOF && ret > 0) {
> + uid = (uid_t) value;
> + } else {
> + ret = sscanf(line, "Gid: %ld", &value);
> + if (ret != EOF && ret > 0)
> + gid = (gid_t) value;
> + }
> + if (uid != (uid_t)-1 && gid != (gid_t)-1)
> + break;
> + }
> +
> + fclose(proc_file);
> + free(line);
> +
> + /* only override arguments if we found something */
> + if (uid != (uid_t)-1)
> + *init_uid = uid;
> + if (gid != (gid_t)-1)
> + *init_gid = gid;
> +
> + /* TODO: we should also parse supplementary groups and use
> +  * setgroups() to set them */
> +
> + /* at least some entries were not found, we return error */
> + if (uid == (uid_t)-1 || gid == (gid_t)-1)
> + return -1;
> +
> + return 0;
> +}
> diff --git a/src/lxc/attach.h b/src/lxc/attach.h
> index 90e693a..1e9b87e 100644
> --- a/src/lxc/attach.h
> +++ b/src/lxc/attach.h
> @@ -41,4 +41,6 @@ extern int lxc_attach_drop_privs(struct 
> lxc_proc_context_info *ctx);
>  struct passwd;
>  extern struct passwd *lxc_attach_getpwuid(uid_t uid);
>  
> +extern int lxc_attach_get_init_uidgid(uid_t* init_uid, gid_t* init_gid);
> +
>  #endif
> diff --git a/src/lxc/lxc_attach.c b/src/lxc/lxc_attach.c
> index 9c86ffe..cdc1601 100644
> --- a/src/lxc/lxc_attach.c
> +++ b/src/lxc/lxc_attach.c
> @@ -417,13 +417,20 @@ int main(int argc, char *argv[])
>   lxc_sync_fini(handler);
>  
>   if (namespace_flags & CLONE_NEWUSER) {
> - /* XXX FIXME this should get the uid of the container 
> init and setuid to that */
> - /* XXX FIXME or perhaps try to map in the lxc-attach 
> caller's uid? */
> - if (setgid(0)) {
> + uid_t init_uid = 0;
> + gid_t init_gid = 0;
> +
> + /* ignore errors, we will fall back to root in that case
> +  * (/proc was not mounted etc.)
> +  */

It's fine if you want to do that, but then please have
lxc_attach_get_init_uidgid() return void, drop this comment
and drop the cast below :)

But also...  you don't actually re-try with init_gid/init_uid of 0.
If lxc_attach_get_init_uidgid() set one of those to -1, then you'll
just fail here.

> + (void) lxc_attach_get_init_uidgid(&init_uid, &init_gid);
> +
> + /* try to set the uid/gid combination */
> + if (setgid(init_gid)) {
>   SYSERROR("switching to container gid");
>   return -1;
>   }
> - if (setuid(0)) {
> + if (setuid(init_uid)) {
>   SYSERROR("switching to container uid");
>   return -1;
>   }
> -- 
> 1.7.10.4
> 

--
Symantec Endpoint Protection 12 positioned as A LEADER in The Forrester  
Wave(TM): Endpoint Security, Q1 2013 and "remains a good choice" in the  
endpoint security space. For insight on selecting the right partner to 
tackle endpoint security challenges, access the full report. 
http://p.sf.net/sfu/symantec-dev2dev
___
Lxc-devel mailing list
Lxc-devel@lists.sourcefor

Re: [lxc-devel] User namespaces

2013-03-06 Thread Serge Hallyn
Quoting Dwight Engen (dwight.en...@oracle.com):
> On Mon, 25 Feb 2013 20:26:21 -0800
> ebied...@xmission.com (Eric W. Biederman) wrote:
...
> > For pty's since they only have the single device node.  We can
> > probably do kuid_has_mapping and kgid_has_mapping to see if we should
> > have super user privileges over the pty.  But that is specific to
> > ptys on /dev/pts. Normal devices potentially can have device nodes
> > with different permissions in different places so we can't figure out
> > an owner for the device.
> > 
> > Eric
> > 
> 
> Yeah, I agree we don't want something pty specific. The following patch
> assumes we define a tty as belonging to the user ns of its session
> leader (and if it doesn't have one then to init_user_ns) as you first
> suggested. I added locking which avoids the race with
> disassociate_tty() and ensures the user ns doesn't get unrefed by way of
> put_pid(tty->session).
> 
> Note that I think TIOCVHANGUP should be checking for CAP_SYS_TTY_CONFIG
> instead of CAP_SYS_ADMIN to be consistent with vhangup(2), but I did
> not change that in the refactoring here.
> 
> --
> 
> From 697f842ffc709312e5775e3d1d0782079c3070dc Mon Sep 17 00:00:00 2001
> From: Dwight Engen 
> Date: Fri, 1 Mar 2013 13:49:58 -0500
> Subject: [PATCH] make vhangup and TIOCVHANGUP namespace aware
> 
> Signed-off-by: Dwight Engen 

It looks good to me.  Eric?

Acked-by: Serge E. Hallyn 

> ---
>  drivers/tty/tty_io.c | 36 ++--
>  fs/open.c|  6 +-
>  include/linux/tty.h  |  2 +-
>  3 files changed, 32 insertions(+), 12 deletions(-)
> 
> diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c
> index a057db8..764d4e7 100644
> --- a/drivers/tty/tty_io.c
> +++ b/drivers/tty/tty_io.c
> @@ -104,6 +104,7 @@
>  
>  #include 
>  #include 
> +#include 
>  
>  #undef TTY_DEBUG_HANGUP
>  
> @@ -722,6 +723,29 @@ void tty_vhangup(struct tty_struct *tty)
>  
>  EXPORT_SYMBOL(tty_vhangup);
>  
> +/**
> + *   tty_vhangup_check_cap   -   process vhangup checking for capablity
> + *
> + *   Perform a vhangup on the given tty
> + */
> +
> +static int tty_vhangup_check_cap(struct tty_struct *tty, int cap)
> +{
> + unsigned long flags;
> + int retval = 0;
> + struct user_namespace *ns = &init_user_ns;
> +
> + spin_lock_irqsave(&tty->ctrl_lock, flags);
> + if (tty->session)
> + ns = ns_of_pid(tty->session)->user_ns;
> + if (!ns_capable(ns, cap))
> + retval = -EPERM;
> + spin_unlock_irqrestore(&tty->ctrl_lock, flags);
> +
> + if (!retval)
> + tty_vhangup(tty);
> + return retval;
> +}
>  
>  /**
>   *   tty_vhangup_self-   process vhangup for own ctty
> @@ -729,15 +753,18 @@ EXPORT_SYMBOL(tty_vhangup);
>   *   Perform a vhangup on the current controlling tty
>   */
>  
> -void tty_vhangup_self(void)
> +int tty_vhangup_self(void)
>  {
>   struct tty_struct *tty;
> + int retval = 0;
>  
>   tty = get_current_tty();
>   if (tty) {
> - tty_vhangup(tty);
> + retval = tty_vhangup_check_cap(tty, CAP_SYS_TTY_CONFIG);
>   tty_kref_put(tty);
>   }
> +
> + return retval;
>  }
>  
>  /**
> @@ -2710,10 +2737,7 @@ long tty_ioctl(struct file *file, unsigned int cmd, 
> unsigned long arg)
>   case TIOCSETD:
>   return tiocsetd(tty, p);
>   case TIOCVHANGUP:
> - if (!capable(CAP_SYS_ADMIN))
> - return -EPERM;
> - tty_vhangup(tty);
> - return 0;
> + return tty_vhangup_check_cap(tty, CAP_SYS_ADMIN);
>   case TIOCGDEV:
>   {
>   unsigned int ret = new_encode_dev(tty_devnum(real_tty));
> diff --git a/fs/open.c b/fs/open.c
> index 9b33c0c..19ac16e 100644
> --- a/fs/open.c
> +++ b/fs/open.c
> @@ -1059,11 +1059,7 @@ EXPORT_SYMBOL(sys_close);
>   */
>  SYSCALL_DEFINE0(vhangup)
>  {
> - if (capable(CAP_SYS_TTY_CONFIG)) {
> - tty_vhangup_self();
> - return 0;
> - }
> - return -EPERM;
> + return tty_vhangup_self();
>  }
>  
>  /*
> diff --git a/include/linux/tty.h b/include/linux/tty.h
> index 8db1b56..c9d0e9c 100644
> --- a/include/linux/tty.h
> +++ b/include/linux/tty.h
> @@ -379,7 +379,7 @@ extern int tty_signal(int sig, struct tty_struct *tty);
>  extern void tty_hangup(struct tty_struct *tty);
>  extern void tty_vhangup(struct tty_struct *tty);
>  extern void tty_vhangup_locked(struct tty_struct *tty);
> -extern void tty_vhangup_self(void);
> +extern int tty_vhangup_self(void);
>  extern void tty_unhangup(struct file *filp);
>  extern int tty_hung_up_p(struct file *filp);
>  extern void do_SAK(struct tty_struct *tty);
> -- 
> 1.7.12.3
> 

--
Symantec Endpoint Protection 12 positioned as A LEADER in The Forrester  
Wave(TM): Endpoint Security, Q1 2013 and "remains a good choice" in the  
endpoint security space. For insight on selecting the r

Re: [lxc-devel] [PATCH 3/3] lxc-attach: User namespaces: Use init's user & group id when attaching

2013-03-06 Thread Christian Seiler
Hi Serge,

> But also...  you don't actually re-try with init_gid/init_uid of 0.
> If lxc_attach_get_init_uidgid() set one of those to -1, then you'll
> just fail here.

No, because lxc_attach_get_init_uidgid doesn't modify them, see the code
below the comment "only override arguments if we found something".

But yes, I can make it return void instead if you like - I just thought
that if somebody else wanted to use it for some other purpose at some
later point in time, it would be nice to provide some feedback.

-- Christian

--
Symantec Endpoint Protection 12 positioned as A LEADER in The Forrester  
Wave(TM): Endpoint Security, Q1 2013 and "remains a good choice" in the  
endpoint security space. For insight on selecting the right partner to 
tackle endpoint security challenges, access the full report. 
http://p.sf.net/sfu/symantec-dev2dev
___
Lxc-devel mailing list
Lxc-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/lxc-devel


Re: [lxc-devel] [PATCH 1/3] lxc-attach: Try really hard to determine login shell

2013-03-06 Thread Christian Seiler
Hi Serge,

> Actually, I think it would be better to have lxc_attach_getpwuid()
> become lxc_attach_getpwshell(), and change the caller a bit.
> Would shorten up the code quite a bit.  What do you think?

Ok, will do.

-- Christian

--
Symantec Endpoint Protection 12 positioned as A LEADER in The Forrester  
Wave(TM): Endpoint Security, Q1 2013 and "remains a good choice" in the  
endpoint security space. For insight on selecting the right partner to 
tackle endpoint security challenges, access the full report. 
http://p.sf.net/sfu/symantec-dev2dev
___
Lxc-devel mailing list
Lxc-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/lxc-devel


[lxc-devel] [PATCH] attach: handle apparmor transitions in !NEWNS cases

2013-03-06 Thread Serge Hallyn
If we're not attaching to the mount ns , then don't enter the
container's apparmor policy.  Since we're running binaries from the host
and not the container, that actually seems the sane thing to do (besides
also the lazier thing).

If we dont' do this patch, then we will need to move the apparmor attach
past the procfs remount, will need to also mount securityfs if available,
and for the !remount_proc_sys case we'll want to mount those just long
enough to do the apparmor transition.

Signed-off-by: Serge Hallyn 
---
 src/lxc/lxc_attach.c | 8 +---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/src/lxc/lxc_attach.c b/src/lxc/lxc_attach.c
index 1f60266..60d9eac 100644
--- a/src/lxc/lxc_attach.c
+++ b/src/lxc/lxc_attach.c
@@ -375,9 +375,11 @@ int main(int argc, char *argv[])
lxc_sync_fini_parent(handler);
close(cgroup_ipc_sockets[1]);
 
-   if (attach_apparmor(init_ctx->aa_profile) < 0) {
-   ERROR("failed switching apparmor profiles");
-   return -1;
+   if ((namespace_flags & CLONE_NEWNS)) {
+   if (attach_apparmor(init_ctx->aa_profile) < 0) {
+   ERROR("failed switching apparmor profiles");
+   return -1;
+   }
}
 
/* A description of the purpose of this functionality is
-- 
1.8.1.2


--
Symantec Endpoint Protection 12 positioned as A LEADER in The Forrester  
Wave(TM): Endpoint Security, Q1 2013 and "remains a good choice" in the  
endpoint security space. For insight on selecting the right partner to 
tackle endpoint security challenges, access the full report. 
http://p.sf.net/sfu/symantec-dev2dev
___
Lxc-devel mailing list
Lxc-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/lxc-devel


[lxc-devel] [PATCH v2 0/3] lxc-attach improvements

2013-03-06 Thread Christian Seiler
Hi Serge,

here are the updated versions of my patches (I also have to resend the
second one due to minor changes in the code from the first patch) that
implement the changes you requested.

They can be found in the branch attach-fixes-1-v2 at github,


-- Christian


--
Symantec Endpoint Protection 12 positioned as A LEADER in The Forrester  
Wave(TM): Endpoint Security, Q1 2013 and "remains a good choice" in the  
endpoint security space. For insight on selecting the right partner to 
tackle endpoint security challenges, access the full report. 
http://p.sf.net/sfu/symantec-dev2dev
___
Lxc-devel mailing list
Lxc-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/lxc-devel


[lxc-devel] [PATCH 1/3] lxc-attach: Try really hard to determine login shell

2013-03-06 Thread Christian Seiler
If no command is specified, and using getpwuid() to determine the login
shell fails, try to spawn a process that executes the utility 'getent'.
getpwuid() may fail because of incompatibilities between the NSS
implementations on the host and in the container.

Signed-off-by: Christian Seiler 
---
 src/lxc/attach.c |  154 ++
 src/lxc/attach.h |2 +
 src/lxc/lxc_attach.c |   18 +-
 3 files changed, 172 insertions(+), 2 deletions(-)

diff --git a/src/lxc/attach.c b/src/lxc/attach.c
index af3d7a0..d1b3b0a 100644
--- a/src/lxc/attach.c
+++ b/src/lxc/attach.c
@@ -32,7 +32,9 @@
 #include 
 #include 
 #include 
+#include 
 #include 
+#include 
 
 #if !HAVE_DECL_PR_CAPBSET_DROP
 #define PR_CAPBSET_DROP 24
@@ -275,3 +277,155 @@ int lxc_attach_drop_privs(struct lxc_proc_context_info 
*ctx)
 
return 0;
 }
+
+char *lxc_attach_getpwshell(uid_t uid)
+{
+   /* local variables */
+   pid_t pid;
+   int pipes[2];
+   int ret;
+   int fd;
+   char *result = NULL;
+
+   /* we need to fork off a process that runs the
+* getent program, and we need to capture its
+* output, so we use a pipe for that purpose
+*/
+   ret = pipe(pipes);
+   if (ret < 0)
+   return NULL;
+
+   pid = fork();
+   if (pid < 0) {
+   close(pipes[0]);
+   close(pipes[1]);
+   return NULL;
+   }
+
+   if (pid) {
+   /* parent process */
+   FILE *pipe_f;
+   char *line = NULL;
+   size_t line_bufsz = 0;
+   int found = 0;
+   int status;
+
+   close(pipes[1]);
+
+   pipe_f = fdopen(pipes[0], "r");
+   while (getline(&line, &line_bufsz, pipe_f) != -1) {
+   char *token;
+   char *saveptr = NULL;
+   long value;
+   char *endptr = NULL;
+   int i;
+
+   /* if we already found something, just continue
+* to read until the pipe doesn't deliver any more
+* data, but don't modify the existing data
+* structure
+*/
+   if (found)
+   continue;
+
+   /* trim line on the right hand side */
+   for (i = strlen(line); line && i > 0 && (line[i - 1] == 
'\n' || line[i - 1] == '\r'); --i)
+   line[i - 1] = '\0';
+
+   /* split into tokens: first user name */
+   token = strtok_r(line, ":", &saveptr);
+   if (!token)
+   continue;
+   /* next: dummy password field */
+   token = strtok_r(NULL, ":", &saveptr);
+   if (!token)
+   continue;
+   /* next: user id */
+   token = strtok_r(NULL, ":", &saveptr);
+   value = token ? strtol(token, &endptr, 10) : 0;
+   if (!token || !endptr || *endptr || value == LONG_MIN 
|| value == LONG_MAX)
+   continue;
+   /* dummy sanity check: user id matches */
+   if ((uid_t) value != uid)
+   continue;
+   /* skip fields: gid, gecos, dir, go to next field 
'shell' */
+   for (i = 0; i < 4; i++) {
+   token = strtok_r(NULL, ":", &saveptr);
+   if (!token)
+   break;
+   }
+   if (!token)
+   continue;
+   result = strdup(token);
+
+   /* sanity check that there are no fields after that */
+   token = strtok_r(NULL, ":", &saveptr);
+   if (token)
+   continue;
+
+   found = 1;
+   }
+
+   free(line);
+   fclose(pipe_f);
+   again:
+   if (waitpid(pid, &status, 0) < 0) {
+   if (errno == EINTR)
+   goto again;
+   return NULL;
+   }
+
+   /* some sanity checks: if anything even hinted at going
+* wrong: we can't be sure we have a valid result, so
+* we assume we don't
+*/
+
+   if (!WIFEXITED(status))
+   return NULL;
+
+   if (WEXITSTATUS(status) != 0)
+   return NULL;
+
+   if (!found)
+   return NULL;
+
+   return result;
+   } else {
+

[lxc-devel] [PATCH 3/3] lxc-attach: User namespaces: Use init's user & group id when attaching

2013-03-06 Thread Christian Seiler
When attaching to a container with a user namespace, try to detect the
user and group ids of init via /proc and attach as that same user. Only
if that is unsuccessful, fall back to (0, 0).

Signed-off-by: Christian Seiler 
---
 src/lxc/attach.c |   47 +++
 src/lxc/attach.h |2 ++
 src/lxc/lxc_attach.c |   15 +++
 3 files changed, 60 insertions(+), 4 deletions(-)

diff --git a/src/lxc/attach.c b/src/lxc/attach.c
index d1b3b0a..c74faf1 100644
--- a/src/lxc/attach.c
+++ b/src/lxc/attach.c
@@ -429,3 +429,50 @@ char *lxc_attach_getpwshell(uid_t uid)
exit(-1);
}
 }
+
+void lxc_attach_get_init_uidgid(uid_t* init_uid, gid_t* init_gid)
+{
+   FILE *proc_file;
+   char proc_fn[MAXPATHLEN];
+   char *line = NULL;
+   size_t line_bufsz = 0;
+   int ret;
+   long value = -1;
+   uid_t uid = (uid_t)-1;
+   gid_t gid = (gid_t)-1;
+
+   /* read capabilities */
+   snprintf(proc_fn, MAXPATHLEN, "/proc/%d/status", 1);
+
+   proc_file = fopen(proc_fn, "r");
+   if (!proc_file)
+   return;
+
+   while (getline(&line, &line_bufsz, proc_file) != -1) {
+   /* format is: real, effective, saved set user, fs
+* we only care about real uid
+*/
+   ret = sscanf(line, "Uid: %ld", &value);
+   if (ret != EOF && ret > 0) {
+   uid = (uid_t) value;
+   } else {
+   ret = sscanf(line, "Gid: %ld", &value);
+   if (ret != EOF && ret > 0)
+   gid = (gid_t) value;
+   }
+   if (uid != (uid_t)-1 && gid != (gid_t)-1)
+   break;
+   }
+
+   fclose(proc_file);
+   free(line);
+
+   /* only override arguments if we found something */
+   if (uid != (uid_t)-1)
+   *init_uid = uid;
+   if (gid != (gid_t)-1)
+   *init_gid = gid;
+
+   /* TODO: we should also parse supplementary groups and use
+* setgroups() to set them */
+}
diff --git a/src/lxc/attach.h b/src/lxc/attach.h
index f448b1e..ef5d87b 100644
--- a/src/lxc/attach.h
+++ b/src/lxc/attach.h
@@ -40,4 +40,6 @@ extern int lxc_attach_drop_privs(struct lxc_proc_context_info 
*ctx);
 
 extern char *lxc_attach_getpwshell(uid_t uid);
 
+extern void lxc_attach_get_init_uidgid(uid_t* init_uid, gid_t* init_gid);
+
 #endif
diff --git a/src/lxc/lxc_attach.c b/src/lxc/lxc_attach.c
index 711e1de..25cc2d5 100644
--- a/src/lxc/lxc_attach.c
+++ b/src/lxc/lxc_attach.c
@@ -418,13 +418,20 @@ int main(int argc, char *argv[])
lxc_sync_fini(handler);
 
if (namespace_flags & CLONE_NEWUSER) {
-   /* XXX FIXME this should get the uid of the container 
init and setuid to that */
-   /* XXX FIXME or perhaps try to map in the lxc-attach 
caller's uid? */
-   if (setgid(0)) {
+   uid_t init_uid = 0;
+   gid_t init_gid = 0;
+
+   /* ignore errors, we will fall back to root in that case
+* (/proc was not mounted etc.)
+*/
+   lxc_attach_get_init_uidgid(&init_uid, &init_gid);
+
+   /* try to set the uid/gid combination */
+   if (setgid(init_gid)) {
SYSERROR("switching to container gid");
return -1;
}
-   if (setuid(0)) {
+   if (setuid(init_uid)) {
SYSERROR("switching to container uid");
return -1;
}
-- 
1.7.10.4


--
Symantec Endpoint Protection 12 positioned as A LEADER in The Forrester  
Wave(TM): Endpoint Security, Q1 2013 and "remains a good choice" in the  
endpoint security space. For insight on selecting the right partner to 
tackle endpoint security challenges, access the full report. 
http://p.sf.net/sfu/symantec-dev2dev
___
Lxc-devel mailing list
Lxc-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/lxc-devel


[lxc-devel] [PATCH 2/3] lxc-attach: Default to /bin/sh if shell cannot be determined or exec'd

2013-03-06 Thread Christian Seiler
If getpwuid() fails and also the fallback of spawning of a 'getent'
process, and the user specified no command to execute, default to
/bin/sh and only fail if even that is not available. This should ensure
that unless the container is *really* weird, no matter what, the user
should always end up with a shell when calling lxc-attach with no
further arguments.

Signed-off-by: Christian Seiler 
---
 src/lxc/lxc_attach.c |   16 +++-
 1 file changed, 11 insertions(+), 5 deletions(-)

diff --git a/src/lxc/lxc_attach.c b/src/lxc/lxc_attach.c
index c129eb0..711e1de 100644
--- a/src/lxc/lxc_attach.c
+++ b/src/lxc/lxc_attach.c
@@ -452,15 +452,21 @@ int main(int argc, char *argv[])
 else
 user_shell = passwd->pw_shell;
 
-   if (!user_shell) {
-   SYSERROR("failed to get passwd "\
-"entry for uid '%d'", uid);
-   return -1;
+if (user_shell) {
+   char *const args[] = {
+   user_shell,
+   NULL,
+   };
+
+   (void) execvp(args[0], args);
}
 
+   /* executed if either no passwd entry or execvp fails,
+* we will fall back on /bin/sh as a default shell
+*/
{
char *const args[] = {
-   user_shell,
+   "/bin/sh",
NULL,
};
 
-- 
1.7.10.4


--
Symantec Endpoint Protection 12 positioned as A LEADER in The Forrester  
Wave(TM): Endpoint Security, Q1 2013 and "remains a good choice" in the  
endpoint security space. For insight on selecting the right partner to 
tackle endpoint security challenges, access the full report. 
http://p.sf.net/sfu/symantec-dev2dev
___
Lxc-devel mailing list
Lxc-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/lxc-devel


Re: [lxc-devel] [PATCH 1/3] lxc-attach: Try really hard to determine login shell

2013-03-06 Thread Serge Hallyn
Quoting Christian Seiler (christ...@iwakd.de):
> If no command is specified, and using getpwuid() to determine the login
> shell fails, try to spawn a process that executes the utility 'getent'.
> getpwuid() may fail because of incompatibilities between the NSS
> implementations on the host and in the container.
> 
> Signed-off-by: Christian Seiler 

Acked-by: Serge E. Hallyn 

One comment below - I'll just change it after applying yours if you
don't mind.

> ---
>  src/lxc/attach.c |  154 
> ++
>  src/lxc/attach.h |2 +
>  src/lxc/lxc_attach.c |   18 +-
>  3 files changed, 172 insertions(+), 2 deletions(-)
> 
> diff --git a/src/lxc/attach.c b/src/lxc/attach.c
> index af3d7a0..d1b3b0a 100644
> --- a/src/lxc/attach.c
> +++ b/src/lxc/attach.c
> @@ -32,7 +32,9 @@
>  #include 
>  #include 
>  #include 
> +#include 
>  #include 
> +#include 
>  
>  #if !HAVE_DECL_PR_CAPBSET_DROP
>  #define PR_CAPBSET_DROP 24
> @@ -275,3 +277,155 @@ int lxc_attach_drop_privs(struct lxc_proc_context_info 
> *ctx)
>  
>   return 0;
>  }
> +
> +char *lxc_attach_getpwshell(uid_t uid)
> +{
> + /* local variables */
> + pid_t pid;
> + int pipes[2];
> + int ret;
> + int fd;
> + char *result = NULL;
> +
> + /* we need to fork off a process that runs the
> +  * getent program, and we need to capture its
> +  * output, so we use a pipe for that purpose
> +  */
> + ret = pipe(pipes);
> + if (ret < 0)
> + return NULL;
> +
> + pid = fork();
> + if (pid < 0) {
> + close(pipes[0]);
> + close(pipes[1]);
> + return NULL;
> + }
> +
> + if (pid) {
> + /* parent process */
> + FILE *pipe_f;
> + char *line = NULL;
> + size_t line_bufsz = 0;
> + int found = 0;
> + int status;
> +
> + close(pipes[1]);
> +
> + pipe_f = fdopen(pipes[0], "r");
> + while (getline(&line, &line_bufsz, pipe_f) != -1) {
> + char *token;
> + char *saveptr = NULL;
> + long value;
> + char *endptr = NULL;
> + int i;
> +
> + /* if we already found something, just continue
> +  * to read until the pipe doesn't deliver any more
> +  * data, but don't modify the existing data
> +  * structure
> +  */
> + if (found)
> + continue;
> +
> + /* trim line on the right hand side */
> + for (i = strlen(line); line && i > 0 && (line[i - 1] == 
> '\n' || line[i - 1] == '\r'); --i)
> + line[i - 1] = '\0';
> +
> + /* split into tokens: first user name */
> + token = strtok_r(line, ":", &saveptr);
> + if (!token)
> + continue;
> + /* next: dummy password field */
> + token = strtok_r(NULL, ":", &saveptr);
> + if (!token)
> + continue;
> + /* next: user id */
> + token = strtok_r(NULL, ":", &saveptr);
> + value = token ? strtol(token, &endptr, 10) : 0;
> + if (!token || !endptr || *endptr || value == LONG_MIN 
> || value == LONG_MAX)
> + continue;
> + /* dummy sanity check: user id matches */
> + if ((uid_t) value != uid)
> + continue;
> + /* skip fields: gid, gecos, dir, go to next field 
> 'shell' */
> + for (i = 0; i < 4; i++) {
> + token = strtok_r(NULL, ":", &saveptr);
> + if (!token)
> + break;
> + }
> + if (!token)
> + continue;

If the sanity check below now fails, we ill leak result.
Not very important since we're about to exec, but I'll add
a if (result) free(result); right here.

> + result = strdup(token);
> +
> + /* sanity check that there are no fields after that */
> + token = strtok_r(NULL, ":", &saveptr);
> + if (token)
> + continue;
> +
> + found = 1;
> + }

--
Symantec Endpoint Protection 12 positioned as A LEADER in The Forrester  
Wave(TM): Endpoint Security, Q1 2013 and "remains a good choice" in the  
endpoint security space. For insight on selecting the right partner to 
tackle endpoint security challenge

Re: [lxc-devel] [PATCH 2/3] lxc-attach: Default to /bin/sh if shell cannot be determined or exec'd

2013-03-06 Thread Serge Hallyn
Quoting Christian Seiler (christ...@iwakd.de):
> If getpwuid() fails and also the fallback of spawning of a 'getent'
> process, and the user specified no command to execute, default to
> /bin/sh and only fail if even that is not available. This should ensure
> that unless the container is *really* weird, no matter what, the user
> should always end up with a shell when calling lxc-attach with no
> further arguments.
> 
> Signed-off-by: Christian Seiler 

Acked-by: Serge E. Hallyn 

> ---
>  src/lxc/lxc_attach.c |   16 +++-
>  1 file changed, 11 insertions(+), 5 deletions(-)
> 
> diff --git a/src/lxc/lxc_attach.c b/src/lxc/lxc_attach.c
> index c129eb0..711e1de 100644
> --- a/src/lxc/lxc_attach.c
> +++ b/src/lxc/lxc_attach.c
> @@ -452,15 +452,21 @@ int main(int argc, char *argv[])
>  else
>  user_shell = passwd->pw_shell;
>  
> - if (!user_shell) {
> - SYSERROR("failed to get passwd "\
> -  "entry for uid '%d'", uid);
> - return -1;
> +if (user_shell) {
> + char *const args[] = {
> + user_shell,
> + NULL,
> + };
> +
> + (void) execvp(args[0], args);
>   }
>  
> + /* executed if either no passwd entry or execvp fails,
> +  * we will fall back on /bin/sh as a default shell
> +  */
>   {
>   char *const args[] = {
> - user_shell,
> + "/bin/sh",
>   NULL,
>   };
>  
> -- 
> 1.7.10.4
> 

--
Symantec Endpoint Protection 12 positioned as A LEADER in The Forrester  
Wave(TM): Endpoint Security, Q1 2013 and "remains a good choice" in the  
endpoint security space. For insight on selecting the right partner to 
tackle endpoint security challenges, access the full report. 
http://p.sf.net/sfu/symantec-dev2dev
___
Lxc-devel mailing list
Lxc-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/lxc-devel


Re: [lxc-devel] [PATCH 3/3] lxc-attach: User namespaces: Use init's user & group id when attaching

2013-03-06 Thread Serge Hallyn
Quoting Christian Seiler (christ...@iwakd.de):
> When attaching to a container with a user namespace, try to detect the
> user and group ids of init via /proc and attach as that same user. Only
> if that is unsuccessful, fall back to (0, 0).
> 
> Signed-off-by: Christian Seiler 

Thanks Christian!

Acked-by: Serge E. Hallyn 

> ---
>  src/lxc/attach.c |   47 +++
>  src/lxc/attach.h |2 ++
>  src/lxc/lxc_attach.c |   15 +++
>  3 files changed, 60 insertions(+), 4 deletions(-)
> 
> diff --git a/src/lxc/attach.c b/src/lxc/attach.c
> index d1b3b0a..c74faf1 100644
> --- a/src/lxc/attach.c
> +++ b/src/lxc/attach.c
> @@ -429,3 +429,50 @@ char *lxc_attach_getpwshell(uid_t uid)
>   exit(-1);
>   }
>  }
> +
> +void lxc_attach_get_init_uidgid(uid_t* init_uid, gid_t* init_gid)
> +{
> + FILE *proc_file;
> + char proc_fn[MAXPATHLEN];
> + char *line = NULL;
> + size_t line_bufsz = 0;
> + int ret;
> + long value = -1;
> + uid_t uid = (uid_t)-1;
> + gid_t gid = (gid_t)-1;
> +
> + /* read capabilities */

Note I'm still not sure what the comment above here means :)

> + snprintf(proc_fn, MAXPATHLEN, "/proc/%d/status", 1);
> +
> + proc_file = fopen(proc_fn, "r");
> + if (!proc_file)
> + return;
> +
> + while (getline(&line, &line_bufsz, proc_file) != -1) {
> + /* format is: real, effective, saved set user, fs
> +  * we only care about real uid
> +  */
> + ret = sscanf(line, "Uid: %ld", &value);
> + if (ret != EOF && ret > 0) {
> + uid = (uid_t) value;
> + } else {
> + ret = sscanf(line, "Gid: %ld", &value);
> + if (ret != EOF && ret > 0)
> + gid = (gid_t) value;
> + }
> + if (uid != (uid_t)-1 && gid != (gid_t)-1)
> + break;
> + }
> +
> + fclose(proc_file);
> + free(line);
> +
> + /* only override arguments if we found something */
> + if (uid != (uid_t)-1)
> + *init_uid = uid;
> + if (gid != (gid_t)-1)
> + *init_gid = gid;
> +
> + /* TODO: we should also parse supplementary groups and use
> +  * setgroups() to set them */
> +}
> diff --git a/src/lxc/attach.h b/src/lxc/attach.h
> index f448b1e..ef5d87b 100644
> --- a/src/lxc/attach.h
> +++ b/src/lxc/attach.h
> @@ -40,4 +40,6 @@ extern int lxc_attach_drop_privs(struct 
> lxc_proc_context_info *ctx);
>  
>  extern char *lxc_attach_getpwshell(uid_t uid);
>  
> +extern void lxc_attach_get_init_uidgid(uid_t* init_uid, gid_t* init_gid);
> +
>  #endif
> diff --git a/src/lxc/lxc_attach.c b/src/lxc/lxc_attach.c
> index 711e1de..25cc2d5 100644
> --- a/src/lxc/lxc_attach.c
> +++ b/src/lxc/lxc_attach.c
> @@ -418,13 +418,20 @@ int main(int argc, char *argv[])
>   lxc_sync_fini(handler);
>  
>   if (namespace_flags & CLONE_NEWUSER) {
> - /* XXX FIXME this should get the uid of the container 
> init and setuid to that */
> - /* XXX FIXME or perhaps try to map in the lxc-attach 
> caller's uid? */
> - if (setgid(0)) {
> + uid_t init_uid = 0;
> + gid_t init_gid = 0;
> +
> + /* ignore errors, we will fall back to root in that case
> +  * (/proc was not mounted etc.)
> +  */
> + lxc_attach_get_init_uidgid(&init_uid, &init_gid);
> +
> + /* try to set the uid/gid combination */
> + if (setgid(init_gid)) {
>   SYSERROR("switching to container gid");
>   return -1;
>   }
> - if (setuid(0)) {
> + if (setuid(init_uid)) {
>   SYSERROR("switching to container uid");
>   return -1;
>   }
> -- 
> 1.7.10.4
> 

--
Symantec Endpoint Protection 12 positioned as A LEADER in The Forrester  
Wave(TM): Endpoint Security, Q1 2013 and "remains a good choice" in the  
endpoint security space. For insight on selecting the right partner to 
tackle endpoint security challenges, access the full report. 
http://p.sf.net/sfu/symantec-dev2dev
___
Lxc-devel mailing list
Lxc-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/lxc-devel


Re: [lxc-devel] [PATCH v2 0/3] lxc-attach improvements

2013-03-06 Thread Serge Hallyn
Quoting Christian Seiler (christ...@iwakd.de):
> Hi Serge,
> 
> here are the updated versions of my patches (I also have to resend the
> second one due to minor changes in the code from the first patch) that
> implement the changes you requested.
> 
> They can be found in the branch attach-fixes-1-v2 at github,
> 

Thanks - all applied to staging.

--
Symantec Endpoint Protection 12 positioned as A LEADER in The Forrester  
Wave(TM): Endpoint Security, Q1 2013 and "remains a good choice" in the  
endpoint security space. For insight on selecting the right partner to 
tackle endpoint security challenges, access the full report. 
http://p.sf.net/sfu/symantec-dev2dev
___
Lxc-devel mailing list
Lxc-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/lxc-devel


[lxc-devel] usernsselfmap

2013-03-06 Thread Serge Hallyn
Hey guys,

just to help play with user namespaces some more I pushed a C version
of Eric's script for completely unprivileged use of user namespaces to
https://code.launchpad.net/~serge-hallyn/+junk/nsexec and to the
nsexec package in ppa:serge-hallyn/userns-natty.  Appending the code
below as well.  The point is:  you unshare a new user namespace, and
in there you map uid 0 to your host uid, then start a shell.  This
requires zero setup on the host (so the shadow package updates to define
per-user subuids are not needed for these games).  From that shell you
can unshare mounts, network, uts namespace, etc, and basically be root
in your fake little domain.

It's fun.  I just './usernsselfmap', and I can pretend I'm root.

BTW, Eric, where the heck does one find the latest version of
util-linux?  Latest I could find did not yet know about userns.
(Once that lands in ubuntu I can drop my nsexec altogether, as well
as lxc-unshare)

Anyway, enjoy!

#include 
#include 
#include 
#include 
#include 

int writemaps(pid_t pid)
{
FILE *fout;
char path[1024];
int origuid = getuid();
int origgid = getgid();
int ret;

printf("starting from uid %d gid %d\n", origuid, origgid);
snprintf(path, 1024, "/proc/%d/uid_map", pid);
fout = fopen(path, "w");
ret = fprintf(fout, "0 %d 1\n", origuid);
if (ret < 0) {
perror("writing uidmap\n");
return -1;
}
ret = fclose(fout);
if (ret < 0) {
perror("closing uidmap\n");
return -1;
}

snprintf(path, 1024, "/proc/%d/gid_map", pid);
fout = fopen(path, "w");
ret = fprintf(fout, "0 %d 1\n", origgid);
if (ret < 0) {
perror("writing gidmap\n");
return -1;
}
ret = fclose(fout);
if (ret < 0) {
perror("closing gidmap\n");
return -1;
}

return 0;
}

int main(int argc, char *argv[])
{
char *args[] = { "/bin/bash", NULL };
int ret, fromchildpipe[2], tochildpipe[2];
pid_t pid;

ret = pipe(fromchildpipe);
if (ret < 0)
exit(1);
ret = pipe(tochildpipe);
if (ret < 0)
exit(1);

pid = fork();
if (pid < 0)
exit(1);
int x = 0;

if (pid > 0) {
int status;

close(fromchildpipe[1]);
close(tochildpipe[0]);
read(fromchildpipe[0], &x, sizeof(x));
if (x == 1)
exit(1);
close(fromchildpipe[0]);
ret = writemaps(pid);
if (ret < 0) {
printf("Error writing maps for %d\n", pid);
x = 1;
}
write(tochildpipe[1], &x, sizeof(x));
close(tochildpipe[1]);
waitpid(pid, &status, __WALL);
exit(x);
}
close(fromchildpipe[0]);
close(tochildpipe[1]);
ret = unshare(CLONE_NEWUSER);
if (ret < 0) {
perror("unshare");
x = 1;
write(fromchildpipe[1], &x, sizeof(x));
exit(1);
}
write(fromchildpipe[1], &x, sizeof(x));
read(tochildpipe[0], &x, sizeof(x));
if (x == 1) {
printf("error in parent writing uid maps\n");
exit(1);
}
close(fromchildpipe[1]);
close(tochildpipe[0]);
ret = setgid(0);
if (ret < 0)
perror("setgid");
ret = setuid(0);
perror("setuid");
printf("execing bash (I am  now %d %d)\n", getuid(), getgid());
execv(args[0], args);
}

--
Symantec Endpoint Protection 12 positioned as A LEADER in The Forrester  
Wave(TM): Endpoint Security, Q1 2013 and "remains a good choice" in the  
endpoint security space. For insight on selecting the right partner to 
tackle endpoint security challenges, access the full report. 
http://p.sf.net/sfu/symantec-dev2dev
___
Lxc-devel mailing list
Lxc-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/lxc-devel


[lxc-devel] Create LXC 0.8.0 rpm on/for Centos

2013-03-06 Thread Leon Waldman
Hi,


I'm trying to build the rpm using the included spec file, but the 
compile is failing with a "You must install the AppArmor development 
package in order to compile lxc".

I'm building it in/for CentOS and (AFAIK) there is no AppArmor 
development package for it.

Is there any way to build the RPM from the source tarball without it? If 
not, is there any alternative?


Thanks in advance.


--
Leon Waldman

--
Symantec Endpoint Protection 12 positioned as A LEADER in The Forrester  
Wave(TM): Endpoint Security, Q1 2013 and "remains a good choice" in the  
endpoint security space. For insight on selecting the right partner to 
tackle endpoint security challenges, access the full report. 
http://p.sf.net/sfu/symantec-dev2dev
___
Lxc-devel mailing list
Lxc-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/lxc-devel


Re: [lxc-devel] [PATCH] attach: handle apparmor transitions in !NEWNS cases

2013-03-06 Thread Stéphane Graber
On 03/06/2013 02:41 PM, Serge Hallyn wrote:
> If we're not attaching to the mount ns , then don't enter the
> container's apparmor policy.  Since we're running binaries from the host
> and not the container, that actually seems the sane thing to do (besides
> also the lazier thing).
> 
> If we dont' do this patch, then we will need to move the apparmor attach
> past the procfs remount, will need to also mount securityfs if available,
> and for the !remount_proc_sys case we'll want to mount those just long
> enough to do the apparmor transition.
> 
> Signed-off-by: Serge Hallyn 

Acked-by: Stéphane Graber 

> ---
>  src/lxc/lxc_attach.c | 8 +---
>  1 file changed, 5 insertions(+), 3 deletions(-)
> 
> diff --git a/src/lxc/lxc_attach.c b/src/lxc/lxc_attach.c
> index 1f60266..60d9eac 100644
> --- a/src/lxc/lxc_attach.c
> +++ b/src/lxc/lxc_attach.c
> @@ -375,9 +375,11 @@ int main(int argc, char *argv[])
>   lxc_sync_fini_parent(handler);
>   close(cgroup_ipc_sockets[1]);
>  
> - if (attach_apparmor(init_ctx->aa_profile) < 0) {
> - ERROR("failed switching apparmor profiles");
> - return -1;
> + if ((namespace_flags & CLONE_NEWNS)) {
> + if (attach_apparmor(init_ctx->aa_profile) < 0) {
> + ERROR("failed switching apparmor profiles");
> + return -1;
> + }
>   }
>  
>   /* A description of the purpose of this functionality is
> 


-- 
Stéphane Graber
Ubuntu developer
http://www.ubuntu.com



signature.asc
Description: OpenPGP digital signature
--
Symantec Endpoint Protection 12 positioned as A LEADER in The Forrester  
Wave(TM): Endpoint Security, Q1 2013 and "remains a good choice" in the  
endpoint security space. For insight on selecting the right partner to 
tackle endpoint security challenges, access the full report. 
http://p.sf.net/sfu/symantec-dev2dev___
Lxc-devel mailing list
Lxc-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/lxc-devel


Re: [lxc-devel] usernsselfmap

2013-03-06 Thread Eric W. Biederman
Kees Cook  writes:

> On Wed, Mar 6, 2013 at 2:25 PM, Serge Hallyn  wrote:
>> just to help play with user namespaces some more I pushed a C version
>> of Eric's script for completely unprivileged use of user namespaces to
>> https://code.launchpad.net/~serge-hallyn/+junk/nsexec and to the
>> nsexec package in ppa:serge-hallyn/userns-natty.  Appending the code
>> below as well.  The point is:  you unshare a new user namespace, and
>> in there you map uid 0 to your host uid, then start a shell.  This
>> requires zero setup on the host (so the shadow package updates to define
>> per-user subuids are not needed for these games).  From that shell you
>> can unshare mounts, network, uts namespace, etc, and basically be root
>> in your fake little domain.
>>
>> It's fun.  I just './usernsselfmap', and I can pretend I'm root.
>
> Yeah, cool. I updated my tools based on the example too. It looks like
> I was losing a race, so adding the pipe sync solved my issues. Also, I
> think you can only map a range of 1.
>
>> BTW, Eric, where the heck does one find the latest version of
>> util-linux?  Latest I could find did not yet know about userns.
>> (Once that lands in ubuntu I can drop my nsexec altogether, as well
>> as lxc-unshare)
>
> AFAICT, it hasn't been released yet. It was only in vcs. I had to go
> find libuser too. :)

git://git.kernel.org/pub/scm/utils/util-linux/util-linux

> I wish there was a cleaner way to do this kind of IPC lock-step. It's
> such a common pattern, and it's so unreadable. :)

For what it's worth.  If you are going to do a combined binary, and you
are just going to worry about yourself.  You don't have to fork to
write /proc/self/uid_map with 0 $old_uid 1.

I had originally hoped to do an upcall to validate other writes to
/proc/self/uid_map but code was never solid and I went with what works
now.

Eric


--
Symantec Endpoint Protection 12 positioned as A LEADER in The Forrester  
Wave(TM): Endpoint Security, Q1 2013 and "remains a good choice" in the  
endpoint security space. For insight on selecting the right partner to 
tackle endpoint security challenges, access the full report. 
http://p.sf.net/sfu/symantec-dev2dev
___
Lxc-devel mailing list
Lxc-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/lxc-devel


Re: [lxc-devel] usernsselfmap

2013-03-06 Thread Serge Hallyn
Quoting Eric W. Biederman (ebied...@xmission.com):
...
> For what it's worth.  If you are going to do a combined binary, and you
> are just going to worry about yourself.  You don't have to fork to
> write /proc/self/uid_map with 0 $old_uid 1.

Well, shoot!  I figured since we'd already unshared, our uid was 65534 /
-1, and there was no sensible value to insert.  Just tried with the orig
uid and it works.  Neato.

> I had originally hoped to do an upcall to validate other writes to
> /proc/self/uid_map but code was never solid and I went with what works
> now.

Right, I remember that.  This isn't so bad in the end

#include 
#include 
#include 
#include 
#include 

int writemaps(pid_t pid, int origuid, int origgid)
{
FILE *fout;
char path[1024];
int ret;

printf("starting from uid %d gid %d\n", origuid, origgid);
snprintf(path, 1024, "/proc/%d/uid_map", pid);
fout = fopen(path, "w");
ret = fprintf(fout, "0 %d 1\n", origuid);
if (ret < 0) {
perror("writing uidmap\n");
return -1;
}
ret = fclose(fout);
if (ret < 0) {
perror("closing uidmap\n");
return -1;
}

snprintf(path, 1024, "/proc/%d/gid_map", pid);
fout = fopen(path, "w");
ret = fprintf(fout, "0 %d 1\n", origgid);
if (ret < 0) {
perror("writing gidmap\n");
return -1;
}
ret = fclose(fout);
if (ret < 0) {
perror("closing gidmap\n");
return -1;
}

return 0;
}

int main(int argc, char *argv[])
{
char *args[] = { "/bin/bash", NULL };
int ret;
int origuid = getuid();
int origgid = getgid();

ret = unshare(CLONE_NEWUSER);
ret = writemaps(getpid(), origuid, origgid);
if (ret < 0) {
printf("Error writing maps\n");
exit(1);
}
if (ret < 0) {
perror("unshare");
exit(1);
}
ret = setgid(0);
if (ret < 0)
perror("setgid");
ret = setuid(0);
perror("setuid");
printf("execing bash (I am  now %d %d)\n", getuid(), getgid());
execv(args[0], args);
}

--
Symantec Endpoint Protection 12 positioned as A LEADER in The Forrester  
Wave(TM): Endpoint Security, Q1 2013 and "remains a good choice" in the  
endpoint security space. For insight on selecting the right partner to 
tackle endpoint security challenges, access the full report. 
http://p.sf.net/sfu/symantec-dev2dev
___
Lxc-devel mailing list
Lxc-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/lxc-devel


Re: [lxc-devel] usernsselfmap

2013-03-06 Thread Eric W. Biederman
Serge Hallyn  writes:

> Quoting Eric W. Biederman (ebied...@xmission.com):
> ...
>> For what it's worth.  If you are going to do a combined binary, and you
>> are just going to worry about yourself.  You don't have to fork to
>> write /proc/self/uid_map with 0 $old_uid 1.
>
> Well, shoot!  I figured since we'd already unshared, our uid was 65534 /
> -1, and there was no sensible value to insert.  Just tried with the orig
> uid and it works.  Neato.

Yes.

My shell example has to jump through hoops because exec drops the caps,
and because as an example it implements the general case.

>> I had originally hoped to do an upcall to validate other writes to
>> /proc/self/uid_map but code was never solid and I went with what works
>> now.
>
> Right, I remember that.  This isn't so bad in the end

No.

Eric

--
Symantec Endpoint Protection 12 positioned as A LEADER in The Forrester  
Wave(TM): Endpoint Security, Q1 2013 and "remains a good choice" in the  
endpoint security space. For insight on selecting the right partner to 
tackle endpoint security challenges, access the full report. 
http://p.sf.net/sfu/symantec-dev2dev
___
Lxc-devel mailing list
Lxc-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/lxc-devel