From: Jelmer Vernooij Date: Sun, 8 Nov 2015 20:56:54 +0000 (+0000) Subject: Imported Upstream version 2.1.5 X-Git-Url: http://git.samba.org/?a=commitdiff_plain;h=89274dfb5641fc2cc404a49994a796f907ae56c1;p=abartlet%2Ftalloc-debian.git Imported Upstream version 2.1.5 --- diff --git a/ABI/pytalloc-util-2.1.4.sigs b/ABI/pytalloc-util-2.1.4.sigs new file mode 100644 index 0000000..961c1a8 --- /dev/null +++ b/ABI/pytalloc-util-2.1.4.sigs @@ -0,0 +1,6 @@ +pytalloc_CObject_FromTallocPtr: PyObject *(void *) +pytalloc_Check: int (PyObject *) +pytalloc_GetObjectType: PyTypeObject *(void) +pytalloc_reference_ex: PyObject *(PyTypeObject *, TALLOC_CTX *, void *) +pytalloc_steal: PyObject *(PyTypeObject *, void *) +pytalloc_steal_ex: PyObject *(PyTypeObject *, TALLOC_CTX *, void *) diff --git a/ABI/pytalloc-util-2.1.5.sigs b/ABI/pytalloc-util-2.1.5.sigs new file mode 100644 index 0000000..961c1a8 --- /dev/null +++ b/ABI/pytalloc-util-2.1.5.sigs @@ -0,0 +1,6 @@ +pytalloc_CObject_FromTallocPtr: PyObject *(void *) +pytalloc_Check: int (PyObject *) +pytalloc_GetObjectType: PyTypeObject *(void) +pytalloc_reference_ex: PyObject *(PyTypeObject *, TALLOC_CTX *, void *) +pytalloc_steal: PyObject *(PyTypeObject *, void *) +pytalloc_steal_ex: PyObject *(PyTypeObject *, TALLOC_CTX *, void *) diff --git a/ABI/pytalloc-util.py3-2.1.5.sigs b/ABI/pytalloc-util.py3-2.1.5.sigs new file mode 100644 index 0000000..0807eb3 --- /dev/null +++ b/ABI/pytalloc-util.py3-2.1.5.sigs @@ -0,0 +1,5 @@ +pytalloc_Check: int (PyObject *) +pytalloc_GetObjectType: PyTypeObject *(void) +pytalloc_reference_ex: PyObject *(PyTypeObject *, TALLOC_CTX *, void *) +pytalloc_steal: PyObject *(PyTypeObject *, void *) +pytalloc_steal_ex: PyObject *(PyTypeObject *, TALLOC_CTX *, void *) diff --git a/ABI/talloc-2.1.4.sigs b/ABI/talloc-2.1.4.sigs new file mode 100644 index 0000000..9969ce3 --- /dev/null +++ b/ABI/talloc-2.1.4.sigs @@ -0,0 +1,65 @@ +_talloc: void *(const void *, size_t) +_talloc_array: void *(const void *, size_t, unsigned int, const char *) +_talloc_free: int (void *, const char *) +_talloc_get_type_abort: void *(const void *, const char *, const char *) +_talloc_memdup: void *(const void *, const void *, size_t, const char *) +_talloc_move: void *(const void *, const void *) +_talloc_pooled_object: void *(const void *, size_t, const char *, unsigned int, size_t) +_talloc_realloc: void *(const void *, void *, size_t, const char *) +_talloc_realloc_array: void *(const void *, void *, size_t, unsigned int, const char *) +_talloc_reference_loc: void *(const void *, const void *, const char *) +_talloc_set_destructor: void (const void *, int (*)(void *)) +_talloc_steal_loc: void *(const void *, const void *, const char *) +_talloc_zero: void *(const void *, size_t, const char *) +_talloc_zero_array: void *(const void *, size_t, unsigned int, const char *) +talloc_asprintf: char *(const void *, const char *, ...) +talloc_asprintf_append: char *(char *, const char *, ...) +talloc_asprintf_append_buffer: char *(char *, const char *, ...) +talloc_autofree_context: void *(void) +talloc_check_name: void *(const void *, const char *) +talloc_disable_null_tracking: void (void) +talloc_enable_leak_report: void (void) +talloc_enable_leak_report_full: void (void) +talloc_enable_null_tracking: void (void) +talloc_enable_null_tracking_no_autofree: void (void) +talloc_find_parent_byname: void *(const void *, const char *) +talloc_free_children: void (void *) +talloc_get_name: const char *(const void *) +talloc_get_size: size_t (const void *) +talloc_increase_ref_count: int (const void *) +talloc_init: void *(const char *, ...) +talloc_is_parent: int (const void *, const void *) +talloc_named: void *(const void *, size_t, const char *, ...) +talloc_named_const: void *(const void *, size_t, const char *) +talloc_parent: void *(const void *) +talloc_parent_name: const char *(const void *) +talloc_pool: void *(const void *, size_t) +talloc_realloc_fn: void *(const void *, void *, size_t) +talloc_reference_count: size_t (const void *) +talloc_reparent: void *(const void *, const void *, const void *) +talloc_report: void (const void *, FILE *) +talloc_report_depth_cb: void (const void *, int, int, void (*)(const void *, int, int, int, void *), void *) +talloc_report_depth_file: void (const void *, int, int, FILE *) +talloc_report_full: void (const void *, FILE *) +talloc_set_abort_fn: void (void (*)(const char *)) +talloc_set_log_fn: void (void (*)(const char *)) +talloc_set_log_stderr: void (void) +talloc_set_memlimit: int (const void *, size_t) +talloc_set_name: const char *(const void *, const char *, ...) +talloc_set_name_const: void (const void *, const char *) +talloc_show_parents: void (const void *, FILE *) +talloc_strdup: char *(const void *, const char *) +talloc_strdup_append: char *(char *, const char *) +talloc_strdup_append_buffer: char *(char *, const char *) +talloc_strndup: char *(const void *, const char *, size_t) +talloc_strndup_append: char *(char *, const char *, size_t) +talloc_strndup_append_buffer: char *(char *, const char *, size_t) +talloc_test_get_magic: int (void) +talloc_total_blocks: size_t (const void *) +talloc_total_size: size_t (const void *) +talloc_unlink: int (const void *, void *) +talloc_vasprintf: char *(const void *, const char *, va_list) +talloc_vasprintf_append: char *(char *, const char *, va_list) +talloc_vasprintf_append_buffer: char *(char *, const char *, va_list) +talloc_version_major: int (void) +talloc_version_minor: int (void) diff --git a/ABI/talloc-2.1.5.sigs b/ABI/talloc-2.1.5.sigs new file mode 100644 index 0000000..9969ce3 --- /dev/null +++ b/ABI/talloc-2.1.5.sigs @@ -0,0 +1,65 @@ +_talloc: void *(const void *, size_t) +_talloc_array: void *(const void *, size_t, unsigned int, const char *) +_talloc_free: int (void *, const char *) +_talloc_get_type_abort: void *(const void *, const char *, const char *) +_talloc_memdup: void *(const void *, const void *, size_t, const char *) +_talloc_move: void *(const void *, const void *) +_talloc_pooled_object: void *(const void *, size_t, const char *, unsigned int, size_t) +_talloc_realloc: void *(const void *, void *, size_t, const char *) +_talloc_realloc_array: void *(const void *, void *, size_t, unsigned int, const char *) +_talloc_reference_loc: void *(const void *, const void *, const char *) +_talloc_set_destructor: void (const void *, int (*)(void *)) +_talloc_steal_loc: void *(const void *, const void *, const char *) +_talloc_zero: void *(const void *, size_t, const char *) +_talloc_zero_array: void *(const void *, size_t, unsigned int, const char *) +talloc_asprintf: char *(const void *, const char *, ...) +talloc_asprintf_append: char *(char *, const char *, ...) +talloc_asprintf_append_buffer: char *(char *, const char *, ...) +talloc_autofree_context: void *(void) +talloc_check_name: void *(const void *, const char *) +talloc_disable_null_tracking: void (void) +talloc_enable_leak_report: void (void) +talloc_enable_leak_report_full: void (void) +talloc_enable_null_tracking: void (void) +talloc_enable_null_tracking_no_autofree: void (void) +talloc_find_parent_byname: void *(const void *, const char *) +talloc_free_children: void (void *) +talloc_get_name: const char *(const void *) +talloc_get_size: size_t (const void *) +talloc_increase_ref_count: int (const void *) +talloc_init: void *(const char *, ...) +talloc_is_parent: int (const void *, const void *) +talloc_named: void *(const void *, size_t, const char *, ...) +talloc_named_const: void *(const void *, size_t, const char *) +talloc_parent: void *(const void *) +talloc_parent_name: const char *(const void *) +talloc_pool: void *(const void *, size_t) +talloc_realloc_fn: void *(const void *, void *, size_t) +talloc_reference_count: size_t (const void *) +talloc_reparent: void *(const void *, const void *, const void *) +talloc_report: void (const void *, FILE *) +talloc_report_depth_cb: void (const void *, int, int, void (*)(const void *, int, int, int, void *), void *) +talloc_report_depth_file: void (const void *, int, int, FILE *) +talloc_report_full: void (const void *, FILE *) +talloc_set_abort_fn: void (void (*)(const char *)) +talloc_set_log_fn: void (void (*)(const char *)) +talloc_set_log_stderr: void (void) +talloc_set_memlimit: int (const void *, size_t) +talloc_set_name: const char *(const void *, const char *, ...) +talloc_set_name_const: void (const void *, const char *) +talloc_show_parents: void (const void *, FILE *) +talloc_strdup: char *(const void *, const char *) +talloc_strdup_append: char *(char *, const char *) +talloc_strdup_append_buffer: char *(char *, const char *) +talloc_strndup: char *(const void *, const char *, size_t) +talloc_strndup_append: char *(char *, const char *, size_t) +talloc_strndup_append_buffer: char *(char *, const char *, size_t) +talloc_test_get_magic: int (void) +talloc_total_blocks: size_t (const void *) +talloc_total_size: size_t (const void *) +talloc_unlink: int (const void *, void *) +talloc_vasprintf: char *(const void *, const char *, va_list) +talloc_vasprintf_append: char *(char *, const char *, va_list) +talloc_vasprintf_append_buffer: char *(char *, const char *, va_list) +talloc_version_major: int (void) +talloc_version_minor: int (void) diff --git a/buildtools/wafsamba/configure_file.py b/buildtools/wafsamba/configure_file.py index 8e2ba3b..e28282b 100644 --- a/buildtools/wafsamba/configure_file.py +++ b/buildtools/wafsamba/configure_file.py @@ -1,18 +1,15 @@ # handle substitution of variables in .in files +import re, os import Build, sys, Logs -from samba_utils import * +from samba_utils import SUBST_VARS_RECURSIVE def subst_at_vars(task): '''substiture @VAR@ style variables in a file''' env = task.env - src = task.inputs[0].srcpath(env) - tgt = task.outputs[0].bldpath(env) + s = task.inputs[0].read() - f = open(src, 'r') - s = f.read() - f.close() # split on the vars a = re.split('(@\w+@)', s) out = [] @@ -27,9 +24,7 @@ def subst_at_vars(task): v = SUBST_VARS_RECURSIVE(task.env[vname], task.env) out.append(v) contents = ''.join(out) - f = open(tgt, 'w') - s = f.write(contents) - f.close() + task.outputs[0].write(contents) return 0 def CONFIGURE_FILE(bld, in_file, **kwargs): diff --git a/buildtools/wafsamba/gccdeps.py b/buildtools/wafsamba/gccdeps.py index 2da42e6..47505f0 100644 --- a/buildtools/wafsamba/gccdeps.py +++ b/buildtools/wafsamba/gccdeps.py @@ -14,7 +14,7 @@ lock = threading.Lock() preprocessor_flag = '-MD' -@feature('cc') +@feature('c', 'cc') @before('apply_core') def add_mmd_cc(self): if self.env.get_flat('CCFLAGS').find(preprocessor_flag) < 0: diff --git a/buildtools/wafsamba/nothreads.py b/buildtools/wafsamba/nothreads.py index 075dcd3..d194eb8 100644 --- a/buildtools/wafsamba/nothreads.py +++ b/buildtools/wafsamba/nothreads.py @@ -10,12 +10,11 @@ "Execute the tasks" -import sys, random, time, threading, traceback, os +import sys, random, threading try: from Queue import Queue except ImportError: from queue import Queue -import Build, Utils, Logs, Options -from Logs import debug, error -from Constants import * +import Utils, Options +from Constants import EXCEPTION, CRASHED, MAXJOBS, ASK_LATER, SKIPPED, SKIP_ME, SUCCESS GAP = 15 diff --git a/buildtools/wafsamba/pkgconfig.py b/buildtools/wafsamba/pkgconfig.py index 8a3f807..25cec78 100644 --- a/buildtools/wafsamba/pkgconfig.py +++ b/buildtools/wafsamba/pkgconfig.py @@ -1,16 +1,13 @@ # handle substitution of variables in pc files -import Build, sys, Logs -from samba_utils import * +import os, re, sys +import Build, Logs +from samba_utils import SUBST_VARS_RECURSIVE, TO_LIST def subst_at_vars(task): '''substiture @VAR@ style variables in a file''' - src = task.inputs[0].srcpath(task.env) - tgt = task.outputs[0].bldpath(task.env) - f = open(src, 'r') - s = f.read() - f.close() + s = task.inputs[0].read() # split on the vars a = re.split('(@\w+@)', s) out = [] @@ -37,9 +34,7 @@ def subst_at_vars(task): break out.append(v) contents = ''.join(out) - f = open(tgt, 'w') - s = f.write(contents) - f.close() + task.outputs[0].write(contents) return 0 diff --git a/buildtools/wafsamba/samba_abi.py b/buildtools/wafsamba/samba_abi.py index 76acd00..8220594 100644 --- a/buildtools/wafsamba/samba_abi.py +++ b/buildtools/wafsamba/samba_abi.py @@ -137,7 +137,8 @@ def abi_check(self): topsrc = self.bld.srcnode.abspath() abi_gen = os.path.join(topsrc, 'buildtools/scripts/abi_gen.sh') - abi_file = "%s/%s-%s.sigs" % (self.abi_directory, self.name, self.vnum) + abi_file = "%s/%s-%s.sigs" % (self.abi_directory, self.version_libname, + self.vnum) tsk = self.create_task('abi_check', self.link_task.outputs[0]) tsk.ABI_FILE = abi_file @@ -147,12 +148,10 @@ def abi_check(self): def abi_process_file(fname, version, symmap): '''process one ABI file, adding new symbols to the symmap''' - f = open(fname, mode='r') - for line in f: + for line in Utils.readf(fname).splitlines(): symname = line.split(":")[0] if not symname in symmap: symmap[symname] = version - f.close() def abi_write_vscript(f, libname, current_version, versions, symmap, abi_match): diff --git a/buildtools/wafsamba/samba_autoconf.py b/buildtools/wafsamba/samba_autoconf.py index c5f132c..296f9fb 100644 --- a/buildtools/wafsamba/samba_autoconf.py +++ b/buildtools/wafsamba/samba_autoconf.py @@ -1,10 +1,10 @@ # a waf tool to add autoconf-like macros to the configure section -import Build, os, sys, Options, preproc, Logs -import string +import os, sys +import Build, Options, preproc, Logs from Configure import conf -from samba_utils import * -import samba_cross +from TaskGen import feature +from samba_utils import TO_LIST, GET_TARGET_TYPE, SET_TARGET_TYPE, runonce, unique_list, mkdir_p missing_headers = set() @@ -569,7 +569,7 @@ int foo() (ccflags, ldflags, cpppath) = library_flags(conf, lib) if shlib: - res = conf.check(features='cc cshlib', fragment=fragment, lib=lib, uselib_store=lib, ccflags=ccflags, ldflags=ldflags, uselib=lib.upper()) + res = conf.check(features='c cshlib', fragment=fragment, lib=lib, uselib_store=lib, ccflags=ccflags, ldflags=ldflags, uselib=lib.upper()) else: res = conf.check(lib=lib, uselib_store=lib, ccflags=ccflags, ldflags=ldflags, uselib=lib.upper()) @@ -657,9 +657,23 @@ def SAMBA_CONFIG_H(conf, path=None): if not IN_LAUNCH_DIR(conf): return - if conf.CHECK_CFLAGS(['-fstack-protector']) and conf.CHECK_LDFLAGS(['-fstack-protector']): - conf.ADD_CFLAGS('-fstack-protector') - conf.ADD_LDFLAGS('-fstack-protector') + # we need to build real code that can't be optimized away to test + if conf.check(fragment=''' + #include + + int main(void) + { + char t[100000]; + while (fgets(t, sizeof(t), stdin)); + return 0; + } + ''', + execute=0, + ccflags='-fstack-protector', + ldflags='-fstack-protector', + msg='Checking if toolchain accepts -fstack-protector'): + conf.ADD_CFLAGS('-fstack-protector') + conf.ADD_LDFLAGS('-fstack-protector') if Options.options.debug: conf.ADD_CFLAGS('-g', testflags=True) diff --git a/buildtools/wafsamba/samba_autoproto.py b/buildtools/wafsamba/samba_autoproto.py index bad627a..b2b5233 100644 --- a/buildtools/wafsamba/samba_autoproto.py +++ b/buildtools/wafsamba/samba_autoproto.py @@ -1,7 +1,8 @@ # waf build tool for building automatic prototypes from C source +import os import Build -from samba_utils import * +from samba_utils import SET_TARGET_TYPE, os_path_relpath def SAMBA_AUTOPROTO(bld, header, source): '''rule for samba prototype generation''' diff --git a/buildtools/wafsamba/samba_bundled.py b/buildtools/wafsamba/samba_bundled.py index c8bfcd2..bfc7ecc 100644 --- a/buildtools/wafsamba/samba_bundled.py +++ b/buildtools/wafsamba/samba_bundled.py @@ -1,8 +1,9 @@ # functions to support bundled libraries +import sys +import Build, Options, Logs from Configure import conf -import sys, Logs -from samba_utils import * +from samba_utils import TO_LIST, runonce def PRIVATE_NAME(bld, name, private_extension, private_library): '''possibly rename a library to include a bundled extension''' @@ -107,16 +108,6 @@ def LIB_MUST_BE_PRIVATE(conf, libname): return ('ALL' in conf.env.PRIVATE_LIBS or libname in conf.env.PRIVATE_LIBS) -@conf -def CHECK_PREREQUISITES(conf, prereqs): - missing = [] - for syslib in TO_LIST(prereqs): - f = 'FOUND_SYSTEMLIB_%s' % syslib - if not f in conf.env: - missing.append(syslib) - return missing - - @runonce @conf def CHECK_BUNDLED_SYSTEM_PKG(conf, libname, minversion='0.0.0', @@ -141,11 +132,34 @@ def CHECK_BUNDLED_SYSTEM(conf, libname, minversion='0.0.0', this first tries via pkg-config, then if that fails tries by testing for a specified function in the specified lib ''' - if conf.LIB_MUST_BE_BUNDLED(libname): - return False + # We always do a logic validation of 'onlyif' first + missing = [] + if onlyif: + for l in TO_LIST(onlyif): + f = 'FOUND_SYSTEMLIB_%s' % l + if not f in conf.env: + Logs.error('ERROR: CHECK_BUNDLED_SYSTEM(%s) - ' % (libname) + + 'missing prerequisite check for ' + + 'system library %s, onlyif=%r' % (l, onlyif)) + sys.exit(1) + if not conf.env[f]: + missing.append(l) found = 'FOUND_SYSTEMLIB_%s' % libname if found in conf.env: return conf.env[found] + if conf.LIB_MUST_BE_BUNDLED(libname): + conf.env[found] = False + return False + + # see if the library should only use a system version if another dependent + # system version is found. That prevents possible use of mixed library + # versions + if missing: + if not conf.LIB_MAY_BE_BUNDLED(libname): + Logs.error('ERROR: Use of system library %s depends on missing system library/libraries %r' % (libname, missing)) + sys.exit(1) + conf.env[found] = False + return False def check_functions_headers_code(): '''helper function for CHECK_BUNDLED_SYSTEM''' @@ -166,19 +180,6 @@ def CHECK_BUNDLED_SYSTEM(conf, libname, minversion='0.0.0', return False return True - - # see if the library should only use a system version if another dependent - # system version is found. That prevents possible use of mixed library - # versions - if onlyif: - missing = conf.CHECK_PREREQUISITES(onlyif) - if missing: - if not conf.LIB_MAY_BE_BUNDLED(libname): - Logs.error('ERROR: Use of system library %s depends on missing system library/libraries %r' % (libname, missing)) - sys.exit(1) - conf.env[found] = False - return False - minversion = minimum_library_version(conf, libname, minversion) msg = 'Checking for system %s' % libname diff --git a/buildtools/wafsamba/samba_conftests.py b/buildtools/wafsamba/samba_conftests.py index 96fead5..b4e44c5 100644 --- a/buildtools/wafsamba/samba_conftests.py +++ b/buildtools/wafsamba/samba_conftests.py @@ -2,10 +2,9 @@ # to test for commonly needed configuration options import os, shutil, re -import Build, Configure, Utils +import Build, Configure, Utils, Options, Logs from Configure import conf -import config_c -from samba_utils import * +from samba_utils import TO_LIST, ADD_LD_LIBRARY_PATH def add_option(self, *k, **kw): @@ -197,7 +196,7 @@ int foo(int v) { return v * 2; } ''' - return conf.check(features='cc cshlib',vnum="1",fragment=snip,msg=msg) + return conf.check(features='c cshlib',vnum="1",fragment=snip,msg=msg) @conf def CHECK_NEED_LC(conf, msg): @@ -216,9 +215,7 @@ def CHECK_NEED_LC(conf, msg): os.makedirs(subdir) - dest = open(os.path.join(subdir, 'liblc1.c'), 'w') - dest.write('#include \nint lib_func(void) { FILE *f = fopen("foo", "r");}\n') - dest.close() + Utils.writef(os.path.join(subdir, 'liblc1.c'), '#include \nint lib_func(void) { FILE *f = fopen("foo", "r");}\n') bld = Build.BuildContext() bld.log = conf.log @@ -229,7 +226,7 @@ def CHECK_NEED_LC(conf, msg): bld.rescan(bld.srcnode) - bld(features='cc cshlib', + bld(features='c cshlib', source='liblctest/liblc1.c', ldflags=conf.env['EXTRA_LDFLAGS'], target='liblc', @@ -249,9 +246,6 @@ def CHECK_SHLIB_W_PYTHON(conf, msg): '''check if we need -undefined dynamic_lookup''' dir = find_config_dir(conf) - - env = conf.env - snip = ''' #include #include @@ -264,7 +258,7 @@ int foo(int v) { ldb_module = PyImport_ImportModule("ldb"); return v * 2; }''' - return conf.check(features='cc cshlib',uselib='PYEMBED',fragment=snip,msg=msg) + return conf.check(features='c cshlib',uselib='PYEMBED',fragment=snip,msg=msg) # this one is quite complex, and should probably be broken up # into several parts. I'd quite like to create a set of CHECK_COMPOUND() @@ -291,13 +285,8 @@ def CHECK_LIBRARY_SUPPORT(conf, rpath=False, version_script=False, msg=None): os.makedirs(subdir) - dest = open(os.path.join(subdir, 'lib1.c'), 'w') - dest.write('int lib_func(void) { return 42; }\n') - dest.close() - - dest = open(os.path.join(dir, 'main.c'), 'w') - dest.write('int main(void) {return !(lib_func() == 42);}\n') - dest.close() + Utils.writef(os.path.join(subdir, 'lib1.c'), 'int lib_func(void) { return 42; }\n') + Utils.writef(os.path.join(dir, 'main.c'), 'int main(void) {return !(lib_func() == 42);}\n') bld = Build.BuildContext() bld.log = conf.log @@ -311,17 +300,15 @@ def CHECK_LIBRARY_SUPPORT(conf, rpath=False, version_script=False, msg=None): ldflags = [] if version_script: ldflags.append("-Wl,--version-script=%s/vscript" % bld.path.abspath()) - dest = open(os.path.join(dir,'vscript'), 'w') - dest.write('TEST_1.0A2 { global: *; };\n') - dest.close() + Utils.writef(os.path.join(dir,'vscript'), 'TEST_1.0A2 { global: *; };\n') - bld(features='cc cshlib', + bld(features='c cshlib', source='libdir/lib1.c', target='libdir/lib1', ldflags=ldflags, name='lib1') - o = bld(features='cc cprogram', + o = bld(features='c cprogram', source='main.c', target='prog1', uselib_local='lib1') @@ -383,15 +370,13 @@ def CHECK_PERL_MANPAGE(conf, msg=None, section=None): if not os.path.exists(bdir): os.makedirs(bdir) - dest = open(os.path.join(bdir, 'Makefile.PL'), 'w') - dest.write(""" + Utils.writef(os.path.join(bdir, 'Makefile.PL'), """ use ExtUtils::MakeMaker; WriteMakefile( 'NAME' => 'WafTest', 'EXE_FILES' => [ 'WafTest' ] ); """) - dest.close() back = os.path.abspath('.') os.chdir(bdir) proc = Utils.pproc.Popen(['perl', 'Makefile.PL'], @@ -406,9 +391,7 @@ WriteMakefile( return if section: - f = open(os.path.join(bdir,'Makefile'), 'r') - man = f.read() - f.close() + man = Utils.readf(os.path.join(bdir,'Makefile')) m = re.search('MAN%sEXT\s+=\s+(\w+)' % section, man) if not m: conf.check_message_2('not found', color='YELLOW') @@ -537,53 +520,3 @@ def CHECK_STANDARD_LIBPATH(conf): conf.env.STANDARD_LIBPATH = dirlist - -waf_config_c_parse_flags = config_c.parse_flags; -def samba_config_c_parse_flags(line1, uselib, env): - # - # We do a special treatment of the rpath components - # in the linkflags line, because currently the upstream - # parse_flags function is incomplete with respect to - # treatment of the rpath. The remainder of the linkflags - # line is later passed to the original funcion. - # - lst1 = shlex.split(line1) - lst2 = [] - while lst1: - x = lst1.pop(0) - - # - # NOTE on special treatment of -Wl,-R and -Wl,-rpath: - # - # It is important to not put a library provided RPATH - # into the LINKFLAGS but in the RPATH instead, since - # the provided LINKFLAGS get prepended to our own internal - # RPATH later, and hence can potentially lead to linking - # in too old versions of our internal libs. - # - # We do this filtering here on our own because of some - # bugs in the real parse_flags() function. - # - if x == '-Wl,-rpath' or x == '-Wl,-R': - x = lst1.pop(0) - if x.startswith('-Wl,'): - rpath = x[4:] - else: - rpath = x - elif x.startswith('-Wl,-R,'): - rpath = x[7:] - elif x.startswith('-Wl,-R'): - rpath = x[6:] - elif x.startswith('-Wl,-rpath,'): - rpath = x[11:] - else: - lst2.append(x) - continue - - env.append_value('RPATH_' + uselib, rpath) - - line2 = ' '.join(lst2) - waf_config_c_parse_flags(line2, uselib, env) - - return -config_c.parse_flags = samba_config_c_parse_flags diff --git a/buildtools/wafsamba/samba_cross.py b/buildtools/wafsamba/samba_cross.py index ed3af1e..b8f2000 100644 --- a/buildtools/wafsamba/samba_cross.py +++ b/buildtools/wafsamba/samba_cross.py @@ -1,8 +1,8 @@ # functions for handling cross-compilation -import Utils, Logs, sys, os, Options, re +import os, sys, re, shlex +import Utils, Logs, Options from Configure import conf -import shlex real_Popen = None diff --git a/buildtools/wafsamba/samba_deps.py b/buildtools/wafsamba/samba_deps.py index d252dc4..f869dee 100644 --- a/buildtools/wafsamba/samba_deps.py +++ b/buildtools/wafsamba/samba_deps.py @@ -1,9 +1,14 @@ # Samba automatic dependency handling and project rules -import Build, os, sys, re, Environment, Logs, time -from samba_utils import * -from samba_autoconf import * +import os, sys, re, time + +import Build, Environment, Options, Logs, Utils +from Logs import debug +from Configure import conf + from samba_bundled import BUILTIN_LIBRARY +from samba_utils import LOCAL_CACHE, TO_LIST, get_tgt_list, unique_list, os_path_relpath +from samba_autoconf import library_flags @conf def ADD_GLOBAL_DEPENDENCY(ctx, dep): @@ -47,7 +52,7 @@ def expand_subsystem_deps(bld): # module_name = rpc_epmapper (a module within the dcerpc_server subsystem) # module = rpc_epmapper (a module object within the dcerpc_server subsystem) - subsystem = bld.name_to_obj(subsystem_name, bld.env) + subsystem = bld.get_tgen_by_name(subsystem_name) bld.ASSERT(subsystem is not None, "Unable to find subsystem %s" % subsystem_name) for d in subsystem_list[subsystem_name]: module_name = d['TARGET'] @@ -101,7 +106,7 @@ def build_dependencies(self): self.uselib = list(self.final_syslibs) self.uselib.extend(list(self.direct_syslibs)) for lib in self.final_libs: - t = self.bld.name_to_obj(lib, self.bld.env) + t = self.bld.get_tgen_by_name(lib) self.uselib.extend(list(t.final_syslibs)) self.uselib = unique_list(self.uselib) @@ -150,7 +155,7 @@ def build_includes(self): inc_abs = [] for d in inc_deps: - t = bld.name_to_obj(d, bld.env) + t = bld.get_tgen_by_name(d) bld.ASSERT(t is not None, "Unable to find dependency %s for %s" % (d, self.sname)) inclist = getattr(t, 'samba_includes_extended', [])[:] if getattr(t, 'local_include', True): @@ -214,6 +219,9 @@ def add_init_functions(self): if m is not None: modules.append(m) + if 'pyembed' in self.features: + return + sentinel = getattr(self, 'init_function_sentinel', 'NULL') targets = LOCAL_CACHE(bld, 'TARGET_TYPE') @@ -282,7 +290,7 @@ def check_duplicate_sources(bld, tgt_list): if not targets[t.sname] in [ 'LIBRARY', 'BINARY', 'PYTHON' ]: continue for obj in t.add_objects: - t2 = t.bld.name_to_obj(obj, bld.env) + t2 = t.bld.get_tgen_by_name(obj) source_set = getattr(t2, 'samba_source_set', set()) for s in source_set: if not s in subsystems: @@ -346,7 +354,7 @@ def check_group_ordering(bld, tgt_list): for t in tgt_list: tdeps = getattr(t, 'add_objects', []) + getattr(t, 'uselib_local', []) for d in tdeps: - t2 = bld.name_to_obj(d, bld.env) + t2 = bld.get_tgen_by_name(d) if t2 is None: continue map1 = grp_map[t.samba_group] @@ -429,7 +437,7 @@ def build_direct_deps(bld, tgt_list): global_deps = bld.env.GLOBAL_DEPENDENCIES global_deps_exclude = set() for dep in global_deps: - t = bld.name_to_obj(dep, bld.env) + t = bld.get_tgen_by_name(dep) for d in t.samba_deps: # prevent loops from the global dependencies list global_deps_exclude.add(d) @@ -469,7 +477,7 @@ def build_direct_deps(bld, tgt_list): implied, t.sname, targets[implied])) sys.exit(1) continue - t2 = bld.name_to_obj(d, bld.env) + t2 = bld.get_tgen_by_name(d) if t2 is None: Logs.error("no task %s of type %s in %s" % (d, targets[d], t.sname)) sys.exit(1) @@ -507,7 +515,7 @@ def indirect_libs(bld, t, chain, loops): dependency_loop(loops, t, obj) continue chain.add(obj) - t2 = bld.name_to_obj(obj, bld.env) + t2 = bld.get_tgen_by_name(obj) r2 = indirect_libs(bld, t2, chain, loops) chain.remove(obj) ret = ret.union(t2.direct_libs) @@ -518,7 +526,7 @@ def indirect_libs(bld, t, chain, loops): dependency_loop(loops, t, obj) continue chain.add(obj) - t2 = bld.name_to_obj(obj, bld.env) + t2 = bld.get_tgen_by_name(obj) r2 = indirect_libs(bld, t2, chain, loops) chain.remove(obj) ret = ret.union(t2.direct_libs) @@ -545,7 +553,7 @@ def indirect_objects(bld, t, chain, loops): dependency_loop(loops, t, lib) continue chain.add(lib) - t2 = bld.name_to_obj(lib, bld.env) + t2 = bld.get_tgen_by_name(lib) r2 = indirect_objects(bld, t2, chain, loops) chain.remove(lib) ret = ret.union(t2.direct_objects) @@ -573,7 +581,7 @@ def extended_objects(bld, t, chain): for lib in t.final_libs: if lib in chain: continue - t2 = bld.name_to_obj(lib, bld.env) + t2 = bld.get_tgen_by_name(lib) chain.add(lib) r2 = extended_objects(bld, t2, chain) chain.remove(lib) @@ -601,7 +609,7 @@ def includes_objects(bld, t, chain, inc_loops): dependency_loop(inc_loops, t, obj) continue chain.add(obj) - t2 = bld.name_to_obj(obj, bld.env) + t2 = bld.get_tgen_by_name(obj) r2 = includes_objects(bld, t2, chain, inc_loops) chain.remove(obj) ret = ret.union(t2.direct_objects) @@ -612,7 +620,7 @@ def includes_objects(bld, t, chain, inc_loops): dependency_loop(inc_loops, t, lib) continue chain.add(lib) - t2 = bld.name_to_obj(lib, bld.env) + t2 = bld.get_tgen_by_name(lib) if t2 is None: targets = LOCAL_CACHE(bld, 'TARGET_TYPE') Logs.error('Target %s of type %s not found in direct_libs for %s' % ( @@ -665,7 +673,7 @@ def break_dependency_loops(bld, tgt_list): # expand indirect subsystem and library loops for loop in loops.copy(): - t = bld.name_to_obj(loop, bld.env) + t = bld.get_tgen_by_name(loop) if t.samba_type in ['SUBSYSTEM']: loops[loop] = loops[loop].union(t.indirect_objects) loops[loop] = loops[loop].union(t.direct_objects) @@ -677,7 +685,7 @@ def break_dependency_loops(bld, tgt_list): # expand indirect includes loops for loop in inc_loops.copy(): - t = bld.name_to_obj(loop, bld.env) + t = bld.get_tgen_by_name(loop) inc_loops[loop] = inc_loops[loop].union(t.includes_objects) if loop in inc_loops[loop]: inc_loops[loop].remove(loop) @@ -723,7 +731,7 @@ def reduce_objects(bld, tgt_list): # if we will indirectly link to a target then we don't need it new = t.final_objects.copy() for l in t.final_libs: - t2 = bld.name_to_obj(l, bld.env) + t2 = bld.get_tgen_by_name(l) t2_obj = extended_objects(bld, t2, set()) dup = new.intersection(t2_obj) if t.sname in rely_on: @@ -743,7 +751,7 @@ def reduce_objects(bld, tgt_list): # add back in any objects that were relied upon by the reduction rules for r in rely_on: - t = bld.name_to_obj(r, bld.env) + t = bld.get_tgen_by_name(r) t.final_objects = t.final_objects.union(rely_on[r]) return True @@ -752,7 +760,7 @@ def reduce_objects(bld, tgt_list): def show_library_loop(bld, lib1, lib2, path, seen): '''show the detailed path of a library loop between lib1 and lib2''' - t = bld.name_to_obj(lib1, bld.env) + t = bld.get_tgen_by_name(lib1) if not lib2 in getattr(t, 'final_libs', set()): return @@ -791,7 +799,7 @@ def calculate_final_deps(bld, tgt_list, loops): # replace lib deps with objlist deps for l in t.final_libs: objname = l + '.objlist' - t2 = bld.name_to_obj(objname, bld.env) + t2 = bld.get_tgen_by_name(objname) if t2 is None: Logs.error('ERROR: subsystem %s not found' % objname) sys.exit(1) @@ -807,7 +815,7 @@ def calculate_final_deps(bld, tgt_list, loops): objname = module_name else: continue - t2 = bld.name_to_obj(objname, bld.env) + t2 = bld.get_tgen_by_name(objname) if t2 is None: Logs.error('ERROR: subsystem %s not found' % objname) sys.exit(1) @@ -819,7 +827,7 @@ def calculate_final_deps(bld, tgt_list, loops): for t in tgt_list: if t.samba_type in ['LIBRARY', 'PYTHON']: for l in t.final_libs.copy(): - t2 = bld.name_to_obj(l, bld.env) + t2 = bld.get_tgen_by_name(l) if t.sname in t2.final_libs: if getattr(bld.env, "ALLOW_CIRCULAR_LIB_DEPENDENCIES", False): # we could break this in either direction. If one of the libraries @@ -853,7 +861,7 @@ def calculate_final_deps(bld, tgt_list, loops): diff.remove(t.sname) # make sure we don't recreate the loop again! for d in diff.copy(): - t2 = bld.name_to_obj(d, bld.env) + t2 = bld.get_tgen_by_name(d) if t2.samba_type == 'LIBRARY': if t.sname in t2.final_libs: debug('deps: removing expansion %s from %s', d, t.sname) @@ -878,12 +886,12 @@ def calculate_final_deps(bld, tgt_list, loops): continue syslibs = set() for d in t.final_objects: - t2 = bld.name_to_obj(d, bld.env) + t2 = bld.get_tgen_by_name(d) syslibs = syslibs.union(t2.direct_syslibs) # this adds the indirect syslibs as well, which may not be needed # depending on the linker flags for d in t.final_libs: - t2 = bld.name_to_obj(d, bld.env) + t2 = bld.get_tgen_by_name(d) syslibs = syslibs.union(t2.direct_syslibs) t.final_syslibs = syslibs @@ -893,7 +901,7 @@ def calculate_final_deps(bld, tgt_list, loops): for t in tgt_list: if t.samba_type in ['LIBRARY', 'PYTHON']: for l in t.final_libs.copy(): - t2 = bld.name_to_obj(l, bld.env) + t2 = bld.get_tgen_by_name(l) if t.sname in t2.final_libs: Logs.error('ERROR: Unresolved library loop %s from %s' % (t.sname, t2.sname)) lib_loop_error = True @@ -909,7 +917,7 @@ def show_dependencies(bld, target, seen): if target in seen: return - t = bld.name_to_obj(target, bld.env) + t = bld.get_tgen_by_name(target) if t is None: Logs.error("ERROR: Unable to find target '%s'" % target) sys.exit(1) @@ -938,7 +946,7 @@ def show_object_duplicates(bld, tgt_list): if not targets[t.sname] in [ 'LIBRARY', 'PYTHON' ]: continue for n in getattr(t, 'final_objects', set()): - t2 = bld.name_to_obj(n, bld.env) + t2 = bld.get_tgen_by_name(n) if not n in used_by: used_by[n] = set() used_by[n].add(t.sname) diff --git a/buildtools/wafsamba/samba_dist.py b/buildtools/wafsamba/samba_dist.py index 654a168..dbcb02a 100644 --- a/buildtools/wafsamba/samba_dist.py +++ b/buildtools/wafsamba/samba_dist.py @@ -1,8 +1,10 @@ # customised version of 'waf dist' for Samba tools # uses git ls-files to get file lists -import Utils, os, sys, tarfile, stat, Scripting, Logs, Options -from samba_utils import * +import os, sys, tarfile +import Utils, Scripting, Logs, Options +from Configure import conf +from samba_utils import os_path_relpath dist_dirs = None dist_files = None diff --git a/buildtools/wafsamba/samba_headers.py b/buildtools/wafsamba/samba_headers.py index 50ccad7..0a80082 100644 --- a/buildtools/wafsamba/samba_headers.py +++ b/buildtools/wafsamba/samba_headers.py @@ -1,7 +1,8 @@ # specialist handling of header files for Samba -import Build, re, Task, TaskGen, shutil, sys, Logs -from samba_utils import * +import os, re, sys, fnmatch +import Build, Logs, Utils +from samba_utils import TO_LIST, os_path_relpath def header_install_path(header, header_path): diff --git a/buildtools/wafsamba/samba_install.py b/buildtools/wafsamba/samba_install.py index 3d0c23a..5f399f9 100644 --- a/buildtools/wafsamba/samba_install.py +++ b/buildtools/wafsamba/samba_install.py @@ -3,9 +3,10 @@ # with all the configure options that affect rpath and shared # library use -import Options +import os +import Options, Utils from TaskGen import feature, before, after -from samba_utils import * +from samba_utils import LIB_PATH, MODE_755, install_rpath, build_rpath @feature('install_bin') @after('apply_core') @@ -224,7 +225,6 @@ def symlink_bin(self): if self.target.endswith('.inst'): return - blddir = os.path.dirname(self.bld.srcnode.abspath(self.bld.env)) if not self.link_task.outputs or not self.link_task.outputs[0]: raise Utils.WafError('no outputs found for %s in symlink_bin' % self.name) binpath = self.link_task.outputs[0].abspath(self.env) diff --git a/buildtools/wafsamba/samba_optimisation.py b/buildtools/wafsamba/samba_optimisation.py index 51d514e..9d4fad1 100644 --- a/buildtools/wafsamba/samba_optimisation.py +++ b/buildtools/wafsamba/samba_optimisation.py @@ -11,7 +11,7 @@ import Build, Utils, Node from TaskGen import feature, after, before import preproc -@feature('cc', 'cxx') +@feature('c', 'cc', 'cxx') @after('apply_type_vars', 'apply_lib_vars', 'apply_core') def apply_incpaths(self): lst = [] @@ -59,7 +59,7 @@ def apply_incpaths(self): if node: self.env.append_value('INC_PATHS', node) -@feature('cc') +@feature('c', 'cc') @after('apply_incpaths') def apply_obj_vars_cc(self): """after apply_incpaths for INC_PATHS""" @@ -165,7 +165,7 @@ def is_this_a_static_lib(self, name): try: return cache[name] except KeyError: - ret = cache[name] = 'cstaticlib' in self.bld.name_to_obj(name, self.env).features + ret = cache[name] = 'cstaticlib' in self.bld.get_tgen_by_name(name).features return ret TaskGen.task_gen.is_this_a_static_lib = is_this_a_static_lib @@ -187,7 +187,7 @@ def shared_ancestors(self): return ret TaskGen.task_gen.shared_ancestors = shared_ancestors -@feature('cc', 'cxx') +@feature('c', 'cc', 'cxx') @after('apply_link', 'init_cc', 'init_cxx', 'apply_core') def apply_lib_vars(self): """after apply_link because of 'link_task' @@ -215,7 +215,7 @@ def apply_lib_vars(self): if lib_name in seen: continue - y = self.name_to_obj(lib_name) + y = self.get_tgen_by_name(lib_name) if not y: raise Utils.WafError('object %r was not found in uselib_local (required by %r)' % (lib_name, self.name)) y.post() diff --git a/buildtools/wafsamba/samba_patterns.py b/buildtools/wafsamba/samba_patterns.py index 0469992..9c6d499 100644 --- a/buildtools/wafsamba/samba_patterns.py +++ b/buildtools/wafsamba/samba_patterns.py @@ -1,21 +1,16 @@ # a waf tool to add extension based build patterns for Samba -import Task -from TaskGen import extension -from samba_utils import * +import Build from wafsamba import samba_version_file def write_version_header(task): '''print version.h contents''' src = task.inputs[0].srcpath(task.env) - tgt = task.outputs[0].bldpath(task.env) version = samba_version_file(src, task.env.srcdir, env=task.env, is_install=task.env.is_install) string = str(version) - f = open(tgt, 'w') - s = f.write(string) - f.close() + task.outputs[0].write(string) return 0 diff --git a/buildtools/wafsamba/samba_perl.py b/buildtools/wafsamba/samba_perl.py index 3909aba..c07387a 100644 --- a/buildtools/wafsamba/samba_perl.py +++ b/buildtools/wafsamba/samba_perl.py @@ -1,5 +1,4 @@ -import Build -from samba_utils import * +import Utils from Configure import conf done = {} diff --git a/buildtools/wafsamba/samba_pidl.py b/buildtools/wafsamba/samba_pidl.py index 110b15e..9651e4d 100644 --- a/buildtools/wafsamba/samba_pidl.py +++ b/buildtools/wafsamba/samba_pidl.py @@ -1,8 +1,9 @@ # waf build tool for building IDL files with pidl -from TaskGen import before -import Build, os, sys, Logs -from samba_utils import * +import os +import Build +from TaskGen import feature, before +from samba_utils import SET_TARGET_TYPE, TO_LIST, LOCAL_CACHE def SAMBA_PIDL(bld, pname, source, options='', @@ -112,13 +113,12 @@ Build.BuildContext.SAMBA_PIDL_LIST = SAMBA_PIDL_LIST ################################################################# # the rule for generating the NDR tables -from TaskGen import feature, before @feature('collect') @before('exec_rule') def collect(self): pidl_headers = LOCAL_CACHE(self.bld, 'PIDL_HEADERS') for (name, hd) in pidl_headers.items(): - y = self.bld.name_to_obj(name, self.env) + 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: @@ -128,7 +128,6 @@ def collect(self): def SAMBA_PIDL_TABLES(bld, name, target): '''generate the pidl NDR tables file''' - headers = bld.env.PIDL_HEADERS bld.SET_BUILD_GROUP('main') t = bld( features = 'collect', diff --git a/buildtools/wafsamba/samba_python.py b/buildtools/wafsamba/samba_python.py index a8f780f..6f94350 100644 --- a/buildtools/wafsamba/samba_python.py +++ b/buildtools/wafsamba/samba_python.py @@ -1,9 +1,7 @@ # waf build tool for building IDL files with pidl -import Build -from samba_utils import * -from samba_autoconf import * - +import os +import Build, Logs, Utils from Configure import conf @conf diff --git a/buildtools/wafsamba/samba_third_party.py b/buildtools/wafsamba/samba_third_party.py index 46a1b94..8cfa4df 100644 --- a/buildtools/wafsamba/samba_third_party.py +++ b/buildtools/wafsamba/samba_third_party.py @@ -1,8 +1,8 @@ # functions to support third party libraries +import os +import Utils, Build from Configure import conf -import sys, Logs, os -from samba_bundled import * @conf def CHECK_FOR_THIRD_PARTY(conf): diff --git a/buildtools/wafsamba/samba_utils.py b/buildtools/wafsamba/samba_utils.py index 540fe44..36d3929 100644 --- a/buildtools/wafsamba/samba_utils.py +++ b/buildtools/wafsamba/samba_utils.py @@ -1,11 +1,11 @@ # a waf tool to add autoconf-like macros to the configure section # and for SAMBA_ macros for building libraries, binaries etc -import Build, os, sys, Options, Utils, Task, re, fnmatch, Logs +import os, sys, re, fnmatch, shlex +import Build, Options, Utils, Task, Logs, Configure from TaskGen import feature, before from Configure import conf, ConfigurationContext from Logs import debug -import shlex # TODO: make this a --option LIB_PATH="shared" @@ -66,7 +66,7 @@ def ADD_LD_LIBRARY_PATH(path): def needs_private_lib(bld, target): '''return True if a target links to a private library''' for lib in getattr(target, "final_libs", []): - t = bld.name_to_obj(lib, bld.env) + t = bld.get_tgen_by_name(lib) if t and getattr(t, 'private_library', False): return True return False @@ -140,7 +140,6 @@ def exec_command(self, cmd, **kw): '''this overrides the 'waf -v' debug output to be in a nice unix like format instead of a python list. Thanks to ita on #waf for this''' - import Utils, Logs _cmd = cmd if isinstance(cmd, list): _cmd = ' '.join(cmd) @@ -164,7 +163,7 @@ def ADD_COMMAND(opt, name, function): Options.Handler.ADD_COMMAND = ADD_COMMAND -@feature('cc', 'cshlib', 'cprogram') +@feature('c', 'cc', 'cshlib', 'cprogram') @before('apply_core','exec_rule') def process_depends_on(self): '''The new depends_on attribute for build rules @@ -173,7 +172,7 @@ def process_depends_on(self): if getattr(self , 'depends_on', None): lst = self.to_list(self.depends_on) for x in lst: - y = self.bld.name_to_obj(x, self.env) + y = self.bld.get_tgen_by_name(x) self.bld.ASSERT(y is not None, "Failed to find dependency %s of %s" % (x, self.name)) y.post() if getattr(y, 'more_includes', None): @@ -644,7 +643,7 @@ def get_tgt_list(bld): type = targets[tgt] if not type in ['SUBSYSTEM', 'MODULE', 'BINARY', 'LIBRARY', 'ASN1', 'PYTHON']: continue - t = bld.name_to_obj(tgt, bld.env) + t = bld.get_tgen_by_name(tgt) if t is None: Logs.error("Target %s of type %s has no task generator" % (tgt, type)) sys.exit(1) @@ -657,11 +656,10 @@ def PROCESS_SEPARATE_RULE(self, rule): You should have file named wscript__rule in the current directory where stage is either 'configure' or 'build' ''' - ctxclass = self.__class__.__name__ stage = '' - if ctxclass == 'ConfigurationContext': + if isinstance(self, Configure.ConfigurationContext): stage = 'configure' - elif ctxclass == 'BuildContext': + elif isinstance(self, Build.BuildContext): stage = 'build' file_path = os.path.join(self.curdir, WSCRIPT_FILE+'_'+stage+'_'+rule) txt = load_file(file_path) diff --git a/buildtools/wafsamba/samba_version.py b/buildtools/wafsamba/samba_version.py index bb0be96..950a855 100644 --- a/buildtools/wafsamba/samba_version.py +++ b/buildtools/wafsamba/samba_version.py @@ -42,12 +42,10 @@ def git_version_summary(path, env=None): def distversion_version_summary(path): #get version from .distversion file - f = open(path + '/.distversion', 'r') suffix = None fields = {} - for line in f: - line = line.strip() + for line in Utils.readf(path + '/.distversion').splitlines(): if line == '': continue if line.startswith("#"): @@ -64,7 +62,6 @@ def distversion_version_summary(path): except: print("Failed to parse line %s from .distversion file." % (line)) raise - f.close() if "COMMIT_TIME" in fields: fields["COMMIT_TIME"] = int(fields["COMMIT_TIME"]) diff --git a/buildtools/wafsamba/samba_wildcard.py b/buildtools/wafsamba/samba_wildcard.py index 84503b8..3d87481 100644 --- a/buildtools/wafsamba/samba_wildcard.py +++ b/buildtools/wafsamba/samba_wildcard.py @@ -1,9 +1,9 @@ # based on playground/evil in the waf svn tree -import os, datetime -import Scripting, Utils, Options, Logs, Environment, fnmatch -from Constants import * -from samba_utils import * +import os, datetime, fnmatch +import Scripting, Utils, Options, Logs, Environment +from Constants import SRCDIR, BLDDIR +from samba_utils import LOCAL_CACHE, os_path_relpath def run_task(t, k): '''run a single build task''' diff --git a/buildtools/wafsamba/symbols.py b/buildtools/wafsamba/symbols.py index daa18b9..7ff4bac 100644 --- a/buildtools/wafsamba/symbols.py +++ b/buildtools/wafsamba/symbols.py @@ -1,9 +1,10 @@ # a waf tool to extract symbols from object files or libraries # using nm, producing a set of exposed defined/undefined symbols -import Utils, Build, subprocess, Logs, re -from samba_wildcard import fake_build_environment -from samba_utils import * +import os, re, subprocess +import Utils, Build, Options, Logs +from Logs import debug +from samba_utils import TO_LIST, LOCAL_CACHE, get_tgt_list, os_path_relpath # these are the data structures used in symbols.py: # @@ -251,7 +252,7 @@ def build_symbol_sets(bld, tgt_list): bld.env.public_symbols[name] = t.public_symbols if t.samba_type == 'LIBRARY': for dep in t.add_objects: - t2 = bld.name_to_obj(dep, bld.env) + t2 = bld.get_tgen_by_name(dep) bld.ASSERT(t2 is not None, "Library '%s' has unknown dependency '%s'" % (name, dep)) bld.env.public_symbols[name] = bld.env.public_symbols[name].union(t2.public_symbols) @@ -264,7 +265,7 @@ def build_symbol_sets(bld, tgt_list): bld.env.used_symbols[name] = t.used_symbols if t.samba_type == 'LIBRARY': for dep in t.add_objects: - t2 = bld.name_to_obj(dep, bld.env) + t2 = bld.get_tgen_by_name(dep) bld.ASSERT(t2 is not None, "Library '%s' has unknown dependency '%s'" % (name, dep)) bld.env.used_symbols[name] = bld.env.used_symbols[name].union(t2.used_symbols) @@ -362,7 +363,7 @@ def build_autodeps(bld, t): if targets[depname[0]] in [ 'SYSLIB' ]: deps.add(depname[0]) continue - t2 = bld.name_to_obj(depname[0], bld.env) + t2 = bld.get_tgen_by_name(depname[0]) if len(t2.in_library) != 1: deps.add(depname[0]) continue @@ -385,7 +386,7 @@ def build_library_names(bld, tgt_list): for t in tgt_list: if t.samba_type in [ 'LIBRARY' ]: for obj in t.samba_deps_extended: - t2 = bld.name_to_obj(obj, bld.env) + t2 = bld.get_tgen_by_name(obj) if t2 and t2.samba_type in [ 'SUBSYSTEM', 'ASN1' ]: if not t.sname in t2.in_library: t2.in_library.append(t.sname) @@ -402,7 +403,7 @@ def check_library_deps(bld, t): Logs.warn("WARNING: Target '%s' in multiple libraries: %s" % (t.sname, t.in_library)) for dep in t.autodeps: - t2 = bld.name_to_obj(dep, bld.env) + t2 = bld.get_tgen_by_name(dep) if t2 is None: continue for dep2 in t2.autodeps: @@ -435,7 +436,7 @@ def check_syslib_collisions(bld, tgt_list): def check_dependencies(bld, t): '''check for depenencies that should be changed''' - if bld.name_to_obj(t.sname + ".objlist", bld.env): + if bld.get_tgen_by_name(t.sname + ".objlist"): return targets = LOCAL_CACHE(bld, 'TARGET_TYPE') @@ -475,7 +476,7 @@ def check_dependencies(bld, t): def check_syslib_dependencies(bld, t): '''check for syslib depenencies''' - if bld.name_to_obj(t.sname + ".objlist", bld.env): + if bld.get_tgen_by_name(t.sname + ".objlist"): return sname = real_name(t.sname) diff --git a/buildtools/wafsamba/wafsamba.py b/buildtools/wafsamba/wafsamba.py index c27241e..318dabf 100644 --- a/buildtools/wafsamba/wafsamba.py +++ b/buildtools/wafsamba/wafsamba.py @@ -20,6 +20,7 @@ from samba_perl import * from samba_deps import * from samba_bundled import * from samba_third_party import * +import samba_cross import samba_install import samba_conftests import samba_abi @@ -95,9 +96,7 @@ Build.BuildContext.ADD_INIT_FUNCTION = ADD_INIT_FUNCTION def generate_empty_file(task): - target_fname = installed_location=task.outputs[0].bldpath(task.env) - target_file = open(installed_location, 'w') - target_file.close() + task.outputs[0].write('') return 0 ################################################################# @@ -245,7 +244,7 @@ def SAMBA_LIBRARY(bld, libname, source, if bld.env['ENABLE_RELRO'] is True: ldflags.extend(TO_LIST('-Wl,-z,relro,-z,now')) - features = 'cc cshlib symlink_lib install_lib' + features = 'c cshlib symlink_lib install_lib' if pyext: features += ' pyext' if pyembed: @@ -254,6 +253,15 @@ def SAMBA_LIBRARY(bld, libname, source, if abi_directory: features += ' abi_check' + if pyembed and bld.env['PYTHON_SO_ABI_FLAG']: + # For ABI checking, we don't care about the exact Python version. + # Replace the Python ABI tag (e.g. ".cpython-35m") by a generic ".py3" + abi_flag = bld.env['PYTHON_SO_ABI_FLAG'] + replacement = '.py%s' % bld.env['PYTHON_VERSION'].split('.')[0] + version_libname = libname.replace(abi_flag, replacement) + else: + version_libname = libname + vscript = None if bld.env.HAVE_LD_VERSION_SCRIPT: if private_library: @@ -264,7 +272,7 @@ def SAMBA_LIBRARY(bld, libname, source, version = None if version: vscript = "%s.vscript" % libname - bld.ABI_VSCRIPT(libname, abi_directory, version, vscript, + bld.ABI_VSCRIPT(version_libname, abi_directory, version, vscript, abi_match) fullname = apply_pattern(bundled_name, bld.env.shlib_PATTERN) fullpath = bld.path.find_or_declare(fullname) @@ -290,6 +298,7 @@ def SAMBA_LIBRARY(bld, libname, source, samba_deps = deps, samba_includes = includes, version_script = vscript, + version_libname = version_libname, local_include = local_include, global_include = global_include, vnum = vnum, @@ -356,7 +365,7 @@ def SAMBA_BINARY(bld, binname, source, if not SET_TARGET_TYPE(bld, binname, 'BINARY'): return - features = 'cc cprogram symlink_bin install_bin' + features = 'c cprogram symlink_bin install_bin' if pyembed: features += ' pyembed' @@ -580,7 +589,7 @@ def SAMBA_SUBSYSTEM(bld, modname, source, bld.SET_BUILD_GROUP(group) - features = 'cc' + features = 'c' if pyext: features += ' pyext' if pyembed: diff --git a/buildtools/wafsamba/wscript b/buildtools/wafsamba/wscript index d6bb688..69c556c 100755 --- a/buildtools/wafsamba/wscript +++ b/buildtools/wafsamba/wscript @@ -2,9 +2,9 @@ # this is a base set of waf rules that everything else pulls in first -import sys, wafsamba, Configure, Logs -import Options, os, preproc -from samba_utils import * +import os, sys +import wafsamba, Configure, Logs, Options, Utils +from samba_utils import os_path_relpath from optparse import SUPPRESS_HELP # this forces configure to be re-run if any of the configure @@ -78,9 +78,6 @@ def set_options(opt): help='additional directory to search for libiconv', action='store', dest='iconv_open', default='/usr/local', match = ['Checking for library iconv', 'Checking for iconv_open', 'Checking for header iconv.h']) - opt.add_option('--with-gettext', - help='additional directory to search for gettext', - action='store', dest='gettext_location', default='None') opt.add_option('--without-gettext', help=("Disable use of gettext"), action="store_true", dest='disable_gettext', default=False) @@ -99,9 +96,13 @@ def set_options(opt): gr.add_option('--enable-developer', help=("Turn on developer warnings and debugging"), action="store_true", dest='developer', default=False) + def picky_developer_callback(option, opt_str, value, parser): + parser.values.developer = True + parser.values.picky_developer = True gr.add_option('--picky-developer', help=("Treat all warnings as errors (enable -Werror)"), - action="store_true", dest='picky_developer', default=False) + action="callback", callback=picky_developer_callback, + dest='picky_developer', default=False) gr.add_option('--fatal-errors', help=("Stop compilation on first error (enable -Wfatal-errors)"), action="store_true", dest='fatal_errors', default=False) @@ -241,7 +242,7 @@ def configure(conf): cc.run = Task.compile_fun_noshell('cc', '${CC} ${CCFLAGS} ${CPPFLAGS} ${_CCINCFLAGS} ${_CCDEFFLAGS} ${CC_SRC_F}${SRC} ${CC_TGT_F}${TGT[0].abspath(env)}')[0] try: try: - conf.check(features='cc testd', fragment='int main() {return 0;}\n', ccflags=['-MD'], mandatory=True, msg='Check for -MD') + conf.check(features='c testd', fragment='int main() {return 0;}\n', ccflags=['-MD'], mandatory=True, msg='Check for -MD') except: pass else: @@ -361,6 +362,40 @@ def configure(conf): cflags=conf.env.VISIBILITY_CFLAGS, define='HAVE_VISIBILITY_ATTR', addmain=False) + # check HAVE_CONSTRUCTOR_ATTRIBUTE + conf.CHECK_CODE(''' + void test_constructor_attribute(void) __attribute__ ((constructor)); + + void test_constructor_attribute(void) + { + return; + } + + int main(void) { + return 0; + } + ''', + 'HAVE_CONSTRUCTOR_ATTRIBUTE', + addmain=False, + msg='Checking for library constructor support') + + # check HAVE_DESTRUCTOR_ATTRIBUTE + conf.CHECK_CODE(''' + void test_destructor_attribute(void) __attribute__ ((destructor)); + + void test_destructor_attribute(void) + { + return; + } + + int main(void) { + return 0; + } + ''', + 'HAVE_DESTRUCTOR_ATTRIBUTE', + addmain=False, + msg='Checking for library destructor support') + if sys.platform.startswith('aix'): conf.DEFINE('_ALL_SOURCE', 1, add_to_cflags=True) # Might not be needed if ALL_SOURCE is defined diff --git a/lib/replace/replace.c b/lib/replace/replace.c index dccf514..b5d7f11 100644 --- a/lib/replace/replace.c +++ b/lib/replace/replace.c @@ -475,6 +475,26 @@ char *rep_strcasestr(const char *haystack, const char *needle) } #endif +#ifndef HAVE_STRSEP +char *rep_strsep(char **pps, const char *delim) +{ + char *ret = *pps; + char *p = *pps; + + if (p == NULL) { + return NULL; + } + p += strcspn(p, delim); + if (*p == '\0') { + *pps = NULL; + } else { + *p = '\0'; + *pps = p + 1; + } + return ret; +} +#endif + #ifndef HAVE_STRTOK_R /* based on GLIBC version, copyright Free Software Foundation */ char *rep_strtok_r(char *s, const char *delim, char **save_ptr) @@ -518,8 +538,10 @@ long long int rep_strtoll(const char *str, char **endptr, int base) } #else #ifdef HAVE_BSD_STRTOLL +#undef strtoll long long int rep_strtoll(const char *str, char **endptr, int base) { + int saved_errno = errno; long long int nb = strtoll(str, endptr, base); /* With glibc EINVAL is only returned if base is not ok */ if (errno == EINVAL) { @@ -528,7 +550,7 @@ long long int rep_strtoll(const char *str, char **endptr, int base) * able to make the convertion. * Let's reset errno. */ - errno = 0; + errno = saved_errno; } } return nb; @@ -552,25 +574,23 @@ unsigned long long int rep_strtoull(const char *str, char **endptr, int base) } #else #ifdef HAVE_BSD_STRTOLL -#ifdef HAVE_STRTOUQ +#undef strtoull unsigned long long int rep_strtoull(const char *str, char **endptr, int base) { - unsigned long long int nb = strtouq(str, endptr, base); - /* In linux EINVAL is only returned if base is not ok */ + int saved_errno = errno; + unsigned long long int nb = strtoull(str, endptr, base); + /* With glibc EINVAL is only returned if base is not ok */ if (errno == EINVAL) { if (base == 0 || (base >1 && base <37)) { /* Base was ok so it's because we were not * able to make the convertion. * Let's reset errno. */ - errno = 0; + errno = saved_errno; } } return nb; } -#else -#error "You need the strtouq function" -#endif /* HAVE_STRTOUQ */ #endif /* HAVE_BSD_STRTOLL */ #endif /* HAVE_STRTOULL */ @@ -808,7 +828,7 @@ int rep_clock_gettime(clockid_t clk_id, struct timespec *tp) struct timeval tval; switch (clk_id) { case 0: /* CLOCK_REALTIME :*/ -#ifdef HAVE_GETTIMEOFDAY_TZ +#if defined(HAVE_GETTIMEOFDAY_TZ) || defined(HAVE_GETTIMEOFDAY_TZ_VOID) gettimeofday(&tval,NULL); #else gettimeofday(&tval); diff --git a/lib/replace/replace.h b/lib/replace/replace.h index 3ff4e36..c764d06 100644 --- a/lib/replace/replace.h +++ b/lib/replace/replace.h @@ -349,6 +349,11 @@ void rep_setlinebuf(FILE *); char *rep_strcasestr(const char *haystack, const char *needle); #endif +#ifndef HAVE_STRSEP +#define strsep rep_strsep +char *rep_strsep(char **pps, const char *delim); +#endif + #ifndef HAVE_STRTOK_R #define strtok_r rep_strtok_r char *rep_strtok_r(char *s, const char *delim, char **save_ptr); diff --git a/lib/replace/wscript b/lib/replace/wscript index 516db2f..a1c2094 100644 --- a/lib/replace/wscript +++ b/lib/replace/wscript @@ -240,7 +240,7 @@ def configure(conf): conf.CHECK_FUNCS('lstat getpgrp utime utimes setuid seteuid setreuid setresuid setgid setegid') conf.CHECK_FUNCS('setregid setresgid chroot strerror vsyslog setlinebuf mktime') conf.CHECK_FUNCS('ftruncate chsize rename waitpid wait4') - conf.CHECK_FUNCS('initgroups pread pwrite strndup strcasestr') + conf.CHECK_FUNCS('initgroups pread pwrite strndup strcasestr strsep') conf.CHECK_FUNCS('strtok_r mkdtemp dup2 dprintf vdprintf isatty chown lchown') conf.CHECK_FUNCS('link readlink symlink realpath snprintf vsnprintf') conf.CHECK_FUNCS('asprintf vasprintf setenv unsetenv strnlen strtoull __strtoull') @@ -361,13 +361,6 @@ removeea setea # try to find libintl (if --without-gettext is not given) conf.env.intl_libs='' if not Options.options.disable_gettext: - # any extra path given to look at? - if not Options.options.gettext_location == 'None': - conf.env['CFLAGS'].extend(["-I%s" % Options.options.gettext_location]); - conf.env['LDFLAGS'].extend(["-L%s" % Options.options.gettext_location]); - else: - conf.env['CFLAGS'].extend(["-I/usr/local"]); - conf.env['LDFLAGS'].extend(["-L/usr/local"]); conf.CHECK_HEADERS('libintl.h') conf.CHECK_LIB('intl') conf.CHECK_DECLS('dgettext gettext bindtextdomain textdomain bind_textdomain_codeset', headers="libintl.h") @@ -407,10 +400,6 @@ removeea setea conf.undefine('HAVE_DGETTEXT') conf.undefine('HAVE_DECL_DGETTEXT') - # did the user insist on gettext (--with-gettext)? - if Options.options.gettext_location != 'None' and (not conf.env['HAVE_GETTEXT'] or not conf.env['HAVE_DGETTEXT']): - conf.fatal('library gettext not found at specified location') - conf.CHECK_FUNCS_IN('pthread_create', 'pthread', checklibc=True, headers='pthread.h') PTHREAD_CFLAGS='error' @@ -502,7 +491,14 @@ removeea setea addmain=False, msg='Checking for working strptime') - conf.CHECK_CODE('gettimeofday(NULL, NULL)', 'HAVE_GETTIMEOFDAY_TZ', execute=False) + conf.CHECK_C_PROTOTYPE('gettimeofday', + 'int gettimeofday(struct timeval *tv, struct timezone *tz)', + define='HAVE_GETTIMEOFDAY_TZ', headers='sys/time.h') + + conf.CHECK_C_PROTOTYPE('gettimeofday', + 'int gettimeofday(struct timeval *tv, void *tz)', + define='HAVE_GETTIMEOFDAY_TZ_VOID', + headers='sys/time.h') conf.CHECK_CODE('#include "test/snprintf.c"', define="HAVE_C99_VSNPRINTF", @@ -630,7 +626,7 @@ REPLACEMENT_FUNCTIONS = { 'memmove', 'strdup', 'setlinebuf', 'vsyslog', 'strnlen', 'strndup', 'waitpid', 'seteuid', 'setegid', 'chroot', 'mkstemp', 'mkdtemp', 'pread', 'pwrite', 'strcasestr', - 'strtok_r', 'strtoll', 'strtoull', 'setenv', 'unsetenv', + 'strsep', 'strtok_r', 'strtoll', 'strtoull', 'setenv', 'unsetenv', 'utime', 'utimes', 'dup2', 'chown', 'link', 'readlink', 'symlink', 'lchown', 'realpath', 'memmem', 'vdprintf', 'dprintf', 'get_current_dir_name', diff --git a/talloc.c b/talloc.c index c10fd53..90b9d96 100644 --- a/talloc.c +++ b/talloc.c @@ -33,6 +33,10 @@ #include "replace.h" #include "talloc.h" +#ifdef HAVE_SYS_AUXV_H +#include +#endif + #ifdef TALLOC_BUILD_VERSION_MAJOR #if (TALLOC_VERSION_MAJOR != TALLOC_BUILD_VERSION_MAJOR) #error "TALLOC_VERSION_MAJOR != TALLOC_BUILD_VERSION_MAJOR" @@ -60,20 +64,26 @@ #define MAX_TALLOC_SIZE 0x10000000 -#define TALLOC_MAGIC_BASE 0xe814ec70 -#define TALLOC_MAGIC ( \ - TALLOC_MAGIC_BASE + \ - (TALLOC_VERSION_MAJOR << 12) + \ - (TALLOC_VERSION_MINOR << 4) \ -) #define TALLOC_FLAG_FREE 0x01 #define TALLOC_FLAG_LOOP 0x02 #define TALLOC_FLAG_POOL 0x04 /* This is a talloc pool */ #define TALLOC_FLAG_POOLMEM 0x08 /* This is allocated in a pool */ +/* + * Bits above this are random, used to make it harder to fake talloc + * headers during an attack. Try not to change this without good reason. + */ +#define TALLOC_FLAG_MASK 0x0F + #define TALLOC_MAGIC_REFERENCE ((const char *)1) +#define TALLOC_MAGIC_BASE 0xe814ec70 +static unsigned int talloc_magic = ( + TALLOC_MAGIC_BASE + + (TALLOC_VERSION_MAJOR << 12) + + (TALLOC_VERSION_MINOR << 4)); + /* by default we abort when given a bad pointer (such as when talloc_free() is called on a pointer that came from malloc() */ #ifndef TALLOC_ABORT @@ -249,13 +259,13 @@ typedef int (*talloc_destructor_t)(void *); struct talloc_pool_hdr; struct talloc_chunk { + unsigned flags; struct talloc_chunk *next, *prev; struct talloc_chunk *parent, *child; struct talloc_reference_handle *refs; talloc_destructor_t destructor; const char *name; size_t size; - unsigned flags; /* * limit semantics: @@ -290,6 +300,11 @@ _PUBLIC_ int talloc_version_minor(void) return TALLOC_VERSION_MINOR; } +_PUBLIC_ int talloc_test_get_magic(void) +{ + return talloc_magic; +} + static void (*talloc_log_fn)(const char *message); _PUBLIC_ void talloc_set_log_fn(void (*log_fn)(const char *message)) @@ -297,6 +312,50 @@ _PUBLIC_ void talloc_set_log_fn(void (*log_fn)(const char *message)) talloc_log_fn = log_fn; } +#ifdef HAVE_CONSTRUCTOR_ATTRIBUTE +void talloc_lib_init(void) __attribute__((constructor)); +void talloc_lib_init(void) +{ + uint32_t random_value; +#if defined(HAVE_GETAUXVAL) && defined(AT_RANDOM) + uint8_t *p; + /* + * Use the kernel-provided random values used for + * ASLR. This won't change per-exec, which is ideal for us + */ + p = (uint8_t *) getauxval(AT_RANDOM); + if (p) { + /* + * We get 16 bytes from getauxval. By calling rand(), + * a totally insecure PRNG, but one that will + * deterministically have a different value when called + * twice, we ensure that if two talloc-like libraries + * are somehow loaded in the same address space, that + * because we choose different bytes, we will keep the + * protection against collision of multiple talloc + * libs. + * + * This protection is important because the effects of + * passing a talloc pointer from one to the other may + * be very hard to determine. + */ + int offset = rand() % (16 - sizeof(random_value)); + memcpy(&random_value, p + offset, sizeof(random_value)); + } else +#endif + { + /* + * Otherwise, hope the location we are loaded in + * memory is randomised by someone else + */ + random_value = ((uintptr_t)talloc_lib_init & 0xFFFFFFFF); + } + talloc_magic = random_value & ~TALLOC_FLAG_MASK; +} +#else +#warning "No __attribute__((constructor)) support found on this platform, additional talloc security measures not available" +#endif + static void talloc_log(const char *fmt, ...) PRINTF_ATTRIBUTE(1,2); static void talloc_log(const char *fmt, ...) { @@ -345,12 +404,6 @@ static void talloc_abort(const char *reason) static void talloc_abort_magic(unsigned magic) { - unsigned striped = magic - TALLOC_MAGIC_BASE; - unsigned major = (striped & 0xFFFFF000) >> 12; - unsigned minor = (striped & 0x00000FF0) >> 4; - talloc_log("Bad talloc magic[0x%08X/%u/%u] expected[0x%08X/%u/%u]\n", - magic, major, minor, - TALLOC_MAGIC, TALLOC_VERSION_MAJOR, TALLOC_VERSION_MINOR); talloc_abort("Bad talloc magic value - wrong talloc version used/mixed"); } @@ -369,9 +422,9 @@ static inline struct talloc_chunk *talloc_chunk_from_ptr(const void *ptr) { const char *pp = (const char *)ptr; struct talloc_chunk *tc = discard_const_p(struct talloc_chunk, pp - TC_HDR_SIZE); - if (unlikely((tc->flags & (TALLOC_FLAG_FREE | ~0xF)) != TALLOC_MAGIC)) { - if ((tc->flags & (~0xFFF)) == TALLOC_MAGIC_BASE) { - talloc_abort_magic(tc->flags & (~0xF)); + if (unlikely((tc->flags & (TALLOC_FLAG_FREE | ~TALLOC_FLAG_MASK)) != talloc_magic)) { + if ((tc->flags & (~0xF)) == talloc_magic) { + talloc_abort_magic(tc->flags & (~TALLOC_FLAG_MASK)); return NULL; } @@ -561,7 +614,7 @@ static inline struct talloc_chunk *talloc_alloc_pool(struct talloc_chunk *parent pool_hdr->end = (void *)((char *)pool_hdr->end + chunk_size); - result->flags = TALLOC_MAGIC | TALLOC_FLAG_POOLMEM; + result->flags = talloc_magic | TALLOC_FLAG_POOLMEM; result->pool = pool_hdr; pool_hdr->object_count++; @@ -617,7 +670,7 @@ static inline void *__talloc_with_prefix(const void *context, size_t size, return NULL; } tc = (struct talloc_chunk *)(ptr + prefix_len); - tc->flags = TALLOC_MAGIC; + tc->flags = talloc_magic; tc->pool = NULL; talloc_memlimit_grow(limit, total_len); diff --git a/talloc.h b/talloc.h index 5ece54d..b7408b9 100644 --- a/talloc.h +++ b/talloc.h @@ -47,6 +47,8 @@ extern "C" { int talloc_version_major(void); int talloc_version_minor(void); +/* This is mostly useful only for testing */ +int talloc_test_get_magic(void); /** * @brief Define a talloc parent type diff --git a/test_magic_differs.sh b/test_magic_differs.sh new file mode 100755 index 0000000..0f765f0 --- /dev/null +++ b/test_magic_differs.sh @@ -0,0 +1,14 @@ +#!/bin/sh +# This test ensures that two different talloc processes do not use the same +# magic value to lessen the opportunity for transferrable attacks. + +echo "test: magic differs" + +if [ + "`./talloc_test_magic_differs_helper`" != "`./talloc_test_magic_differs_helper`" +]; then + echo "failure: magic remained the same between executions" + exit 1 +fi + +echo "success: magic differs" diff --git a/test_magic_differs_helper.c b/test_magic_differs_helper.c new file mode 100644 index 0000000..6798827 --- /dev/null +++ b/test_magic_differs_helper.c @@ -0,0 +1,12 @@ +#include +#include "talloc.h" + +/* + * This program is called by a testing shell script in order to ensure that + * if the library is loaded into different processes it uses different magic + * values in order to thwart security attacks. + */ +int main(int argc, char *argv[]) { + printf("%i\n", talloc_test_get_magic()); + return 0; +} diff --git a/testsuite.c b/testsuite.c index 6d0fe94..34410b8 100644 --- a/testsuite.c +++ b/testsuite.c @@ -31,6 +31,9 @@ #include #endif +#include +#include + #include "talloc_testsuite.h" static struct timeval timeval_current(void) @@ -1747,6 +1750,7 @@ static void *thread_fn(void *arg) ret = pthread_cond_wait(&condvar, &mtx); if (ret != 0) { talloc_free(top_ctx); + pthread_mutex_unlock(&mtx); return NULL; } } @@ -1827,6 +1831,7 @@ static bool test_pthread_talloc_passing(void) printf("pthread_cond_wait %d failed (%d)\n", i, ret); talloc_free(mem_ctx); + pthread_mutex_unlock(&mtx); return false; } } @@ -1850,6 +1855,70 @@ static bool test_pthread_talloc_passing(void) } #endif +static void test_magic_protection_abort(const char *reason) +{ + /* exit with errcode 42 to communicate successful test to the parent process */ + if (strcmp(reason, "Bad talloc magic value - unknown value") == 0) { + _exit(42); + } else { + printf("talloc aborted for an unexpected reason\n"); + } +} + +static bool test_magic_protection(void) +{ + void *pool = talloc_pool(NULL, 1024); + int *p1, *p2; + pid_t pid; + int exit_status; + + printf("test: magic_protection\n"); + p1 = talloc(pool, int); + p2 = talloc(pool, int); + + /* To avoid complaints from the compiler assign values to the p1 & p2. */ + *p1 = 6; + *p2 = 9; + + pid = fork(); + if (pid == 0) { + talloc_set_abort_fn(test_magic_protection_abort); + + /* + * Simulate a security attack + * by triggering a buffer overflow in memset to overwrite the + * constructor in the next pool chunk. + * + * Real attacks would attempt to set a real destructor. + */ + memset(p1, '\0', 32); + + /* Then the attack takes effect when the memory's freed. */ + talloc_free(pool); + + /* Never reached. Make compilers happy */ + return true; + } + + while (wait(&exit_status) != pid); + + if (!WIFEXITED(exit_status)) { + printf("Child exited through unexpected abnormal means\n"); + return false; + } + if (WEXITSTATUS(exit_status) != 42) { + printf("Child exited with wrong exit status\n"); + return false; + } + if (WIFSIGNALED(exit_status)) { + printf("Child recieved unexpected signal\n"); + return false; + } + + printf("success: magic_protection\n"); + return true; +} + static void test_reset(void) { talloc_set_log_fn(test_log_stdout); @@ -1932,6 +2001,8 @@ bool torture_local_talloc(struct torture_context *tctx) } test_reset(); ret &= test_autofree(); + test_reset(); + ret &= test_magic_protection(); test_reset(); talloc_disable_null_tracking(); diff --git a/third_party/waf/wafadmin/Build.py b/third_party/waf/wafadmin/Build.py index 50f4d7f..d36d3df 100644 --- a/third_party/waf/wafadmin/Build.py +++ b/third_party/waf/wafadmin/Build.py @@ -645,6 +645,10 @@ class BuildContext(Utils.Context): cache[v] = x return cache.get(env.variant() + '_' + name, None) + def get_tgen_by_name(self, name): + """waf 1.8 api""" + return self.name_to_obj(name, self.env) + def flush(self, all=1): """tell the task generators to create the tasks""" diff --git a/third_party/waf/wafadmin/Node.py b/third_party/waf/wafadmin/Node.py index 158a4a4..6b03726 100644 --- a/third_party/waf/wafadmin/Node.py +++ b/third_party/waf/wafadmin/Node.py @@ -689,6 +689,13 @@ class Node(object): child = self.ensure_dir_node_from_path(k) child.update_build_dir(env) + def read(self, flags='r', encoding='ISO8859-1'): + """backported from waf 1.8""" + return Utils.readf(self.abspath(), flags, encoding) + + def write(self, data, flags='w', encoding='ISO8859-1'): + """backported from waf 1.8""" + Utils.writef(self.abspath(self.bld.env), data, flags, encoding) class Nodu(Node): pass diff --git a/third_party/waf/wafadmin/TaskGen.py b/third_party/waf/wafadmin/TaskGen.py index 5900809..386798f 100644 --- a/third_party/waf/wafadmin/TaskGen.py +++ b/third_party/waf/wafadmin/TaskGen.py @@ -242,6 +242,9 @@ class task_gen(object): def name_to_obj(self, name): return self.bld.name_to_obj(name, self.env) + def get_tgen_by_name(self, name): + return self.bld.get_tgen_by_name(name) + def find_sources_in_dirs(self, dirnames, excludes=[], exts=[]): """ The attributes "excludes" and "exts" must be lists to avoid the confusion diff --git a/third_party/waf/wafadmin/Tools/cc.py b/third_party/waf/wafadmin/Tools/cc.py index e54df47..7eb5272 100644 --- a/third_party/waf/wafadmin/Tools/cc.py +++ b/third_party/waf/wafadmin/Tools/cc.py @@ -23,7 +23,7 @@ g_cc_type_vars = ['CCFLAGS', 'LINKFLAGS'] class cc_taskgen(ccroot.ccroot_abstract): pass -@feature('cc') +@feature('c', 'cc') @before('apply_type_vars') @after('default_cc') def init_cc(self): @@ -33,7 +33,7 @@ def init_cc(self): if not self.env['CC_NAME']: raise Utils.WafError("At least one compiler (gcc, ..) must be selected") -@feature('cc') +@feature('c', 'cc') @after('apply_incpaths') def apply_obj_vars_cc(self): """after apply_incpaths for INC_PATHS""" @@ -51,7 +51,7 @@ def apply_obj_vars_cc(self): for i in env['CPPPATH']: app('_CCINCFLAGS', cpppath_st % i) -@feature('cc') +@feature('c', 'cc') @after('apply_lib_vars') def apply_defines_cc(self): """after uselib is set for CCDEFINES""" diff --git a/third_party/waf/wafadmin/Tools/ccroot.py b/third_party/waf/wafadmin/Tools/ccroot.py index c130b40..2240b2f 100644 --- a/third_party/waf/wafadmin/Tools/ccroot.py +++ b/third_party/waf/wafadmin/Tools/ccroot.py @@ -190,7 +190,7 @@ def get_target_name(self): return os.path.join(dir, pattern % name) -@feature('cc', 'cxx') +@feature('c', 'cc', 'cxx') @before('apply_core') def default_cc(self): """compiled_tasks attribute must be set before the '.c->.o' tasks can be created""" @@ -253,7 +253,7 @@ def default_link_install(self): if self.install_path: self.bld.install_files(self.install_path, self.link_task.outputs[0], env=self.env, chmod=self.chmod) -@feature('cc', 'cxx') +@feature('c', 'cc', 'cxx') @after('apply_type_vars', 'apply_lib_vars', 'apply_core') def apply_incpaths(self): """used by the scanner @@ -297,7 +297,7 @@ def apply_incpaths(self): if USE_TOP_LEVEL: self.env.append_value('INC_PATHS', self.bld.srcnode) -@feature('cc', 'cxx') +@feature('c', 'cc', 'cxx') @after('init_cc', 'init_cxx') @before('apply_lib_vars') def apply_type_vars(self): @@ -339,7 +339,7 @@ def apply_link(self): self.link_task = tsk -@feature('cc', 'cxx') +@feature('c', 'cc', 'cxx') @after('apply_link', 'init_cc', 'init_cxx', 'apply_core') def apply_lib_vars(self): """after apply_link because of 'link_task' @@ -523,7 +523,7 @@ c_attrs = { 'frameworkpath' : 'FRAMEWORKPATH' } -@feature('cc', 'cxx') +@feature('c', 'cc', 'cxx') @before('init_cxx', 'init_cc') @before('apply_lib_vars', 'apply_obj_vars', 'apply_incpaths', 'init_cc') def add_extra_flags(self): diff --git a/third_party/waf/wafadmin/Tools/config_c.py b/third_party/waf/wafadmin/Tools/config_c.py index 9f1103c..3ab447c 100644 --- a/third_party/waf/wafadmin/Tools/config_c.py +++ b/third_party/waf/wafadmin/Tools/config_c.py @@ -82,6 +82,10 @@ def parse_flags(line, uselib, env): # RPATH later, and hence can potentially lead to linking # in too old versions of our internal libs. # + elif x == '-Wl,-rpath' or x == '-Wl,-R': + app('RPATH_' + uselib, lst.pop(0).lstrip('-Wl,')) + elif x.startswith('-Wl,-R,'): + app('RPATH_' + uselib, x[7:]) elif x.startswith('-Wl,-R'): app('RPATH_' + uselib, x[6:]) elif x.startswith('-Wl,-rpath,'): diff --git a/third_party/waf/wafadmin/Tools/msvc.py b/third_party/waf/wafadmin/Tools/msvc.py index 2a97d19..72e7376 100644 --- a/third_party/waf/wafadmin/Tools/msvc.py +++ b/third_party/waf/wafadmin/Tools/msvc.py @@ -638,7 +638,7 @@ def msvc_common_flags(conf): ##### conf above, build below @after('apply_link') -@feature('cc', 'cxx') +@feature('c', 'cc', 'cxx') def apply_flags_msvc(self): if self.env.CC_NAME != 'msvc' or not self.link_task: return diff --git a/third_party/waf/wafadmin/Tools/osx.py b/third_party/waf/wafadmin/Tools/osx.py index 88ca0d9..95184ee 100644 --- a/third_party/waf/wafadmin/Tools/osx.py +++ b/third_party/waf/wafadmin/Tools/osx.py @@ -38,7 +38,7 @@ app_info = ''' # see WAF issue 285 # and also http://trac.macports.org/ticket/17059 -@feature('cc', 'cxx') +@feature('c', 'cc', 'cxx') @before('apply_lib_vars') def set_macosx_deployment_target(self): if self.env['MACOSX_DEPLOYMENT_TARGET']: @@ -47,7 +47,7 @@ def set_macosx_deployment_target(self): if sys.platform == 'darwin': os.environ['MACOSX_DEPLOYMENT_TARGET'] = '.'.join(platform.mac_ver()[0].split('.')[:2]) -@feature('cc', 'cxx') +@feature('c', 'cc', 'cxx') @after('apply_lib_vars') def apply_framework(self): for x in self.to_list(self.env['FRAMEWORKPATH']): @@ -145,7 +145,7 @@ def apply_link_osx(self): self.env.append_value('LINKFLAGS', path) @before('apply_link', 'apply_lib_vars') -@feature('cc', 'cxx') +@feature('c', 'cc', 'cxx') def apply_bundle(self): """use env['MACBUNDLE'] to force all shlibs into mac bundles or use obj.mac_bundle = True for specific targets only""" diff --git a/third_party/waf/wafadmin/Utils.py b/third_party/waf/wafadmin/Utils.py index 5a59a4c..abb46a7 100644 --- a/third_party/waf/wafadmin/Utils.py +++ b/third_party/waf/wafadmin/Utils.py @@ -147,6 +147,38 @@ except ImportError: # portability fixes may be added elsewhere (although, md5 should be everywhere by now) md5 = None +def readf(fname, m='r', encoding='ISO8859-1'): + """backported from waf 1.8""" + if sys.hexversion > 0x3000000 and not 'b' in m: + m += 'b' + f = open(fname, m) + try: + txt = f.read() + finally: + f.close() + if encoding: + txt = txt.decode(encoding) + else: + txt = txt.decode() + else: + f = open(fname, m) + try: + txt = f.read() + finally: + f.close() + return txt + +def writef(fname, data, m='w', encoding='ISO8859-1'): + """backported from waf 1.8""" + if sys.hexversion > 0x3000000 and not 'b' in m: + data = data.encode(encoding) + m += 'b' + f = open(fname, m) + try: + f.write(data) + finally: + f.close() + class ordered_dict(UserDict): def __init__(self, dict = None): self.allkeys = [] @@ -423,8 +455,7 @@ def check_dir(path): os.makedirs(path) except OSError, e: if not os.path.isdir(path): - raise Errors.WafError('Cannot create the folder %r' % path, ex=e) - + raise WafError("Cannot create the folder '%s' (error: %s)" % (path, e)) def cmd_output(cmd, **kw): @@ -557,15 +588,6 @@ def load_tool(tool, tooldir=None): for dt in tooldir: sys.path.remove(dt) -def readf(fname, m='r'): - "get the contents of a file, it is not used anywhere for the moment" - f = open(fname, m) - try: - txt = f.read() - finally: - f.close() - return txt - def nada(*k, **kw): """A function that does nothing""" pass diff --git a/wscript b/wscript index bbe0cb1..b288071 100644 --- a/wscript +++ b/wscript @@ -1,7 +1,7 @@ #!/usr/bin/env python APPNAME = 'talloc' -VERSION = '2.1.3' +VERSION = '2.1.5' blddir = 'bin' @@ -66,6 +66,9 @@ def configure(conf): Logs.warn('Disabling pytalloc-util as python devel libs not found') conf.env.disable_python = True + conf.CHECK_HEADERS('sys/auxv.h') + conf.CHECK_FUNCS('getauxval') + conf.SAMBA_CONFIG_H() conf.SAMBA_CHECK_UNDEFINED_SYMBOL_FLAGS() @@ -97,6 +100,10 @@ def build(bld): testsuite_deps, install=False) + bld.SAMBA_BINARY('talloc_test_magic_differs_helper', + 'test_magic_differs_helper.c', + 'talloc', install=False) + else: private_library = True @@ -151,9 +158,14 @@ def test(ctx): cmd = os.path.join(Utils.g_module.blddir, 'talloc_testsuite') ret = samba_utils.RUN_COMMAND(cmd) print("testsuite returned %d" % ret) + magic_cmd = os.path.join(srcdir, 'lib', 'talloc', + 'test_magic_differs.sh') + + magic_ret = samba_utils.RUN_COMMAND(magic_cmd) + print("magic differs test returned %d" % magic_ret) pyret = samba_utils.RUN_PYTHON_TESTS(['test_pytalloc.py']) print("python testsuite returned %d" % pyret) - sys.exit(ret or pyret) + sys.exit(ret or magic_ret or pyret) def dist(): '''makes a tarball for distribution'''