mirror of
https://github.com/samba-team/samba.git
synced 2025-01-06 13:18:07 +03:00
068b366709
Like many languages, Perl uses has randomisation to prevent nasty users using crafted values that hash to the same number to effect a denial of service. This means the traversal order of perl HASH tables is different every time. The IDL handed to pidl is trusted, so we don't really need randomisation, but we do want to be sure the build is the same every time. I am not aware of hash randomisation causing problems, but it seems prudent to avoid it. We do a similar thing with PYTHONHASHSEED for the entire build. Thanks to Freexian and the Debian LTS project for sponsoring this work. BUG: https://bugzilla.samba.org/show_bug.cgi?id=13213 Signed-off-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> Reviewed-by: Andrew Bartlett <abartlet@samba.org>
178 lines
6.7 KiB
Python
178 lines
6.7 KiB
Python
# waf build tool for building IDL files with pidl
|
|
|
|
import os
|
|
from waflib import Build, Utils
|
|
from waflib.TaskGen import feature, before
|
|
from samba_utils import SET_TARGET_TYPE, TO_LIST, LOCAL_CACHE
|
|
|
|
def SAMBA_PIDL(bld, pname, source,
|
|
options='',
|
|
output_dir='.',
|
|
generate_tables=True):
|
|
'''Build a IDL file using pidl.
|
|
This will produce up to 17 output files depending on the options used'''
|
|
|
|
bname = source[0:-4] # strip off the .idl suffix
|
|
bname = os.path.basename(bname)
|
|
name = "%s_%s" % (pname, bname.upper())
|
|
|
|
if not SET_TARGET_TYPE(bld, name, 'PIDL'):
|
|
return
|
|
|
|
bld.SET_BUILD_GROUP('build_source')
|
|
|
|
# the output files depend on the options used. Use this dictionary
|
|
# to map between the options and the resulting file names
|
|
options_map = { '--header' : '%s.h',
|
|
'--ndr-parser' : 'ndr_%s.c ndr_%s.h',
|
|
'--samba3-ndr-server' : 'srv_%s.c srv_%s.h',
|
|
'--samba3-ndr-client' : 'cli_%s.c cli_%s.h',
|
|
'--server' : 'ndr_%s_s.c',
|
|
'--server-compat' : 'ndr_%s_scompat.c ndr_%s_scompat.h',
|
|
'--client' : 'ndr_%s_c.c ndr_%s_c.h',
|
|
'--python' : 'py_%s.c',
|
|
'--tdr-parser' : 'tdr_%s.c tdr_%s.h',
|
|
'--dcom-proxy' : '%s_p.c',
|
|
'--com-header' : 'com_%s.h'
|
|
}
|
|
|
|
table_header_idx = None
|
|
out_files = []
|
|
options_list = TO_LIST(options)
|
|
|
|
for o in options_list:
|
|
if o in options_map:
|
|
ofiles = TO_LIST(options_map[o])
|
|
for f in ofiles:
|
|
out_files.append(os.path.join(output_dir, f % bname))
|
|
if f == 'ndr_%s.h':
|
|
# remember this one for the tables generation
|
|
table_header_idx = len(out_files) - 1
|
|
|
|
# depend on the full pidl sources
|
|
source = TO_LIST(source)
|
|
try:
|
|
pidl_src_nodes = bld.pidl_files_cache
|
|
except AttributeError:
|
|
bld.pidl_files_cache = bld.srcnode.ant_glob('pidl/lib/Parse/**/*.pm', flat=False)
|
|
bld.pidl_files_cache.extend(bld.srcnode.ant_glob('pidl', flat=False))
|
|
pidl_src_nodes = bld.pidl_files_cache
|
|
|
|
# the cd .. is needed because pidl currently is sensitive to the directory it is run in
|
|
cpp = ""
|
|
cc = ""
|
|
if bld.CONFIG_SET("CPP") and bld.CONFIG_GET("CPP") != "":
|
|
if isinstance(bld.CONFIG_GET("CPP"), list):
|
|
cpp = 'CPP="%s"' % " ".join(bld.CONFIG_GET("CPP"))
|
|
else:
|
|
cpp = 'CPP="%s"' % bld.CONFIG_GET("CPP")
|
|
|
|
if cpp == "CPP=xlc_r":
|
|
cpp = ""
|
|
|
|
if bld.env['PIDL_DEVELOPER_MODE']:
|
|
pidl_dev = 'PIDL_DEVELOPER=1 '
|
|
else:
|
|
pidl_dev = ''
|
|
|
|
if bld.CONFIG_SET("CC"):
|
|
if isinstance(bld.CONFIG_GET("CC"), list):
|
|
cc = 'CC="%s"' % " ".join(bld.CONFIG_GET("CC"))
|
|
else:
|
|
cc = 'CC="%s"' % bld.CONFIG_GET("CC")
|
|
|
|
t = bld(rule=('cd ${PIDL_LAUNCH_DIR} && PERL_HASH_SEED=0 %s%s %s ${PERL} '
|
|
'${PIDL} --quiet ${OPTIONS} --outputdir ${OUTPUTDIR} -- "${IDLSRC}"' %
|
|
(pidl_dev, cpp, cc)),
|
|
ext_out = '.c',
|
|
before = 'c',
|
|
update_outputs = True,
|
|
shell = True,
|
|
source = source,
|
|
target = out_files,
|
|
name = name,
|
|
samba_type = 'PIDL')
|
|
|
|
|
|
t.env.PIDL_LAUNCH_DIR = bld.srcnode.path_from(bld.bldnode)
|
|
pnode = bld.srcnode.find_resource('pidl/pidl')
|
|
t.env.PIDL = pnode.path_from(bld.srcnode)
|
|
t.env.OPTIONS = TO_LIST(options)
|
|
snode = t.path.find_resource(source[0])
|
|
t.env.IDLSRC = snode.path_from(bld.srcnode)
|
|
t.env.OUTPUTDIR = bld.bldnode.path_from(bld.srcnode) + '/' + bld.path.find_dir(output_dir).path_from(bld.srcnode)
|
|
|
|
bld.add_manual_dependency(snode, pidl_src_nodes)
|
|
|
|
if generate_tables and table_header_idx is not None:
|
|
pidl_headers = LOCAL_CACHE(bld, 'PIDL_HEADERS')
|
|
pidl_headers[name] = [bld.path.find_or_declare(out_files[table_header_idx])]
|
|
|
|
t.more_includes = '#' + bld.path.path_from(bld.srcnode)
|
|
Build.BuildContext.SAMBA_PIDL = SAMBA_PIDL
|
|
|
|
def SAMBA_PIDL_LIST(bld, name, source,
|
|
options='',
|
|
output_dir='.',
|
|
generate_tables=True,
|
|
generate_fuzzers=True):
|
|
'''A wrapper for building a set of IDL files'''
|
|
for p in TO_LIST(source):
|
|
bld.SAMBA_PIDL(name, p, options=options, output_dir=output_dir, generate_tables=generate_tables)
|
|
|
|
# Some IDL files don't exactly match between name and
|
|
# "interface" so we need a way to skip those, while other IDL
|
|
# files have the table generation skipped entirely, on which
|
|
# the fuzzers rely
|
|
if generate_tables and generate_fuzzers:
|
|
interface = p[0:-4] # strip off the .idl suffix
|
|
bld.SAMBA_NDR_FUZZ(interface,
|
|
auto_deps=True,
|
|
fuzz_type="TYPE_STRUCT")
|
|
|
|
# Only generate the TYPE_STRUCT fuzzer if this isn't
|
|
# really DCE/RPC
|
|
if '--client' in options:
|
|
bld.SAMBA_NDR_FUZZ(interface,
|
|
auto_deps=True,
|
|
fuzz_type="TYPE_IN")
|
|
bld.SAMBA_NDR_FUZZ(interface,
|
|
auto_deps=True,
|
|
fuzz_type="TYPE_OUT")
|
|
Build.BuildContext.SAMBA_PIDL_LIST = SAMBA_PIDL_LIST
|
|
|
|
|
|
#################################################################
|
|
# the rule for generating the NDR tables
|
|
@feature('collect')
|
|
@before('exec_rule')
|
|
def collect(self):
|
|
pidl_headers = LOCAL_CACHE(self.bld, 'PIDL_HEADERS')
|
|
# The first source is tables.pl itself
|
|
self.source = Utils.to_list(self.source)
|
|
for (name, hd) in pidl_headers.items():
|
|
y = self.bld.get_tgen_by_name(name)
|
|
self.bld.ASSERT(y is not None, 'Failed to find PIDL header %s' % name)
|
|
y.post()
|
|
for node in hd:
|
|
self.bld.ASSERT(node is not None, 'Got None as build node generating PIDL table for %s' % name)
|
|
self.source.append(node)
|
|
|
|
|
|
def SAMBA_PIDL_TABLES(bld, name, target):
|
|
'''generate the pidl NDR tables file'''
|
|
bld.SET_BUILD_GROUP('main')
|
|
t = bld(
|
|
features = 'collect',
|
|
rule = '${PERL} ${SRC} > ${TGT}',
|
|
ext_out = '.c',
|
|
before = 'c',
|
|
update_outputs = True,
|
|
shell = True,
|
|
source = '../../librpc/tables.pl',
|
|
target = target,
|
|
name = name)
|
|
t.env.LIBRPC = os.path.join(bld.srcnode.abspath(), 'librpc')
|
|
Build.BuildContext.SAMBA_PIDL_TABLES = SAMBA_PIDL_TABLES
|
|
|