From 68bd64cd38f40eedddbe8e96ea6a61c746d1b78b Mon Sep 17 00:00:00 2001 From: Jussi Pakkanen Date: Fri, 29 Sep 2017 23:25:35 +0300 Subject: Prevent projects from directly grabbing files from other subprojects. --- mesonbuild/interpreter.py | 35 ++++++++++++++++++++++ test cases/failing/63 subproj filegrab/meson.build | 3 ++ test cases/failing/63 subproj filegrab/prog.c | 1 + .../63 subproj filegrab/subprojects/a/meson.build | 3 ++ 4 files changed, 42 insertions(+) create mode 100644 test cases/failing/63 subproj filegrab/meson.build create mode 100644 test cases/failing/63 subproj filegrab/prog.c create mode 100644 test cases/failing/63 subproj filegrab/subprojects/a/meson.build diff --git a/mesonbuild/interpreter.py b/mesonbuild/interpreter.py index b938080..f4bc11f 100644 --- a/mesonbuild/interpreter.py +++ b/mesonbuild/interpreter.py @@ -2785,6 +2785,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: @@ -2792,6 +2826,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 {!r} instead of ' 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 0000000..6982c78 --- /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 0000000..0314ff1 --- /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 0000000..80b9888 --- /dev/null +++ b/test cases/failing/63 subproj filegrab/subprojects/a/meson.build @@ -0,0 +1,3 @@ +project('a', 'c') + +executable('prog', '../../prog.c') -- cgit v1.1