[prev in list] [next in list] [prev in thread] [next in thread]
List: gentoo-portage-dev
Subject: Re: [gentoo-portage-dev] [PATCH 2/3] Support FEATURES=pid-sandbox
From: Michał_Górny <mgorny () gentoo ! org>
Date: 2018-11-18 8:25:14
Message-ID: 1542529514.1293.7.camel () gentoo ! org
[Download RAW message or body]
On Sat, 2018-11-17 at 19:20 -0800, Zac Medico wrote:
> On 11/14/18 12:02 AM, Michał Górny wrote:
> > @@ -531,6 +543,15 @@ def _exec(binary, mycommand, opt_name, fd_pipes, env, gid, \
> > groups, uid, umask, errno.errorcode.get(ctypes.get_errno(), '?')),
> > noiselevel=-1)
> > else:
> > + if unshare_pid:
> > + # pid namespace requires us to become init
> > + # TODO: do init-ty stuff
> > + # therefore, fork() ASAP
> > + fork_ret = os.fork()
> > + if fork_ret != 0:
> > + pid, status = os.waitpid(fork_ret, 0)
> > + assert pid == fork_ret
> > + os._exit(status)
> > if unshare_mount:
> > # mark the whole filesystem as private to avoid
> > # mounts escaping the namespace
> > @@ -541,6 +562,18 @@ def _exec(binary, mycommand, opt_name, fd_pipes, env, gid, \
> > groups, uid, umask, # TODO: should it be fatal maybe?
> > writemsg("Unable to mark mounts private: %d\n" % (mount_ret,),
> > noiselevel=-1)
> > + if unshare_pid:
> > + if mount_ret != 0:
> > + # can't proceed without private mounts
> > + os._exit(1)
>
> For the benefit of anyone not watching
> https://github.com/gentoo/portage/pull/379, the mount_ret is expected
> to be non-zero inside a chroot where `mount --make-rprivate /` would
> fail because / is not a mountpoint, and this is an extremely valuable
> use case for tools like catalyst that perform builds inside a chroot.
>
> Based on /proc/[pid]/mountinfo documentation in the proc(5) manpage,
> and empirical analysis of /proc/self/mountinfo in various states,
> it should be reasonable to assume that the current propagation flags
> are suitable if there is not a shared / or /proc mountpoint found in
> /proc/self/mountinfo. We can use a function like this to check if the
> `mount --make-rprivate /` call is needed:
>
> def want_make_rprivate():
> try:
> with open('/proc/self/mountinfo', 'rb') as f:
> if re.match(rb'^\S+ \S+ \S+ \S+ (?P<mountpoint>/|/proc) \S+ (?:\S+:\S+ \
> )*(?P<shared>shared:\S+ )', f.read(), re.MULTILINE) is None: return False
> except EnvironmentError:
> pass
> return True
Technically speaking, FEATURES=mount-sandbox goes beyond /proc, so
making it guess based on the state of /proc is wrong. Yes, we need only
/proc for the purpose of pid-sandbox but we shouldn't presume the user
wouldn't want more.
Maybe we should split the logic more, and e.g. be more fatal about
--make-rprivate failing when mount-sandbox is explicitly used, and only
care about /proc when pid-sandbox is only used. In the latter case, it
probably doesn't make sense to check but just try to --make-private
/proc. /proc is naturally a mountpoint, so it should cause no harm to
privatize it.
Also, after some extra reading I think we should use 'slave' instead of
'private'. Having things implicitly 'private' might be surprising since
user's actions won't propagate into the build namespace, and I think we
want them to propagate.
--
Best regards,
Michał Górny
["signature.asc" (application/pgp-signature)]
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic