Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(27)

Side by Side Diff: build/link_irt.py

Issue 1009533004: Add lint check for IRT sandbox base address hiding. (Closed) Base URL: https://chromium.googlesource.com/native_client/src/native_client.git@master
Patch Set: review Created 5 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « build/build_nexe.py ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 #!/usr/bin/python 1 #!/usr/bin/python
2 # Copyright 2014 The Native Client Authors. All rights reserved. 2 # Copyright 2014 The Native Client Authors. All rights reserved.
3 # Use of this source code is governed by a BSD-style license that can be 3 # Use of this source code is governed by a BSD-style license that can be
4 # found in the LICENSE file. 4 # found in the LICENSE file.
5 5
6 """Script for linking the NaCl IRT and IRT core. 6 """Script for linking the NaCl IRT and IRT core.
7 7
8 This module will take care of linking the NaCl IRT. Compiling the libraries 8 This module will take care of linking the NaCl IRT. Compiling the libraries
9 and object files that go into the NaCl IRT is done outside of this script. 9 and object files that go into the NaCl IRT is done outside of this script.
10 10
11 Linking is factored out because the IRT has specific requirements for 11 Linking is factored out because the IRT has specific requirements for
12 where to place the text vs data segments, and also requires editting how 12 where to place the text vs data segments, and also requires editting how
13 TLS access is done. Thus, it's more complicated than the usual linking. 13 TLS access is done. Thus, it's more complicated than the usual linking.
14 """ 14 """
15 15
16 import argparse 16 import argparse
17 import os 17 import os
18 import re
18 import sys 19 import sys
19 20
20 from build_nexe_tools import (CommandRunner, Error, FixPath, MakeDir) 21 from build_nexe_tools import (CommandRunner, Error, FixPath, MakeDir)
21 22
22 23
23 class IRTLinker(CommandRunner): 24 class IRTLinker(CommandRunner):
24 """Builder object that generates build command-lines and runs them. 25 """Builder object that generates build command-lines and runs them.
25 """ 26 """
26 27
27 def __init__(self, options): 28 def __init__(self, options):
28 super(IRTLinker, self).__init__(options) 29 super(IRTLinker, self).__init__(options)
29 # IRT constraints for auto layout. 30 # IRT constraints for auto layout.
30 # IRT text can only go up to 256MB. Addresses after that are for data. 31 # IRT text can only go up to 256MB. Addresses after that are for data.
31 # Reserve an extra page because: 32 # Reserve an extra page because:
32 # * sel_ldr requires a HLT sled at the end of the dynamic code area; 33 # * sel_ldr requires a HLT sled at the end of the dynamic code area;
33 # * dynamic_load_test currently tests loading at the end of the dynamic 34 # * dynamic_load_test currently tests loading at the end of the dynamic
34 # code area. 35 # code area.
35 self.irt_text_max = 0x10000000 - 0x10000 36 self.irt_text_max = 0x10000000 - 0x10000
36 # Data can only go up to the sandbox_top - sizeof(stack). 37 # Data can only go up to the sandbox_top - sizeof(stack).
37 # NaCl allocates 16MB for the initial thread's stack (see 38 # NaCl allocates 16MB for the initial thread's stack (see
38 # NACL_DEFAULT_STACK_MAX in sel_ldr.h). 39 # NACL_DEFAULT_STACK_MAX in sel_ldr.h).
39 # Assume sandbox_top is 1GB, since even on x86-64 the limit would 40 # Assume sandbox_top is 1GB, since even on x86-64 the limit would
40 # only be 2GB (rip-relative references can only be +/- 2GB). 41 # only be 2GB (rip-relative references can only be +/- 2GB).
41 sandbox_top = 0x40000000 42 sandbox_top = 0x40000000
42 self.irt_data_max = sandbox_top - (16 << 20) 43 self.irt_data_max = sandbox_top - (16 << 20)
43 self.output = options.output 44 self.output = options.output
44 self.link_cmd = options.link_cmd 45 self.link_cmd = options.link_cmd
45 self.readelf_cmd = options.readelf_cmd 46 self.readelf_cmd = options.readelf_cmd
47 self.objdump_cmd = options.objdump_cmd
46 self.tls_edit = options.tls_edit 48 self.tls_edit = options.tls_edit
47 self.SetCommandsAreScripts(options.commands_are_scripts) 49 self.SetCommandsAreScripts(options.commands_are_scripts)
48 50
49 def GetIRTLayout(self, irt_file): 51 def GetIRTLayout(self, irt_file):
50 """Check if the IRT's data and text segment fit layout constraints and 52 """Check if the IRT's data and text segment fit layout constraints and
51 get sizes of the IRT's text and data segments. 53 get sizes of the IRT's text and data segments.
52 54
53 Returns a tuple containing: 55 Returns a tuple containing:
54 * whether the IRT data/text top addresses fit within the max limit 56 * whether the IRT data/text top addresses fit within the max limit
55 * current data/text top addrs 57 * current data/text top addrs
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
155 'text_top=0x%x and data_top=0x%x\n' % ( 157 'text_top=0x%x and data_top=0x%x\n' % (
156 text_top, data_top)) 158 text_top, data_top))
157 self.Log('IRT layout fits: text_top=0x%x and data_top=0x%x' % 159 self.Log('IRT layout fits: text_top=0x%x and data_top=0x%x' %
158 (text_top, data_top)) 160 (text_top, data_top))
159 161
160 tls_edit_cmd = [FixPath(self.tls_edit), pre_tls_edit_out, out] 162 tls_edit_cmd = [FixPath(self.tls_edit), pre_tls_edit_out, out]
161 tls_edit_err = self.Run(tls_edit_cmd, possibly_script=False) 163 tls_edit_err = self.Run(tls_edit_cmd, possibly_script=False)
162 if tls_edit_err: 164 if tls_edit_err:
163 raise Error('FAILED with %d: %s' % (err, ' '.join(tls_edit_cmd))) 165 raise Error('FAILED with %d: %s' % (err, ' '.join(tls_edit_cmd)))
164 166
167 def SandboxBaseCheck(self):
168 """
169 Check that sandbox base address is not revealed.
170
171 This is a kind of lint check to ensure that the LLVM assembler's option for
172 hiding the sandbox base address on x86-64 is being used in all code compiled
173 into the IRT. It is only a heuristic intended to prevent accidental changes
174 in the IRT or toolchain build, and is not exhaustive. It is a stopgap until
175 we can fix https://code.google.com/p/nativeclient/issues/detail?id=3596
176 """
177 cmd = [self.objdump_cmd, '-d', self.output]
178 output = self.Run(cmd, get_output=True)
179 # Disallow callq, all movs variants, all stos variants
180 # (objdump always disassembles 'call' as 'callq' in x86-64)
181 test_regex = r'\scallq\s|\smovs[bwlq]\s|\sstos[bwlq]\s'
182 # Disallow reads/pushes from rsp (other than %rsp,%rpb), and from rbp
183 test_regex += r'|[^(]%rsp,(?!%rbp)|[^(]%rbp,|push\s+%r[sb]p'
184 # Disallow reads from %r11 or uses as a base register
185 test_regex += r'|%r11,'
186 # All indirect jumps must be through r11
187 test_regex += r'|jmpq\s+\*%r(?!11)'
188 matched = re.search(test_regex, output)
189 if matched:
190 print 'The following instructions may reveal the sandbox base address:'
191 lines_printed = 0
192 lines_printed_limit = 50
193 for line in output.splitlines():
194 match = re.search(test_regex, line)
195 if match and lines_printed < lines_printed_limit:
196 lines_printed += 1
197 print line
198 if lines_printed == lines_printed_limit:
199 print '(additional lines not printed)'
200 print 'ran', cmd
201 raise Error('IRT sandbox base address hiding lint check failed')
202
203 else:
204 self.Log('Sandbox base address hiding lint check passed')
205
165 206
166 def Main(): 207 def Main():
167 parser = argparse.ArgumentParser() 208 parser = argparse.ArgumentParser()
168 parser.add_argument('-o', '--output', dest='output', required=True, 209 parser.add_argument('-o', '--output', dest='output', required=True,
169 help='Output filename') 210 help='Output filename')
170 parser.add_argument('--tls-edit', dest='tls_edit', required=True, 211 parser.add_argument('--tls-edit', dest='tls_edit', required=True,
171 help='Path of tls edit utility') 212 help='Path of tls edit utility')
172 parser.add_argument('--link-cmd', dest='link_cmd', required=True, 213 parser.add_argument('--link-cmd', dest='link_cmd', required=True,
173 help='Path of linker utility') 214 help='Path of linker utility')
174 parser.add_argument('--readelf-cmd', dest='readelf_cmd', required=True, 215 parser.add_argument('--readelf-cmd', dest='readelf_cmd', required=True,
175 help='Path of readelf utility') 216 help='Path of readelf utility')
217 parser.add_argument('--objdump-cmd', dest='objdump_cmd', required=False,
218 help='Path of objdump utility')
176 parser.add_argument('-v', '--verbose', dest='verbose', default=False, 219 parser.add_argument('-v', '--verbose', dest='verbose', default=False,
177 help='Enable verbosity', action='store_true') 220 help='Enable verbosity', action='store_true')
178 parser.add_argument('--commands-are-scripts', dest='commands_are_scripts', 221 parser.add_argument('--commands-are-scripts', dest='commands_are_scripts',
179 action='store_true', default=False, 222 action='store_true', default=False,
180 help='Indicate that toolchain commands are scripts') 223 help='Indicate that toolchain commands are scripts')
224 parser.add_argument('--sandbox-base-hiding-check',
225 dest='sandbox_base_hiding_check', action='store_true',
226 default=False)
181 args, remaining_args = parser.parse_known_args() 227 args, remaining_args = parser.parse_known_args()
182 linker = IRTLinker(args) 228 linker = IRTLinker(args)
183 linker.Link(remaining_args) 229 linker.Link(remaining_args)
230 if args.sandbox_base_hiding_check:
231 linker.SandboxBaseCheck()
184 return 0 232 return 0
185 233
186 234
187 if __name__ == '__main__': 235 if __name__ == '__main__':
188 sys.exit(Main()) 236 sys.exit(Main())
OLDNEW
« no previous file with comments | « build/build_nexe.py ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698