Re: [lxc-devel] set shmmax for container in lxc-execute

2012-07-06 Thread J. Xiao
I checked all the capabilities are up before opening shmmax file.
If I seteuid to 0, the open succeeds. There seems to be a difference 
between having a root euid and a regular user having root capabilities 
in terms of writing to shmmax file.

On 7/5/2012 4:49 PM, Stéphane Graber wrote:
> On 07/05/2012 04:41 PM, J. Xiao wrote:
>> Thanks Stephane for your answer.
>>
>> However, I am running on RedHat, is there a similar file on RedHat I can
>> check?
>
> I don't know RedHat but as far as I know Ubuntu is the only distro
> currently restricting access to /proc in containers. RedHat uses SELinux
> but lxc currently doesn't have any support for it, so it's unlikely to
> be the problem.
>
> Maybe something is dropping some capabilities that are preventing you
> from changing these limits?
>
>




--
Live Security Virtual Conference
Exclusive live event will cover all the ways today's security and 
threat landscape has changed and how IT managers can respond. Discussions 
will include endpoint security, mobile security and the latest in malware 
threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/
___
Lxc-devel mailing list
Lxc-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/lxc-devel


[lxc-devel] [PATCH 0/1] support shmmax/shmall KEY for lxc-execute

2012-07-06 Thread jian
From: Jian Xiao 

Often system admin needs to change /proc/sys/kernel/shmmax and shmall values
to run a job. These values are not inherited by container and needs to be
passed to container when starting the job.

This patch adds "lxc.shmmax" and "lxc.shmall" configuration variable
for lxc-execute "-s" or "-r" option. With this, user could run a job in 
container with desired shmmax and shmall value.

Jian Xiao (1):
  support shmmax/shmall KEY for lxc-execute

 src/lxc/conf.c|  123 +
 src/lxc/conf.h|2 +
 src/lxc/confile.c |   32 ++
 3 files changed, 157 insertions(+), 0 deletions(-)


--
Live Security Virtual Conference
Exclusive live event will cover all the ways today's security and 
threat landscape has changed and how IT managers can respond. Discussions 
will include endpoint security, mobile security and the latest in malware 
threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/
___
Lxc-devel mailing list
Lxc-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/lxc-devel


[lxc-devel] [PATCH 1/1] support shmmax/shmall KEY for lxc-execute

2012-07-06 Thread jian
From: Jian Xiao 

Signed-off-by: Jian Xiao 
---
 src/lxc/conf.c|  123 +
 src/lxc/conf.h|2 +
 src/lxc/confile.c |   32 ++
 3 files changed, 157 insertions(+), 0 deletions(-)

diff --git a/src/lxc/conf.c b/src/lxc/conf.c
index e8088bb..d59731c 100644
--- a/src/lxc/conf.c
+++ b/src/lxc/conf.c
@@ -1285,6 +1285,119 @@ static int setup_caps(struct lxc_list *caps)
return 0;
 }
 
+static int setup_shmmax(unsigned long shmmax)
+{
+   int rc, fd;
+   uid_t euid = geteuid();
+   char shmmax_str[64];
+
+   if (!shmmax)
+   return 0;
+
+   snprintf(shmmax_str, sizeof(shmmax_str), "%lu", shmmax);
+
+   /* Process has all the capabilities set, but cannot open shmmax
+* to write. Temporarily set euid to root to get around this.
+* This is only done for non-root uid.
+*/
+   if (euid && seteuid(0)) {
+   SYSERROR("failed to change euid to 0\n");
+   return -1;
+   }
+
+   fd = open("/proc/sys/kernel/shmmax", O_WRONLY);
+   if (fd < 0) {
+   SYSERROR("fail to open /proc/sys/kernel/shmmax");
+   return -1;
+}
+
+   rc = write(fd, shmmax_str, strlen(shmmax_str));
+if (rc < 0) {
+   SYSERROR("fail to write /proc/sys/kernel/shmmax");
+   close(fd);
+   return -1;
+   }
+
+   close(fd);
+
+   /* set euid back */
+   if (euid) {
+   if (seteuid(euid)) {
+   ERROR("failed to change euid to '%d': %m", euid);
+   return -1;
+   }
+
+   /* seteuid() to non-zero clears effective capabilities
+* so we need to restore them
+*/
+   if (lxc_caps_up()) {
+   ERROR("failed to restore capabilities: %m");
+   return -1;
+   }
+   }
+
+   DEBUG("shmmax has been setup to %lu\n", shmmax);
+
+   return 0;
+}
+
+static int setup_shmall(unsigned long shmall)
+{
+   int rc, fd;
+   uid_t euid = geteuid();
+   char shmall_str[64];
+
+   if (!shmall)
+   return 0;
+
+   snprintf(shmall_str, sizeof(shmall_str), "%lu", shmall);
+
+   /* Process has all the capabilities set, but cannot open shmall
+* to write. Temporarily set euid to root to get around this.
+* This is only done for non-root uid.
+*/
+   if (euid && seteuid(0)) {
+   SYSERROR("failed to change euid to 0\n");
+   return -1;
+   }
+
+   fd = open("/proc/sys/kernel/shmall", O_WRONLY);
+   if (fd < 0) {
+   SYSERROR("fail to open /proc/sys/kernel/shmall");
+   return -1;
+}
+
+   rc = write(fd, shmall_str, strlen(shmall_str));
+if (rc < 0) {
+   SYSERROR("fail to write /proc/sys/kernel/shmall");
+   close(fd);
+   return -1;
+   }
+
+   close(fd);
+
+   /* set euid back */
+   if (euid) {
+   if (seteuid(euid)) {
+   ERROR("failed to change euid to '%d': %m", euid);
+   return -1;
+   }
+
+   /* seteuid() to non-zero clears effective capabilities
+* so we need to restore them
+*/
+   if (lxc_caps_up()) {
+   ERROR("failed to restore capabilities: %m");
+   return -1;
+   }
+   }
+
+   DEBUG("shmall has been setup to %lu\n", shmall);
+
+   return 0;
+}
+
+
 static int setup_hw_addr(char *hwaddr, const char *ifname)
 {
struct sockaddr sockaddr;
@@ -2047,6 +2160,16 @@ int lxc_setup(const char *name, struct lxc_conf 
*lxc_conf)
return -1;
}
 
+   if (setup_shmmax(lxc_conf->shmmax)) {
+   ERROR("failed to set shmmax");
+   return -1;
+   }
+
+   if (setup_shmall(lxc_conf->shmall)) {
+   ERROR("failed to set shmall");
+   return -1;
+   }
+
NOTICE("'%s' is setup.", name);
 
return 0;
diff --git a/src/lxc/conf.h b/src/lxc/conf.h
index 09f55cb..347521e 100644
--- a/src/lxc/conf.h
+++ b/src/lxc/conf.h
@@ -216,6 +216,8 @@ struct lxc_conf {
struct lxc_rootfs rootfs;
char *ttydir;
int close_all_fds;
+   unsigned long shmmax;
+   unsigned long shmall;
 };
 
 /*
diff --git a/src/lxc/confile.c b/src/lxc/confile.c
index b305aef..f71f4c7 100644
--- a/src/lxc/confile.c
+++ b/src/lxc/confile.c
@@ -71,6 +71,8 @@ static int config_network_ipv6(const char *, char *, struct 
lxc_conf *);
 static int config_network_ipv6_gateway(const char *, char *, struct lxc_conf 
*);
 static int config_cap_drop(const char *, char *, struct lxc_conf *);
 static int config_console(const char *, char *, struct lxc_conf *);
+static int config_shmmax(const char *, 

Re: [lxc-devel] set shmmax for container in lxc-execute

2012-07-06 Thread Serge Hallyn
Quoting J. Xiao (j...@linux.vnet.ibm.com):
> I checked all the capabilities are up before opening shmmax file.
> If I seteuid to 0, the open succeeds. There seems to be a difference 
> between having a root euid and a regular user having root capabilities 
> in terms of writing to shmmax file.

Yup, for sysctl files your uid is checked.  A simple program to
demonstrate:

#include 
#include 
#include 
#include 
#include 

void setcaps(void) {
cap_value_t v;
cap_t caps = cap_get_proc();
for (v=0; v<32; v++) {
cap_set_flag(caps, CAP_EFFECTIVE, 1, &v, CAP_SET);
}
cap_set_proc(caps);
}

int main()
{
prctl(PR_SET_KEEPCAPS, 1);
seteuid(1000);
setcaps();
FILE *f = fopen("/proc/sys/kernel/shmmax", "w");
if (f == NULL)
perror("fopen");
else
fclose(f);
printf("I am %d\n", getpid());
sleep(20); // if you want a chance to check /proc/$pid/status
exit(0);
}

--
Live Security Virtual Conference
Exclusive live event will cover all the ways today's security and 
threat landscape has changed and how IT managers can respond. Discussions 
will include endpoint security, mobile security and the latest in malware 
threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/
___
Lxc-devel mailing list
Lxc-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/lxc-devel


Re: [lxc-devel] [PATCH 1/1] support shmmax/shmall KEY for lxc-execute

2012-07-06 Thread Serge Hallyn
Quoting j...@linux.vnet.ibm.com (j...@linux.vnet.ibm.com):
> From: Jian Xiao 
> 
> Signed-off-by: Jian Xiao 

Two issues below.

> ---
>  src/lxc/conf.c|  123 
> +
>  src/lxc/conf.h|2 +
>  src/lxc/confile.c |   32 ++
>  3 files changed, 157 insertions(+), 0 deletions(-)
> 
> diff --git a/src/lxc/conf.c b/src/lxc/conf.c
> index e8088bb..d59731c 100644
> --- a/src/lxc/conf.c
> +++ b/src/lxc/conf.c
> @@ -1285,6 +1285,119 @@ static int setup_caps(struct lxc_list *caps)
>   return 0;
>  }
>  
> +static int setup_shmmax(unsigned long shmmax)

setup_shmmax and setup_shmall are identical except for the shmmax/shmall
strings.  Can you use one function for both and pass in the string to
use?

> +{
> + int rc, fd;
> + uid_t euid = geteuid();
> + char shmmax_str[64];
> +
> + if (!shmmax)
> + return 0;
> +
> + snprintf(shmmax_str, sizeof(shmmax_str), "%lu", shmmax);
> +
> + /* Process has all the capabilities set, but cannot open shmmax
> +  * to write. Temporarily set euid to root to get around this.
> +  * This is only done for non-root uid.
> +  */
> + if (euid && seteuid(0)) {
> + SYSERROR("failed to change euid to 0\n");
> + return -1;
> + }
> +
> + fd = open("/proc/sys/kernel/shmmax", O_WRONLY);
> + if (fd < 0) {
> + SYSERROR("fail to open /proc/sys/kernel/shmmax");
> + return -1;
> +}
> +
> + rc = write(fd, shmmax_str, strlen(shmmax_str));
> +if (rc < 0) {
> + SYSERROR("fail to write /proc/sys/kernel/shmmax");
> + close(fd);
> + return -1;
> + }
> +
> + close(fd);
> +
> + /* set euid back */
> + if (euid) {
> + if (seteuid(euid)) {
> + ERROR("failed to change euid to '%d': %m", euid);
> + return -1;
> + }
> +
> + /* seteuid() to non-zero clears effective capabilities
> +  * so we need to restore them
> +  */
> + if (lxc_caps_up()) {
> + ERROR("failed to restore capabilities: %m");
> + return -1;
> + }
> + }
> +
> + DEBUG("shmmax has been setup to %lu\n", shmmax);
> +
> + return 0;
> +}
> +
> +static int setup_shmall(unsigned long shmall)
> +{
> + int rc, fd;
> + uid_t euid = geteuid();
> + char shmall_str[64];
> +
> + if (!shmall)
> + return 0;
> +
> + snprintf(shmall_str, sizeof(shmall_str), "%lu", shmall);
> +
> + /* Process has all the capabilities set, but cannot open shmall
> +  * to write. Temporarily set euid to root to get around this.
> +  * This is only done for non-root uid.
> +  */
> + if (euid && seteuid(0)) {
> + SYSERROR("failed to change euid to 0\n");
> + return -1;
> + }
> +
> + fd = open("/proc/sys/kernel/shmall", O_WRONLY);
> + if (fd < 0) {
> + SYSERROR("fail to open /proc/sys/kernel/shmall");
> + return -1;
> +}
> +
> + rc = write(fd, shmall_str, strlen(shmall_str));
> +if (rc < 0) {
> + SYSERROR("fail to write /proc/sys/kernel/shmall");
> + close(fd);
> + return -1;
> + }
> +
> + close(fd);
> +
> + /* set euid back */
> + if (euid) {
> + if (seteuid(euid)) {
> + ERROR("failed to change euid to '%d': %m", euid);
> + return -1;
> + }
> +
> + /* seteuid() to non-zero clears effective capabilities
> +  * so we need to restore them
> +  */
> + if (lxc_caps_up()) {
> + ERROR("failed to restore capabilities: %m");
> + return -1;
> + }
> + }
> +
> + DEBUG("shmall has been setup to %lu\n", shmall);
> +
> + return 0;
> +}
> +
> +
>  static int setup_hw_addr(char *hwaddr, const char *ifname)
>  {
>   struct sockaddr sockaddr;
> @@ -2047,6 +2160,16 @@ int lxc_setup(const char *name, struct lxc_conf 
> *lxc_conf)
>   return -1;
>   }
>  
> + if (setup_shmmax(lxc_conf->shmmax)) {
> + ERROR("failed to set shmmax");
> + return -1;
> + }
> +
> + if (setup_shmall(lxc_conf->shmall)) {
> + ERROR("failed to set shmall");
> + return -1;
> + }
> +

You should move this up before the pivot_root(), as it's possible that
/proc won't yet be mounted in the container.

Other than that,

Acked-by: Serge Hallyn 

>   NOTICE("'%s' is setup.", name);
>  
>   return 0;
> diff --git a/src/lxc/conf.h b/src/lxc/conf.h
> index 09f55cb..347521e 100644
> --- a/src/lxc/conf.h
> +++ b/src/lxc/conf.h
> @@ -216,6 +216,8 @@ struct lxc_conf {
>   struct lxc_rootfs rootfs;
>   char *ttydir;
>   int close_all_fds;
> + unsigned long shmmax;
> +