dirsrvtests/tests/tickets/ticket49104_test.py | 80 ++++++++++++++++++++++++++ ldap/servers/slapd/tools/dbscan.c | 17 +++++ 2 files changed, 96 insertions(+), 1 deletion(-)
New commits: commit c5a67ce1ad297cf59b5dd0e47c9896e261aba08c Author: Noriko Hosoi nhosoi@redhat.com Date: Fri Jan 27 15:41:08 2017 -0800
Ticket #49104 - Add CI test
Description: dbscan-bin crashing due to a segmentation fault
diff --git a/dirsrvtests/tests/tickets/ticket49104_test.py b/dirsrvtests/tests/tickets/ticket49104_test.py new file mode 100644 index 0000000..9840b1d --- /dev/null +++ b/dirsrvtests/tests/tickets/ticket49104_test.py @@ -0,0 +1,80 @@ +# --- BEGIN COPYRIGHT BLOCK --- +# Copyright (C) 2017 Red Hat, Inc. +# All rights reserved. +# +# License: GPL (version 3 or any later version). +# See LICENSE for details. +# --- END COPYRIGHT BLOCK --- +# +import logging +import subprocess + +import pytest +from lib389.tasks import * +from lib389.topologies import topology_st + +log = logging.getLogger(__name__) + +def test_ticket49104_setup(topology_st): + """ + Generate an ldif file having 10K entries and import it. + """ + # Generate a test ldif (100k entries) + ldif_dir = topology_st.standalone.get_ldif_dir() + import_ldif = ldif_dir + '/49104.ldif' + try: + topology_st.standalone.buildLDIF(100000, import_ldif) + except OSError as e: + log.fatal('ticket 49104: failed to create test ldif,\ + error: %s - %s' % (e.errno, e.strerror)) + assert False + + # Online + try: + topology_st.standalone.tasks.importLDIF(suffix=DEFAULT_SUFFIX, + input_file=import_ldif, + args={TASK_WAIT: True}) + except ValueError: + log.fatal('ticket 49104: Online import failed') + assert False + +def test_ticket49104(topology_st): + """ + Run dbscan with valgrind changing the truncate size. + If there is no Invalid report, we can claim the test has passed. + """ + log.info("Test ticket 49104 -- dbscan crashes by memory corruption") + myvallog = '/tmp/val49104.out' + if os.path.exists(myvallog): + os.remove(myvallog) + prog = os.path.join(topology_st.standalone.get_bin_dir(), 'dbscan-bin') + valcmd = 'valgrind --tool=memcheck --leak-check=yes --num-callers=40 --log-file=%s ' % myvallog + id2entry = os.path.join(topology_st.standalone.dbdir, DEFAULT_BENAME, 'id2entry.db') + + for i in range(20, 30): + cmd = valcmd + '%s -f %s -t %d -R' % (prog, id2entry , i) + log.info('Running script: %s' % cmd) + proc = subprocess.Popen(cmd.split(), stdout=subprocess.PIPE) + outs = '' + try: + outs = proc.communicate() + except OSError as e: + log.exception('dbscan: error executing (%s): error %d - %s' % + (cmd, e.errno, e.strerror)) + raise e + + grep = 'egrep "Invalid read|Invalid write" %s' % myvallog + p = os.popen(grep, "r") + l = p.readline() + if 'Invalid' in l: + log.fatal('ERROR: valgrind reported invalid read/write: %s' % l) + assert False + + log.info('ticket 49104 - PASSED') + + +if __name__ == '__main__': + # Run isolated + # -s for DEBUG mode + CURRENT_FILE = os.path.realpath(__file__) + pytest.main("-s %s" % CURRENT_FILE)
commit efeb2f6e873df32ce7545fa1fb319806d2108fda Author: Noriko Hosoi nhosoi@redhat.com Date: Thu Jan 26 15:10:46 2017 -0800
Ticket #49104 - dbscan-bin crashing due to a segmentation fault
Description: There was a logic error in format_raw. When a truncate option (-t width) is given, the function cut the output and replace the last 5 bytes with " ...\0". The position to start the replace was not correct in some case.
https://fedorahosted.org/389/ticket/49104
Reviewed by wibrown@redhat.com (Thank you, William!!)
diff --git a/ldap/servers/slapd/tools/dbscan.c b/ldap/servers/slapd/tools/dbscan.c index 0a7f85e..33252b8 100644 --- a/ldap/servers/slapd/tools/dbscan.c +++ b/ldap/servers/slapd/tools/dbscan.c @@ -202,6 +202,7 @@ static char *format_raw(unsigned char *s, int len, int flags, return NULL;
for (p = s, o = buf, i = 0; i < len && o < bufend; p++, i++) { + int ishex = 0; if ((*p == '%') || (*p <= ' ') || (*p >= 126)) { /* index keys are stored with their trailing NUL */ if ((*p == 0) && (i == len-1)) @@ -215,18 +216,32 @@ static char *format_raw(unsigned char *s, int len, int flags, *o++ = '%'; *o++ = hex[*p / 16]; *o++ = hex[*p % 16]; + ishex = 1; } } else { *o++ = *p; } if (truncatesiz > 0 && o > bufend - 5) { /* truncate it */ + /* + * Padding " ...\0" at the end of the buf. + * If dumped as %##, truncate the partial value if any. + */ + o = bufend - 5; + if (ishex) { + if ((o > buf) && *(o-1) == '%') { + o -= 1; + } else if ((o > buf + 1) && *(o-2) == '%') { + o -= 2; + } + } strcpy((char *)o, " ..."); i = len; o += 4; + break; } } - *o = 0; + *o = '\0'; return (char *)buf; }
389-commits@lists.fedoraproject.org