public inbox for gentoo-commits@lists.gentoo.org
 help / color / mirror / Atom feed
* [gentoo-commits] proj/portage:master commit in: man/, pym/portage/package/ebuild/, pym/portage/
@ 2011-04-05 22:23 Zac Medico
  0 siblings, 0 replies; 5+ messages in thread
From: Zac Medico @ 2011-04-05 22:23 UTC (permalink / raw
  To: gentoo-commits

commit:     1944622240d87dfa90d88ba19d68f023eed9949f
Author:     Zac Medico <zmedico <AT> gentoo <DOT> org>
AuthorDate: Tue Apr  5 22:23:28 2011 +0000
Commit:     Zac Medico <zmedico <AT> gentoo <DOT> org>
CommitDate: Tue Apr  5 22:23:28 2011 +0000
URL:        http://git.overlays.gentoo.org/gitweb/?p=proj/portage.git;a=commit;h=19446222

Add force-mirror FEATURE.

force-mirror: Only fetch files from configured mirrors, ignoring
SRC_URI, except when mirror is in the ebuild(5) RESTRICT variable.

BUG=chromium-os:13221
TEST=Test that ebuilds now fail with FEATURES=force-mirror if files are
not in the configured mirror.

Change-Id: I8484d5af8dff97b431398030b33c024ff1295ba0

Review URL: http://codereview.chromium.org/6677171

---
 man/make.conf.5                     |    4 ++++
 pym/portage/const.py                |    4 ++--
 pym/portage/package/ebuild/fetch.py |   10 +++++-----
 3 files changed, 11 insertions(+), 7 deletions(-)

diff --git a/man/make.conf.5 b/man/make.conf.5
index a86f257..cf8d217 100644
--- a/man/make.conf.5
+++ b/man/make.conf.5
@@ -304,6 +304,10 @@ enabled for more than a short period of time.
 Modifies .la files to not include other .la files and some other
 fixes (order of flags, duplicated entries, ...)
 .TP
+.B force\-mirror
+Only fetch files from configured mirrors, ignoring \fBSRC_URI\fR,
+except when \fImirror\fR is in the \fBebuild\fR(5) \fBRESTRICT\fR variable.
+.TP
 .B lmirror
 When \fImirror\fR is enabled in \fBFEATURES\fR, fetch files even
 when \fImirror\fR is also in the \fBebuild\fR(5) \fBRESTRICT\fR variable.

diff --git a/pym/portage/const.py b/pym/portage/const.py
index 89fdda1..b92149d 100644
--- a/pym/portage/const.py
+++ b/pym/portage/const.py
@@ -88,8 +88,8 @@ EBUILD_PHASES            = ("pretend", "setup", "unpack", "prepare", "configure"
 SUPPORTED_FEATURES       = frozenset([
                            "assume-digests", "binpkg-logs", "buildpkg", "buildsyspkg", "candy",
                            "ccache", "chflags", "collision-protect", "compress-build-logs",
-                           "digest", "distcc", "distlocks",
-                           "fakeroot", "fail-clean", "fixpackages", "getbinpkg",
+                           "digest", "distcc", "distlocks", "fakeroot",
+                           "fail-clean", "fixpackages", "force-mirror", "getbinpkg",
                            "installsources", "keeptemp", "keepwork", "fixlafiles", "lmirror",
                            "metadata-transfer", "mirror", "multilib-strict", "news",
                            "noauto", "noclean", "nodoc", "noinfo", "noman", "nostrip",

diff --git a/pym/portage/package/ebuild/fetch.py b/pym/portage/package/ebuild/fetch.py
index c33375c..6e4c728 100644
--- a/pym/portage/package/ebuild/fetch.py
+++ b/pym/portage/package/ebuild/fetch.py
@@ -245,8 +245,8 @@ def fetch(myuris, mysettings, listonly=0, fetchonly=0,
 	userpriv = secpass >= 2 and "userpriv" in features
 
 	# 'nomirror' is bad/negative logic. You Restrict mirroring, not no-mirroring.
-	if "mirror" in restrict or \
-	   "nomirror" in restrict:
+	restrict_mirror = "mirror" in restrict or "nomirror" in restrict
+	if restrict_mirror:
 		if ("mirror" in features) and ("lmirror" not in features):
 			# lmirror should allow you to bypass mirror restrictions.
 			# XXX: This is not a good thing, and is temporary at best.
@@ -344,8 +344,7 @@ def fetch(myuris, mysettings, listonly=0, fetchonly=0,
 	if "local" in custommirrors:
 		mymirrors += custommirrors["local"]
 
-	if "nomirror" in restrict or \
-	   "mirror" in restrict:
+	if restrict_mirror:
 		# We don't add any mirrors.
 		pass
 	else:
@@ -374,6 +373,7 @@ def fetch(myuris, mysettings, listonly=0, fetchonly=0,
 			del mymirrors[x]
 
 	restrict_fetch = "fetch" in restrict
+	force_mirror = "force-mirror" in features and not restrict_mirror
 	custom_local_mirrors = custommirrors.get("local", [])
 	if restrict_fetch:
 		# With fetch restriction, a normal uri may only be fetched from
@@ -430,7 +430,7 @@ def fetch(myuris, mysettings, listonly=0, fetchonly=0,
 				writemsg(_("Invalid mirror definition in SRC_URI:\n"), noiselevel=-1)
 				writemsg("  %s\n" % (myuri), noiselevel=-1)
 		else:
-			if restrict_fetch:
+			if restrict_fetch or force_mirror:
 				# Only fetch from specific mirrors is allowed.
 				continue
 			if "primaryuri" in restrict:



^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [gentoo-commits] proj/portage:master commit in: man/, pym/portage/package/ebuild/, pym/portage/
@ 2011-04-07 23:50 Zac Medico
  0 siblings, 0 replies; 5+ messages in thread
From: Zac Medico @ 2011-04-07 23:50 UTC (permalink / raw
  To: gentoo-commits

commit:     b773f82f3ab84270d6541b84298013b6221ebcac
Author:     David James <davidjames <AT> google <DOT> com>
AuthorDate: Thu Apr  7 23:49:58 2011 +0000
Commit:     Zac Medico <zmedico <AT> gentoo <DOT> org>
CommitDate: Thu Apr  7 23:49:58 2011 +0000
URL:        http://git.overlays.gentoo.org/gitweb/?p=proj/portage.git;a=commit;h=b773f82f

Add force-mirror FEATURE.

force-mirror: Only fetch files from configured mirrors, ignoring
SRC_URI, except when mirror is in the ebuild(5) RESTRICT variable.

BUG=chromium-os:13221
TEST=Test that ebuilds now fail with FEATURES=force-mirror if files are
not in the configured mirror.

Change-Id: I8484d5af8dff97b431398030b33c024ff1295ba0

Review URL: http://codereview.chromium.org/6677171

---
 man/make.conf.5                     |    4 ++++
 pym/portage/const.py                |    4 ++--
 pym/portage/package/ebuild/fetch.py |   10 +++++-----
 3 files changed, 11 insertions(+), 7 deletions(-)

diff --git a/man/make.conf.5 b/man/make.conf.5
index a86f257..cf8d217 100644
--- a/man/make.conf.5
+++ b/man/make.conf.5
@@ -304,6 +304,10 @@ enabled for more than a short period of time.
 Modifies .la files to not include other .la files and some other
 fixes (order of flags, duplicated entries, ...)
 .TP
+.B force\-mirror
+Only fetch files from configured mirrors, ignoring \fBSRC_URI\fR,
+except when \fImirror\fR is in the \fBebuild\fR(5) \fBRESTRICT\fR variable.
+.TP
 .B lmirror
 When \fImirror\fR is enabled in \fBFEATURES\fR, fetch files even
 when \fImirror\fR is also in the \fBebuild\fR(5) \fBRESTRICT\fR variable.

diff --git a/pym/portage/const.py b/pym/portage/const.py
index 89fdda1..b92149d 100644
--- a/pym/portage/const.py
+++ b/pym/portage/const.py
@@ -88,8 +88,8 @@ EBUILD_PHASES            = ("pretend", "setup", "unpack", "prepare", "configure"
 SUPPORTED_FEATURES       = frozenset([
                            "assume-digests", "binpkg-logs", "buildpkg", "buildsyspkg", "candy",
                            "ccache", "chflags", "collision-protect", "compress-build-logs",
-                           "digest", "distcc", "distlocks",
-                           "fakeroot", "fail-clean", "fixpackages", "getbinpkg",
+                           "digest", "distcc", "distlocks", "fakeroot",
+                           "fail-clean", "fixpackages", "force-mirror", "getbinpkg",
                            "installsources", "keeptemp", "keepwork", "fixlafiles", "lmirror",
                            "metadata-transfer", "mirror", "multilib-strict", "news",
                            "noauto", "noclean", "nodoc", "noinfo", "noman", "nostrip",

diff --git a/pym/portage/package/ebuild/fetch.py b/pym/portage/package/ebuild/fetch.py
index c33375c..6e4c728 100644
--- a/pym/portage/package/ebuild/fetch.py
+++ b/pym/portage/package/ebuild/fetch.py
@@ -245,8 +245,8 @@ def fetch(myuris, mysettings, listonly=0, fetchonly=0,
 	userpriv = secpass >= 2 and "userpriv" in features
 
 	# 'nomirror' is bad/negative logic. You Restrict mirroring, not no-mirroring.
-	if "mirror" in restrict or \
-	   "nomirror" in restrict:
+	restrict_mirror = "mirror" in restrict or "nomirror" in restrict
+	if restrict_mirror:
 		if ("mirror" in features) and ("lmirror" not in features):
 			# lmirror should allow you to bypass mirror restrictions.
 			# XXX: This is not a good thing, and is temporary at best.
@@ -344,8 +344,7 @@ def fetch(myuris, mysettings, listonly=0, fetchonly=0,
 	if "local" in custommirrors:
 		mymirrors += custommirrors["local"]
 
-	if "nomirror" in restrict or \
-	   "mirror" in restrict:
+	if restrict_mirror:
 		# We don't add any mirrors.
 		pass
 	else:
@@ -374,6 +373,7 @@ def fetch(myuris, mysettings, listonly=0, fetchonly=0,
 			del mymirrors[x]
 
 	restrict_fetch = "fetch" in restrict
+	force_mirror = "force-mirror" in features and not restrict_mirror
 	custom_local_mirrors = custommirrors.get("local", [])
 	if restrict_fetch:
 		# With fetch restriction, a normal uri may only be fetched from
@@ -430,7 +430,7 @@ def fetch(myuris, mysettings, listonly=0, fetchonly=0,
 				writemsg(_("Invalid mirror definition in SRC_URI:\n"), noiselevel=-1)
 				writemsg("  %s\n" % (myuri), noiselevel=-1)
 		else:
-			if restrict_fetch:
+			if restrict_fetch or force_mirror:
 				# Only fetch from specific mirrors is allowed.
 				continue
 			if "primaryuri" in restrict:



^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [gentoo-commits] proj/portage:master commit in: man/, pym/portage/package/ebuild/, pym/portage/
@ 2013-08-17 20:45 Zac Medico
  0 siblings, 0 replies; 5+ messages in thread
From: Zac Medico @ 2013-08-17 20:45 UTC (permalink / raw
  To: gentoo-commits

commit:     39db5201e087156ed46f6cac4dc9a69a2f3cc81c
Author:     Michał Górny <mgorny <AT> gentoo <DOT> org>
AuthorDate: Sat Aug 17 10:28:05 2013 +0000
Commit:     Zac Medico <zmedico <AT> gentoo <DOT> org>
CommitDate: Sat Aug 17 20:38:53 2013 +0000
URL:        http://git.overlays.gentoo.org/gitweb/?p=proj/portage.git;a=commit;h=39db5201

Add FEATURES=network-sandbox support, bug #481450

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.

---
 man/make.conf.5                        |  4 +++
 pym/portage/const.py                   |  3 +-
 pym/portage/package/ebuild/doebuild.py | 21 ++++++++++++-
 pym/portage/process.py                 | 54 ++++++++++++++++++++++++++++++----
 4 files changed, 75 insertions(+), 7 deletions(-)

diff --git a/man/make.conf.5 b/man/make.conf.5
index 63e2097..461172c 100644
--- a/man/make.conf.5
+++ b/man/make.conf.5
@@ -415,6 +415,10 @@ isn't a symlink to /usr/lib64. To find the bad packages, we have a
 portage feature called \fImultilib\-strict\fR. It will prevent emerge
 from putting 64bit libraries into anything other than (/usr)/lib64.
 .TP
+.B network\-sandbox
+Isolate the ebuild phase functions from host network interfaces.
+Supported only on Linux. Requires network namespace support in kernel.
+.TP
 .B news
 Enable GLEP 42 news support. See
 \fIhttp://www.gentoo.org/proj/en/glep/glep-0042.html\fR.

diff --git a/pym/portage/const.py b/pym/portage/const.py
index bd55cb1..cde0079 100644
--- a/pym/portage/const.py
+++ b/pym/portage/const.py
@@ -104,7 +104,8 @@ SUPPORTED_FEATURES       = frozenset([
                            "fail-clean", "force-mirror", "force-prefix", "getbinpkg",
                            "installsources", "keeptemp", "keepwork", "fixlafiles", "lmirror",
                            "merge-sync",
-                           "metadata-transfer", "mirror", "multilib-strict", "news",
+                           "metadata-transfer", "mirror", "multilib-strict",
+                           "network-sandbox", "news",
                            "noauto", "noclean", "nodoc", "noinfo", "noman",
                            "nostrip", "notitles", "parallel-fetch", "parallel-install",
                            "prelink-checksums", "preserve-libs",

diff --git a/pym/portage/package/ebuild/doebuild.py b/pym/portage/package/ebuild/doebuild.py
index 1cf5dc6..a35e717 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' and "network-sandbox" in features:
+		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..a7464c7 100644
--- a/pym/portage/process.py
+++ b/pym/portage/process.py
@@ -5,8 +5,11 @@
 
 import atexit
 import errno
+import fcntl
 import platform
 import signal
+import socket
+import struct
 import sys
 import traceback
 import os as _os
@@ -21,6 +24,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 +184,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 +217,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.)
 	
@@ -276,6 +282,12 @@ def spawn(mycommand, env={}, opt_name=None, fd_pipes=None, returnpid=False,
 		fd_pipes[1] = pw
 		fd_pipes[2] = pw
 
+	# This caches the libc library lookup in the current
+	# process, so that it's only done once rather than
+	# for each child process.
+	if unshare_net:
+		find_library("c")
+
 	parent_pid = os.getpid()
 	pid = None
 	try:
@@ -284,7 +296,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 +367,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 +392,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 +430,35 @@ 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)
+					else:
+						# 'up' the loopback
+						IFF_UP = 0x1
+						ifreq = struct.pack('16sh', b'lo', IFF_UP)
+						SIOCSIFFLAGS = 0x8914
+
+						sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, 0)
+						try:
+							fcntl.ioctl(sock, SIOCSIFFLAGS, ifreq)
+						except IOError as e:
+							writemsg("Unable to enable loopback interface: %s\n" % (
+								errno.errorcode.get(e.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.


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [gentoo-commits] proj/portage:master commit in: man/, pym/portage/package/ebuild/, pym/portage/
@ 2013-08-18 23:33 Zac Medico
  0 siblings, 0 replies; 5+ messages in thread
From: Zac Medico @ 2013-08-18 23:33 UTC (permalink / raw
  To: gentoo-commits

commit:     f0711200ce35920552962190c9a1f7b98d107070
Author:     Michał Górny <mgorny <AT> gentoo <DOT> org>
AuthorDate: Sun Aug 18 23:22:59 2013 +0000
Commit:     Zac Medico <zmedico <AT> gentoo <DOT> org>
CommitDate: Sun Aug 18 23:31:01 2013 +0000
URL:        http://git.overlays.gentoo.org/gitweb/?p=proj/portage.git;a=commit;h=f0711200

Add FEATURES=ipc-sandbox to isolate IPC from host.

This way, only privileged phases (pkg_*) can use *nix IPC to communicate
with host applications. src_* use private IPC namespace.

---
 man/make.conf.5                        |  4 +++
 pym/portage/const.py                   |  3 +-
 pym/portage/package/ebuild/doebuild.py | 27 +++++++++++-----
 pym/portage/process.py                 | 56 +++++++++++++++++++++-------------
 4 files changed, 60 insertions(+), 30 deletions(-)

diff --git a/man/make.conf.5 b/man/make.conf.5
index 461172c..91817ae 100644
--- a/man/make.conf.5
+++ b/man/make.conf.5
@@ -385,6 +385,10 @@ would otherwise be useless with prefix configurations. This brings
 compatibility with the prefix branch of portage, which also supports EPREFIX
 for all EAPIs (for obvious reasons).
 .TP
+.B ipc\-sandbox
+Isolate the ebuild phase functions from host IPC namespace. Supported
+only on Linux. Requires network namespace support in kernel.
+.TP
 .B lmirror
 When \fImirror\fR is enabled in \fBFEATURES\fR, fetch files even
 when \fImirror\fR is also in the \fBebuild\fR(5) \fBRESTRICT\fR variable.

diff --git a/pym/portage/const.py b/pym/portage/const.py
index cde0079..88c199b 100644
--- a/pym/portage/const.py
+++ b/pym/portage/const.py
@@ -102,7 +102,8 @@ SUPPORTED_FEATURES       = frozenset([
                            "digest", "distcc", "distcc-pump", "distlocks",
                            "downgrade-backup", "ebuild-locks", "fakeroot",
                            "fail-clean", "force-mirror", "force-prefix", "getbinpkg",
-                           "installsources", "keeptemp", "keepwork", "fixlafiles", "lmirror",
+                           "installsources", "ipc-sandbox",
+                           "keeptemp", "keepwork", "fixlafiles", "lmirror",
                            "merge-sync",
                            "metadata-transfer", "mirror", "multilib-strict",
                            "network-sandbox", "news",

diff --git a/pym/portage/package/ebuild/doebuild.py b/pym/portage/package/ebuild/doebuild.py
index a35e717..2d26d2c 100644
--- a/pym/portage/package/ebuild/doebuild.py
+++ b/pym/portage/package/ebuild/doebuild.py
@@ -82,14 +82,18 @@ _unsandboxed_phases = frozenset([
 	"prerm", "setup"
 ])
 
+# phases in which IPC with host is allowed
+_ipc_phases = frozenset([
+	"setup", "pretend",
+	"preinst", "postinst", "prerm", "postrm",
+])
+
 # phases in which networking access is allowed
 _networked_phases = frozenset([
 	# for VCS fetching
 	"unpack",
-	# for IPC
-	"setup", "pretend",
-	"preinst", "postinst", "prerm", "postrm",
-])
+	# + for network-bound IPC
+] + list(_ipc_phases))
 
 _phase_func_map = {
 	"config": "pkg_config",
@@ -120,6 +124,8 @@ def _doebuild_spawn(phase, settings, actionmap=None, **kwargs):
 
 	if phase in _unsandboxed_phases:
 		kwargs['free'] = True
+	if phase in _ipc_phases:
+		kwargs['ipc'] = True
 	if phase in _networked_phases:
 		kwargs['networked'] = True
 
@@ -1399,7 +1405,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, networked=0, **keywords):
+def spawn(mystring, mysettings, debug=0, free=0, droppriv=0, sesandbox=0, fakeroot=0, networked=0, ipc=0, **keywords):
 	"""
 	Spawn a subprocess with extra portage-specific options.
 	Optiosn include:
@@ -1431,6 +1437,8 @@ def spawn(mystring, mysettings, debug=0, free=0, droppriv=0, sesandbox=0, fakero
 	@type fakeroot: Boolean
 	@param networked: Run this command with networking access enabled
 	@type networked: Boolean
+	@param ipc: Run this command with host IPC access enabled
+	@type ipc: Boolean
 	@param keywords: Extra options encoded as a dict, to be passed to spawn
 	@type keywords: Dictionary
 	@rtype: Integer
@@ -1459,9 +1467,12 @@ def spawn(mystring, mysettings, debug=0, free=0, droppriv=0, sesandbox=0, fakero
 
 	features = mysettings.features
 
-	# Unshare network namespace to keep ebuilds sanitized
-	if not networked and uid == 0 and platform.system() == 'Linux' and "network-sandbox" in features:
-		keywords['unshare_net'] = True
+	# Use Linux namespaces if available
+	if uid == 0 and platform.system() == 'Linux':
+		if not networked and "network-sandbox" in features:
+			keywords['unshare_net'] = True
+		if not ipc and "ipc-sandbox" in features:
+			keywords['unshare_ipc'] = True
 
 	# TODO: Enable fakeroot to be used together with droppriv.  The
 	# fake ownership/permissions will have to be converted to real

diff --git a/pym/portage/process.py b/pym/portage/process.py
index 6a60dec..22c6a88 100644
--- a/pym/portage/process.py
+++ b/pym/portage/process.py
@@ -184,7 +184,8 @@ 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, unshare_net=False):
+          path_lookup=True, pre_exec=None, close_fds=True, unshare_net=False,
+          unshare_ipc=False):
 	"""
 	Spawns a given command.
 	
@@ -219,6 +220,8 @@ def spawn(mycommand, env={}, opt_name=None, fd_pipes=None, returnpid=False,
 	@type close_fds: Boolean
 	@param unshare_net: If True, networking will be unshared from the spawned process
 	@type unshare_net: Boolean
+	@param unshare_ipc: If True, IPC will be unshared from the spawned process
+	@type unshare_ipc: Boolean
 
 	logfile requires stdout and stderr to be assigned to this process (ie not pointed
 	   somewhere else.)
@@ -285,7 +288,7 @@ def spawn(mycommand, env={}, opt_name=None, fd_pipes=None, returnpid=False,
 	# This caches the libc library lookup in the current
 	# process, so that it's only done once rather than
 	# for each child process.
-	if unshare_net:
+	if unshare_net or unshare_ipc:
 		find_library("c")
 
 	parent_pid = os.getpid()
@@ -297,7 +300,7 @@ def spawn(mycommand, env={}, opt_name=None, fd_pipes=None, returnpid=False,
 			try:
 				_exec(binary, mycommand, opt_name, fd_pipes,
 					env, gid, groups, uid, umask, pre_exec, close_fds,
-					unshare_net)
+					unshare_net, unshare_ipc)
 			except SystemExit:
 				raise
 			except Exception as e:
@@ -367,7 +370,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, unshare_net):
+	pre_exec, close_fds, unshare_net, unshare_ipc):
 
 	"""
 	Execute a given binary with options
@@ -394,6 +397,8 @@ def _exec(binary, mycommand, opt_name, fd_pipes, env, gid, groups, uid, umask,
 	@type pre_exec: callable
 	@param unshare_net: If True, networking will be unshared from the spawned process
 	@type unshare_net: Boolean
+	@param unshare_ipc: If True, IPC will be unshared from the spawned process
+	@type unshare_ipc: Boolean
 	@rtype: None
 	@return: Never returns (calls os.execve)
 	"""
@@ -430,32 +435,41 @@ 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:
+	# Unshare (while still uid==0)
+	if unshare_net or unshare_ipc:
 		filename = find_library("c")
 		if filename is not None:
 			libc = LoadLibrary(filename)
 			if libc is not None:
+				CLONE_NEWIPC = 0x08000000
 				CLONE_NEWNET = 0x40000000
+
+				flags = 0
+				if unshare_net:
+					flags |= CLONE_NEWNET
+				if unshare_ipc:
+					flags |= CLONE_NEWIPC
+
 				try:
-					if libc.unshare(CLONE_NEWNET) != 0:
-						writemsg("Unable to unshare network: %s\n" % (
+					if libc.unshare(flags) != 0:
+						writemsg("Unable to unshare: %s\n" % (
 							errno.errorcode.get(ctypes.get_errno(), '?')),
 							noiselevel=-1)
 					else:
-						# 'up' the loopback
-						IFF_UP = 0x1
-						ifreq = struct.pack('16sh', b'lo', IFF_UP)
-						SIOCSIFFLAGS = 0x8914
-
-						sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, 0)
-						try:
-							fcntl.ioctl(sock, SIOCSIFFLAGS, ifreq)
-						except IOError as e:
-							writemsg("Unable to enable loopback interface: %s\n" % (
-								errno.errorcode.get(e.errno, '?')),
-								noiselevel=-1)
-						sock.close()
+						if unshare_net:
+							# 'up' the loopback
+							IFF_UP = 0x1
+							ifreq = struct.pack('16sh', b'lo', IFF_UP)
+							SIOCSIFFLAGS = 0x8914
+
+							sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, 0)
+							try:
+								fcntl.ioctl(sock, SIOCSIFFLAGS, ifreq)
+							except IOError as e:
+								writemsg("Unable to enable loopback interface: %s\n" % (
+									errno.errorcode.get(e.errno, '?')),
+									noiselevel=-1)
+							sock.close()
 				except AttributeError:
 					# unshare() not supported by libc
 					pass


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [gentoo-commits] proj/portage:master commit in: man/, pym/portage/package/ebuild/, pym/portage/
@ 2015-05-06 17:26 Brian Dolbec
  0 siblings, 0 replies; 5+ messages in thread
From: Brian Dolbec @ 2015-05-06 17:26 UTC (permalink / raw
  To: gentoo-commits

commit:     1f94508e9adeffd7170cb23852ae40fc1f8b6c98
Author:     Nikoli <nikoli <AT> gmx <DOT> us>
AuthorDate: Wed May  6 14:02:28 2015 +0000
Commit:     Brian Dolbec <dolsen <AT> gentoo <DOT> org>
CommitDate: Wed May  6 17:26:13 2015 +0000
URL:        https://gitweb.gentoo.org/proj/portage.git/commit/?id=1f94508e

Disable SOCKSv5-over-UNIX-socket proxy by default, bug #548710

 man/make.conf.5                        | 4 ++++
 pym/portage/const.py                   | 1 +
 pym/portage/package/ebuild/doebuild.py | 3 ++-
 3 files changed, 7 insertions(+), 1 deletion(-)

diff --git a/man/make.conf.5 b/man/make.conf.5
index 1b71b97..298eb80 100644
--- a/man/make.conf.5
+++ b/man/make.conf.5
@@ -463,6 +463,10 @@ from putting 64bit libraries into anything other than (/usr)/lib64.
 .B network\-sandbox
 Isolate the ebuild phase functions from host network interfaces.
 Supported only on Linux. Requires network namespace support in kernel.
+.TP
+.B network\-sandbox\-proxy
+Enable escaping network-sandbox through SOCKSv5 proxy. Enabling distcc
+feature also enables the proxy.
 
 If asyncio Python module is available (requires Python 3.3, built-in
 since Python 3.4) Portage will additionally spawn an isolated SOCKSv5

diff --git a/pym/portage/const.py b/pym/portage/const.py
index 6c1201d..617cd96 100644
--- a/pym/portage/const.py
+++ b/pym/portage/const.py
@@ -158,6 +158,7 @@ SUPPORTED_FEATURES       = frozenset([
 	"mirror",
 	"multilib-strict",
 	"network-sandbox",
+	"network-sandbox-proxy",
 	"news",
 	"noauto",
 	"noclean",

diff --git a/pym/portage/package/ebuild/doebuild.py b/pym/portage/package/ebuild/doebuild.py
index 4d926c7..5e4d7b1 100644
--- a/pym/portage/package/ebuild/doebuild.py
+++ b/pym/portage/package/ebuild/doebuild.py
@@ -1505,7 +1505,8 @@ def spawn(mystring, mysettings, debug=False, free=False, droppriv=False,
 		keywords['unshare_net'] = not networked
 		keywords['unshare_ipc'] = not ipc
 
-		if not networked and mysettings.get("EBUILD_PHASE") != "nofetch":
+		if not networked and mysettings.get("EBUILD_PHASE") != "nofetch" and \
+			("network-sandbox-proxy" in features or "distcc" in features):
 			# Provide a SOCKS5-over-UNIX-socket proxy to escape sandbox
 			# Don't do this for pkg_nofetch, since the spawn_nofetch
 			# function creates a private PORTAGE_TMPDIR.


^ permalink raw reply related	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2015-05-06 17:26 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-08-17 20:45 [gentoo-commits] proj/portage:master commit in: man/, pym/portage/package/ebuild/, pym/portage/ Zac Medico
  -- strict thread matches above, loose matches on Subject: below --
2015-05-06 17:26 Brian Dolbec
2013-08-18 23:33 Zac Medico
2011-04-07 23:50 Zac Medico
2011-04-05 22:23 Zac Medico

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox