Go to:
Gentoo Home
Documentation
Forums
Lists
Bugs
Planet
Store
Wiki
Get Gentoo!
Gentoo's Bugzilla – Attachment 356282 Details for
Bug 481450
sys-apps/portage: FEATURES=network-sandbox to unshare() networking in ebuilds
Home
|
New
–
[Ex]
|
Browse
|
Search
|
Privacy Policy
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
Unshare networking in ebuilds
0001-Support-unsharing-network-namespaces-in-ebuild.patch (text/plain), 6.07 KB, created by
Michał Górny
on 2013-08-17 10:50:35 UTC
(
hide
)
Description:
Unshare networking in ebuilds
Filename:
MIME Type:
Creator:
Michał Górny
Created:
2013-08-17 10:50:35 UTC
Size:
6.07 KB
patch
obsolete
>From 587e4e0ef74575e9ed830abd6429c1325df9c151 Mon Sep 17 00:00:00 2001 >From: =?UTF-8?q?Micha=C5=82=20G=C3=B3rny?= <mgorny@gentoo.org> >Date: Sat, 17 Aug 2013 12:28:05 +0200 >Subject: [PATCH] Support unsharing network namespaces in ebuild. > >This way, only privileged phases (pkg_* and src_unpack) have network >access during the ebuild run. All of the src_* phases are completely >detached from host's network interfaces. >--- > pym/portage/package/ebuild/doebuild.py | 21 ++++++++++++++++++++- > pym/portage/process.py | 32 +++++++++++++++++++++++++++----- > 2 files changed, 47 insertions(+), 6 deletions(-) > >diff --git a/pym/portage/package/ebuild/doebuild.py b/pym/portage/package/ebuild/doebuild.py >index 1cf5dc6..59a0474 100644 >--- a/pym/portage/package/ebuild/doebuild.py >+++ b/pym/portage/package/ebuild/doebuild.py >@@ -12,6 +12,7 @@ import io > from itertools import chain > import logging > import os as _os >+import platform > import pwd > import re > import signal >@@ -81,6 +82,15 @@ _unsandboxed_phases = frozenset([ > "prerm", "setup" > ]) > >+# phases in which networking access is allowed >+_networked_phases = frozenset([ >+ # for VCS fetching >+ "unpack", >+ # for IPC >+ "setup", "pretend", >+ "preinst", "postinst", "prerm", "postrm", >+]) >+ > _phase_func_map = { > "config": "pkg_config", > "setup": "pkg_setup", >@@ -110,6 +120,8 @@ def _doebuild_spawn(phase, settings, actionmap=None, **kwargs): > > if phase in _unsandboxed_phases: > kwargs['free'] = True >+ if phase in _networked_phases: >+ kwargs['networked'] = True > > if phase == 'depend': > kwargs['droppriv'] = 'userpriv' in settings.features >@@ -1387,7 +1399,7 @@ def _validate_deps(mysettings, myroot, mydo, mydbapi): > > # XXX This would be to replace getstatusoutput completely. > # XXX Issue: cannot block execution. Deadlock condition. >-def spawn(mystring, mysettings, debug=0, free=0, droppriv=0, sesandbox=0, fakeroot=0, **keywords): >+def spawn(mystring, mysettings, debug=0, free=0, droppriv=0, sesandbox=0, fakeroot=0, networked=0, **keywords): > """ > Spawn a subprocess with extra portage-specific options. > Optiosn include: >@@ -1417,6 +1429,8 @@ def spawn(mystring, mysettings, debug=0, free=0, droppriv=0, sesandbox=0, fakero > @type sesandbox: Boolean > @param fakeroot: Run this command with faked root privileges > @type fakeroot: Boolean >+ @param networked: Run this command with networking access enabled >+ @type networked: Boolean > @param keywords: Extra options encoded as a dict, to be passed to spawn > @type keywords: Dictionary > @rtype: Integer >@@ -1444,6 +1458,11 @@ def spawn(mystring, mysettings, debug=0, free=0, droppriv=0, sesandbox=0, fakero > break > > features = mysettings.features >+ >+ # Unshare network namespace to keep ebuilds sanitized >+ if not networked and uid == 0 and platform.system() == 'Linux': >+ keywords['unshare_net'] = True >+ > # TODO: Enable fakeroot to be used together with droppriv. The > # fake ownership/permissions will have to be converted to real > # permissions in the merge phase. >diff --git a/pym/portage/process.py b/pym/portage/process.py >index 5f6a172..512c324 100644 >--- a/pym/portage/process.py >+++ b/pym/portage/process.py >@@ -21,6 +21,7 @@ portage.proxy.lazyimport.lazyimport(globals(), > > from portage.const import BASH_BINARY, SANDBOX_BINARY, FAKEROOT_BINARY > from portage.exception import CommandNotFound >+from portage.util._ctypes import find_library, LoadLibrary, ctypes > > try: > import resource >@@ -180,7 +181,7 @@ def cleanup(): > > def spawn(mycommand, env={}, opt_name=None, fd_pipes=None, returnpid=False, > uid=None, gid=None, groups=None, umask=None, logfile=None, >- path_lookup=True, pre_exec=None, close_fds=True): >+ path_lookup=True, pre_exec=None, close_fds=True, unshare_net=False): > """ > Spawns a given command. > >@@ -213,7 +214,9 @@ def spawn(mycommand, env={}, opt_name=None, fd_pipes=None, returnpid=False, > @param close_fds: If True, then close all file descriptors except those > referenced by fd_pipes (default is True). > @type close_fds: Boolean >- >+ @param unshare_net: If True, networking will be unshared from the spawned process >+ @type unshare_net: Boolean >+ > logfile requires stdout and stderr to be assigned to this process (ie not pointed > somewhere else.) > >@@ -284,7 +287,8 @@ def spawn(mycommand, env={}, opt_name=None, fd_pipes=None, returnpid=False, > if pid == 0: > try: > _exec(binary, mycommand, opt_name, fd_pipes, >- env, gid, groups, uid, umask, pre_exec, close_fds) >+ env, gid, groups, uid, umask, pre_exec, close_fds, >+ unshare_net) > except SystemExit: > raise > except Exception as e: >@@ -354,7 +358,7 @@ def spawn(mycommand, env={}, opt_name=None, fd_pipes=None, returnpid=False, > return 0 > > def _exec(binary, mycommand, opt_name, fd_pipes, env, gid, groups, uid, umask, >- pre_exec, close_fds): >+ pre_exec, close_fds, unshare_net): > > """ > Execute a given binary with options >@@ -379,10 +383,12 @@ def _exec(binary, mycommand, opt_name, fd_pipes, env, gid, groups, uid, umask, > @type umask: Integer > @param pre_exec: A function to be called with no arguments just prior to the exec call. > @type pre_exec: callable >+ @param unshare_net: If True, networking will be unshared from the spawned process >+ @type unshare_net: Boolean > @rtype: None > @return: Never returns (calls os.execve) > """ >- >+ > # If the process we're creating hasn't been given a name > # assign it the name of the executable. > if not opt_name: >@@ -415,6 +421,22 @@ def _exec(binary, mycommand, opt_name, fd_pipes, env, gid, groups, uid, umask, > > _setup_pipes(fd_pipes, close_fds=close_fds) > >+ # Unshare network (while still uid==0) >+ if unshare_net: >+ filename = find_library("c") >+ if filename is not None: >+ libc = LoadLibrary(filename) >+ if libc is not None: >+ CLONE_NEWNET = 0x40000000 >+ try: >+ if libc.unshare(CLONE_NEWNET) != 0: >+ writemsg("Unable to unshare network: %s\n" % ( >+ errno.errorcode.get(ctypes.get_errno(), '?')), >+ noiselevel=-1) >+ except AttributeError: >+ # unshare() not supported by libc >+ pass >+ > # Set requested process permissions. > if gid: > # Cast proxies to int, in case it matters. >-- >1.8.3.2 >
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 481450
: 356282 |
356320
|
356322
|
356324