On Tue, Nov 19, 2013 at 04:17:44PM +0000, Serge Hallyn wrote: > From: Serge Hallyn <serge.hal...@ubuntu.com> > > Temporarily set our euid back to the calling ruid, so that the > access(2) check can succeed based on the euid being the userns > creator. > > Also switch from atoi to strtol > > Signed-off-by: Serge Hallyn <serge.hal...@ubuntu.com>
Acked-by: Stéphane Graber <stgra...@ubuntu.com> > --- > src/lxc/lxc_user_nic.c | 64 > +++++++++++++++++++++++++++++++++++++++++++++----- > 1 file changed, 58 insertions(+), 6 deletions(-) > > diff --git a/src/lxc/lxc_user_nic.c b/src/lxc/lxc_user_nic.c > index e4f59fa..c8513ba 100644 > --- a/src/lxc/lxc_user_nic.c > +++ b/src/lxc/lxc_user_nic.c > @@ -540,7 +540,7 @@ int lxc_netdev_delete_by_name(const char *name) > > #endif > > -bool create_nic(char *nic, char *br, char *pidstr, char **cnic) > +bool create_nic(char *nic, char *br, int pid, char **cnic) > { > #if ISTEST > char path[200]; > @@ -556,7 +556,6 @@ bool create_nic(char *nic, char *br, char *pidstr, char > **cnic) > veth1buf = alloca(IFNAMSIZ); > veth2buf = alloca(IFNAMSIZ); > int ret; > - int pid = atoi(pidstr); > > ret = snprintf(veth1buf, IFNAMSIZ, "%s", nic); > if (ret < 0 || ret >= IFNAMSIZ) { > @@ -596,7 +595,7 @@ out_del: > * *dest will container the name (lxcuser-%d) which is attached > * on the host to the lxc bridge > */ > -void get_new_nicname(char **dest, char *br, char *pid, char **cnic) > +void get_new_nicname(char **dest, char *br, int pid, char **cnic) > { > int i = 0; > // TODO - speed this up. For large installations we won't > @@ -679,7 +678,7 @@ int count_entries(char *buf, off_t len, char *me, char > *t, char *br) > * The dbfile has lines of the format: > * user type bridge nicname > */ > -bool get_nic_if_avail(int fd, char *me, char *pid, char *intype, char *br, > int allowed, char **nicname, char **cnic) > +bool get_nic_if_avail(int fd, char *me, int pid, char *intype, char *br, int > allowed, char **nicname, char **cnic) > { > off_t len, slen; > struct stat sb; > @@ -857,6 +856,47 @@ out_err: > return -1; > } > > +/* > + * If the caller (real uid, not effective uid) may read the > + * /proc/pid/net/ns, then it is either the caller's netns or one > + * which it created. > + */ > +static bool may_access_netns(int pid) > +{ > + int ret; > + char s[200]; > + uid_t ruid, suid, euid; > + bool may_access = false; > + > + ret = getresuid(&ruid, &euid, &suid); > + if (ret) { > + fprintf(stderr, "Failed to get my uids: %s\n", strerror(errno)); > + return false; > + } > + ret = setresuid(ruid, ruid, euid); > + if (ret) { > + fprintf(stderr, "Failed to set temp uids to (%d,%d,%d): %s\n", > + (int)ruid, (int)ruid, (int)euid, > strerror(errno)); > + return false; > + } > + ret = snprintf(s, 200, "/proc/%d/ns/net", pid); > + if (ret < 0 || ret >= 200) // can't happen > + return false; > + ret = access(s, R_OK); > + if (ret) { > + fprintf(stderr, "Uid %d may not access %s: %s\n", > + (int)ruid, s, strerror(errno)); > + } > + may_access = ret == 0; > + ret = setresuid(ruid, euid, suid); > + if (ret) { > + fprintf(stderr, "Failed to restore uids to (%d,%d,%d): %s\n", > + (int)ruid, (int)euid, (int)suid, > strerror(errno)); > + may_access = false; > + } > + return may_access; > +} > + > int main(int argc, char *argv[]) > { > int n, fd; > @@ -879,6 +919,13 @@ int main(int argc, char *argv[]) > else > vethname = "eth0"; > > + errno = 0; > + pid = (int) strtol(argv[1], NULL, 10); > + if (errno) { > + fprintf(stderr, "Could not read pid: %s\n", argv[1]); > + exit(1); > + } > + > if (!create_db_dir(DB_FILE)) { > fprintf(stderr, "Failed to create directory for db file\n"); > exit(1); > @@ -889,16 +936,21 @@ int main(int argc, char *argv[]) > exit(1); > } > > + if (!may_access_netns(pid)) { > + fprintf(stderr, "User %s may not modify netns for pid %d\n", > + me, pid); > + exit(1); > + } > + > n = get_alloted(me, argv[2], argv[3]); > if (n > 0) > - gotone = get_nic_if_avail(fd, me, argv[1], argv[2], argv[3], n, > &nicname, &cnic); > + gotone = get_nic_if_avail(fd, me, pid, argv[2], argv[3], n, > &nicname, &cnic); > close(fd); > if (!gotone) { > fprintf(stderr, "Quota reached\n"); > exit(1); > } > > - pid = atoi(argv[1]); > // Now rename the link > if (rename_in_ns(pid, cnic, vethname) < 0) { > fprintf(stderr, "Failed to rename the link\n"); > -- > 1.8.3.2 > > > ------------------------------------------------------------------------------ > Shape the Mobile Experience: Free Subscription > Software experts and developers: Be at the forefront of tech innovation. > Intel(R) Software Adrenaline delivers strategic insight and game-changing > conversations that shape the rapidly evolving mobile landscape. Sign up now. > http://pubads.g.doubleclick.net/gampad/clk?id=63431311&iu=/4140/ostg.clktrk > _______________________________________________ > Lxc-devel mailing list > Lxc-devel@lists.sourceforge.net > https://lists.sourceforge.net/lists/listinfo/lxc-devel -- Stéphane Graber Ubuntu developer http://www.ubuntu.com
signature.asc
Description: Digital signature
------------------------------------------------------------------------------ Shape the Mobile Experience: Free Subscription Software experts and developers: Be at the forefront of tech innovation. Intel(R) Software Adrenaline delivers strategic insight and game-changing conversations that shape the rapidly evolving mobile landscape. Sign up now. http://pubads.g.doubleclick.net/gampad/clk?id=63431311&iu=/4140/ostg.clktrk
_______________________________________________ Lxc-devel mailing list Lxc-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/lxc-devel