summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJussi Pakkanen <jpakkane@gmail.com>2017-09-29 23:25:35 +0300
committerJussi Pakkanen <jpakkane@gmail.com>2017-10-07 15:53:50 +0300
commit5c0fb752eab518121c520df4c4c1ff858d5c6899 (patch)
tree3f66df193189a68b1eefb4671f7b344adc293817
parentfd339759f20192ff9c464c112b27e402c7e42cbb (diff)
downloadmeson-subgrab.tar.gz
Prevent projects from directly grabbing files from other subprojects.subgrab
-rw-r--r--mesonbuild/interpreter.py35
-rw-r--r--test cases/failing/63 subproj filegrab/meson.build3
-rw-r--r--test cases/failing/63 subproj filegrab/prog.c1
-rw-r--r--test cases/failing/63 subproj filegrab/subprojects/a/meson.build3
4 files changed, 42 insertions, 0 deletions
diff --git a/mesonbuild/interpreter.py b/mesonbuild/interpreter.py
index 012370de2..4785115db 100644
--- a/mesonbuild/interpreter.py
+++ b/mesonbuild/interpreter.py
@@ -2784,6 +2784,40 @@ different subdirectory.
super().run()
mlog.log('Build targets in project:', mlog.bold(str(len(self.build.targets))))
+
+ # Check that the indicated file is within the same subproject
+ # as we currently are. This is to stop people doing
+ # nasty things like:
+ #
+ # f = files('../../master_src/file.c')
+ #
+ # Note that this is validated only when the file
+ # object is generated. The result can be used in a different
+ # subproject than it is defined in (due to e.g. a
+ # declare_dependency).
+ def validate_within_subproject(self, subdir, fname):
+ norm = os.path.normpath(os.path.join(subdir, fname))
+ if os.path.isabs(norm):
+ if not norm.startswith(self.environment.source_dir):
+ # Grabbing files outside the source tree is ok.
+ # This is for vendor stuff like:
+ #
+ # /opt/vendorsdk/src/file_with_license_restrictions.c
+ return
+ norm = os.path.relpath(norm, self.environment.source_dir)
+ assert(not os.path.isabs(norm))
+ segments = norm.split(os.path.sep)
+ num_sps = segments.count(self.subproject_dir)
+ if num_sps == 0:
+ if self.subproject == '':
+ return
+ raise InterpreterException('Sandbox violation: Tried to grab file %s from a different subproject.' % segments[-1])
+ if num_sps > 1:
+ raise InterpreterException('Sandbox violation: Tried to grab file %s from a nested subproject.' % segments[-1])
+ sproj_name = segments[segments.index(self.subproject_dir) + 1]
+ if sproj_name != self.subproject:
+ raise InterpreterException('Sandbox violation: Tried to grab file %s from a different subproject.' % segments[-1])
+
def source_strings_to_files(self, sources):
results = []
for s in sources:
@@ -2791,6 +2825,7 @@ different subdirectory.
CustomTargetHolder, CustomTargetIndexHolder)):
pass
elif isinstance(s, str):
+ self.validate_within_subproject(self.subdir, s)
s = mesonlib.File.from_source_file(self.environment.source_dir, self.subdir, s)
else:
raise InterpreterException("Source item is not string or File-type object.")
diff --git a/test cases/failing/63 subproj filegrab/meson.build b/test cases/failing/63 subproj filegrab/meson.build
new file mode 100644
index 000000000..6982c7837
--- /dev/null
+++ b/test cases/failing/63 subproj filegrab/meson.build
@@ -0,0 +1,3 @@
+project('mainproj', 'c')
+
+subproject('a')
diff --git a/test cases/failing/63 subproj filegrab/prog.c b/test cases/failing/63 subproj filegrab/prog.c
new file mode 100644
index 000000000..0314ff17b
--- /dev/null
+++ b/test cases/failing/63 subproj filegrab/prog.c
@@ -0,0 +1 @@
+int main(int argc, char **argv) { return 0; }
diff --git a/test cases/failing/63 subproj filegrab/subprojects/a/meson.build b/test cases/failing/63 subproj filegrab/subprojects/a/meson.build
new file mode 100644
index 000000000..80b988804
--- /dev/null
+++ b/test cases/failing/63 subproj filegrab/subprojects/a/meson.build
@@ -0,0 +1,3 @@
+project('a', 'c')
+
+executable('prog', '../../prog.c')