Gentoo Archives: gentoo-portage-dev

From: "Michał Górny" <mgorny@g.o>
To: gentoo-portage-dev@l.g.o
Cc: "Michał Górny" <mgorny@g.o>
Subject: [gentoo-portage-dev] [PATCH] portage.package.ebuild: Use a fake FILESDIR to catch invalid accesses
Date: Thu, 16 Mar 2017 19:56:53
Message-Id: 20170316195642.32526-1-mgorny@gentoo.org
1 Use a model of fake FILESDIR path to ensure that invalid accesses to
2 FILESDIR will result in failures rather than being silently allowed by
3 Portage. This mostly involves accesses in the global scope and pkg_*
4 phases, although the current model does not cover the latter completely
5 (i.e. does not guarantee that the directory is removed post src_*).
6
7 This model aims to follow PMS wording quite precisely. The value of
8 FILESDIR is meant to be stable throughout the build process, and it is
9 reliably set to a temporary directory path. However, since the path is
10 not guaranteed to be present outside src_*, the directory symlink is not
11 actually created before src_* phases.
12
13 == Review notes ==
14 This is the final version that actually works ;-). I did a full egencache
15 run with it and the only packages that fail are eblit users (all of them
16 have bugs open with deadline 1 week from now). There might be a few more
17 silly failures, so I'll test it for a while, and ask Toralf to possibly
18 do some tinderboxing.
19
20 ---
21 man/ebuild.5 | 6 +++---
22 pym/_emerge/EbuildPhase.py | 4 +++-
23 pym/portage/package/ebuild/config.py | 3 ---
24 pym/portage/package/ebuild/doebuild.py | 6 +++++-
25 pym/portage/package/ebuild/prepare_build_dirs.py | 13 +++++++++++++
26 5 files changed, 24 insertions(+), 8 deletions(-)
27
28 diff --git a/man/ebuild.5 b/man/ebuild.5
29 index 72b8b6905..e4c866cd2 100644
30 --- a/man/ebuild.5
31 +++ b/man/ebuild.5
32 @@ -411,9 +411,9 @@ not be defined. It is autogenerated from the \fBSRC_URI\fR variable.
33 .B WORKDIR\fR = \fI"${PORTAGE_TMPDIR}/portage/${CATEGORY}/${PF}/work"
34 Contains the path to the package build root. Do not modify this variable.
35 .TP
36 -.B FILESDIR\fR = \fI"${repository_location}/${CATEGORY}/${PN}/files"
37 -Contains the path to the 'files' subdirectory in the package specific
38 -location in given repository. Do not modify this variable.
39 +.B FILESDIR\fR = \fI"${PORTAGE_TMPDIR}/${CATEGORY}/${PF}/files"
40 +Contains the path to the directory in which package-specific auxiliary
41 +files are located. Do not modify this variable.
42 .TP
43 .B EBUILD_PHASE
44 Contains the abreviated name of the phase function that is
45 diff --git a/pym/_emerge/EbuildPhase.py b/pym/_emerge/EbuildPhase.py
46 index fc185fcfd..504c812ea 100644
47 --- a/pym/_emerge/EbuildPhase.py
48 +++ b/pym/_emerge/EbuildPhase.py
49 @@ -11,7 +11,8 @@ from _emerge.BinpkgEnvExtractor import BinpkgEnvExtractor
50 from _emerge.MiscFunctionsProcess import MiscFunctionsProcess
51 from _emerge.EbuildProcess import EbuildProcess
52 from _emerge.CompositeTask import CompositeTask
53 -from portage.package.ebuild.prepare_build_dirs import _prepare_workdir
54 +from portage.package.ebuild.prepare_build_dirs import (_prepare_workdir,
55 + _prepare_fake_filesdir)
56 from portage.util import writemsg
57
58 try:
59 @@ -229,6 +230,7 @@ class EbuildPhase(CompositeTask):
60 # ownership since tar can change that too.
61 os.utime(settings["WORKDIR"], None)
62 _prepare_workdir(settings)
63 + _prepare_fake_filesdir(settings)
64 elif self.phase == "install":
65 out = io.StringIO()
66 _post_src_install_write_metadata(settings)
67 diff --git a/pym/portage/package/ebuild/config.py b/pym/portage/package/ebuild/config.py
68 index ef29afeab..f8043dbf5 100644
69 --- a/pym/portage/package/ebuild/config.py
70 +++ b/pym/portage/package/ebuild/config.py
71 @@ -2784,9 +2784,6 @@ class config(object):
72 mydict.pop("EPREFIX", None)
73 mydict.pop("EROOT", None)
74
75 - if phase == 'depend':
76 - mydict.pop('FILESDIR', None)
77 -
78 if phase not in ("pretend", "setup", "preinst", "postinst") or \
79 not eapi_exports_replace_vars(eapi):
80 mydict.pop("REPLACING_VERSIONS", None)
81 diff --git a/pym/portage/package/ebuild/doebuild.py b/pym/portage/package/ebuild/doebuild.py
82 index 4baae17b1..2f80a28ee 100644
83 --- a/pym/portage/package/ebuild/doebuild.py
84 +++ b/pym/portage/package/ebuild/doebuild.py
85 @@ -31,6 +31,7 @@ portage.proxy.lazyimport.lazyimport(globals(),
86 'portage.package.ebuild.digestcheck:digestcheck',
87 'portage.package.ebuild.digestgen:digestgen',
88 'portage.package.ebuild.fetch:fetch',
89 + 'portage.package.ebuild.prepare_build_dirs:_prepare_fake_filesdir',
90 'portage.package.ebuild._ipc.QueryCommand:QueryCommand',
91 'portage.dep._slot_operator:evaluate_slot_operator_equal_deps',
92 'portage.package.ebuild._spawn_nofetch:spawn_nofetch',
93 @@ -164,6 +165,9 @@ def _doebuild_spawn(phase, settings, actionmap=None, **kwargs):
94 os.path.basename(EBUILD_SH_BINARY))),
95 ebuild_sh_arg)
96
97 + if phase == 'unpack':
98 + _prepare_fake_filesdir(settings)
99 +
100 settings['EBUILD_PHASE'] = phase
101 try:
102 return spawn(cmd, settings, **kwargs)
103 @@ -337,7 +341,6 @@ def doebuild_environment(myebuild, mydo, myroot=None, settings=None,
104 mysettings["EBUILD"] = ebuild_path
105 mysettings["O"] = pkg_dir
106 mysettings.configdict["pkg"]["CATEGORY"] = cat
107 - mysettings["FILESDIR"] = pkg_dir+"/files"
108 mysettings["PF"] = mypv
109
110 if hasattr(mydbapi, 'repositories'):
111 @@ -390,6 +393,7 @@ def doebuild_environment(myebuild, mydo, myroot=None, settings=None,
112 mysettings["WORKDIR"] = os.path.join(mysettings["PORTAGE_BUILDDIR"], "work")
113 mysettings["D"] = os.path.join(mysettings["PORTAGE_BUILDDIR"], "image") + os.sep
114 mysettings["T"] = os.path.join(mysettings["PORTAGE_BUILDDIR"], "temp")
115 + mysettings["FILESDIR"] = os.path.join(settings["PORTAGE_BUILDDIR"], "files")
116
117 # Prefix forward compatability
118 eprefix_lstrip = mysettings["EPREFIX"].lstrip(os.sep)
119 diff --git a/pym/portage/package/ebuild/prepare_build_dirs.py b/pym/portage/package/ebuild/prepare_build_dirs.py
120 index 7e5249b66..e3ae318bd 100644
121 --- a/pym/portage/package/ebuild/prepare_build_dirs.py
122 +++ b/pym/portage/package/ebuild/prepare_build_dirs.py
123 @@ -396,3 +396,16 @@ def _ensure_log_subdirs(logdir, subdir):
124 while subdir_split:
125 current = os.path.join(current, subdir_split.pop())
126 ensure_dirs(current, uid=uid, gid=gid, mode=grp_mode, mask=0)
127 +
128 +def _prepare_fake_filesdir(settings):
129 + real_filesdir = settings["O"]+"/files"
130 + symlink_path = settings["FILESDIR"]
131 +
132 + try:
133 + link_target = os.readlink(symlink_path)
134 + except OSError:
135 + os.symlink(real_filesdir, symlink_path)
136 + else:
137 + if link_target != real_filesdir:
138 + os.unlink(symlink_path)
139 + os.symlink(real_filesdir, symlink_path)
140 --
141 2.12.0

Replies