Package: libfuzzy2 Version: 2.12-1 Severity: important Source: ssdeep Tags: patch jessie
Dear Maintainer, While I'm reviewing ssdeep source code as a new ssdeep developer, I found several bugs including this. Because of this bug's severity and Debian's freeze policy on Jessie, I want this bug to be reviewed and if it's considered as RC, I'd like to contribute targeted patch to fix this particular bug. [TECH BACKGROUND] A ssdeep digest consists of three parts: * Block size * First substring * Second substring For instance, "3:ubvcl+nz:uTcknzbn" can be splitted like this: * Block size (3) * First substring ("ubvcl+nz") * Second substring ("uTcknzbn") [BUG] The bug is in fuzzy_compare function which will be used to compare digests. This function is supposed to return 100 if given digests are identical. However, this function actually returns 100 if the block size and the first digest substring are identical. This means, even if second digest substring is not identical, fuzzy_compare considers it is. [REPRODUCTION] I attached two files to reproduce this issue easily (file1.gz and file2.gz). | $ ssdeep -V | 2.12 | $ /path/to/ssdeep-2.13-rc/ssdeep -V | 2.13 | $ | $ gzip -d file1.gz | $ gzip -d file2.gz | $ | $ ssdeep -l file1 file2 | tee files.ssdeep | ssdeep,1.1--blocksize:hash:hash,filename | 3:urNZHi:0/C,"file1" | 3:urNZHi:uJp,"file2" | $ | $ ssdeep -a -k files.ssdeep -x files.ssdeep | files.ssdeep:file1 matches files.ssdeep:file2 (100) | files.ssdeep:file1 matches files.ssdeep:file2 (100) | | files.ssdeep:file2 matches files.ssdeep:file1 (100) | files.ssdeep:file2 matches files.ssdeep:file1 (100) | | files.ssdeep:file1 matches files.ssdeep:file2 (100) | files.ssdeep:file1 matches files.ssdeep:file2 (100) | | files.ssdeep:file2 matches files.ssdeep:file1 (100) | files.ssdeep:file2 matches files.ssdeep:file1 (100) | | $ /path/to/ssdeep-2.13-rc/ssdeep -a -k files.ssdeep -x files.ssdeep | files.ssdeep:file1 matches files.ssdeep:file2 (0) | files.ssdeep:file1 matches files.ssdeep:file2 (0) | | files.ssdeep:file2 matches files.ssdeep:file1 (0) | files.ssdeep:file2 matches files.ssdeep:file1 (0) | | files.ssdeep:file1 matches files.ssdeep:file2 (0) | files.ssdeep:file1 matches files.ssdeep:file2 (0) | | files.ssdeep:file2 matches files.ssdeep:file1 (0) | files.ssdeep:file2 matches files.ssdeep:file1 (0) | | $ As you can see, "file1" and "file2" digests are different ("3:urNZHi:0/C" and "3:urNZHi:uJp") but the block size and the first substring are identical. Because ssdeep don't compare short substrings (to prevent exaggrations), comparison should result in mismatch (0). However, ssdeep 2.12 considers these digests are identical because of the bug and results in complete match (100). [SEVERITY] Since it affects reliability of digest match and clustering features (I mean most of ssdeep features) and this software is used for security purposes, it may be release critical on Jessie. [UPSTREAM] Please note that this bug is fixed in version 2.13 RC and the new release, version 2.13 will be released in a few weeks. -- System Information: Debian Release: 8.0 APT prefers testing-updates APT policy: (500, 'testing-updates'), (500, 'testing') Architecture: amd64 (x86_64) Kernel: Linux 3.16.0-4-amd64 (SMP w/8 CPU cores) Locale: LANG=en_US.UTF-8, LC_CTYPE=en_US.UTF-8 (charmap=UTF-8) Shell: /bin/sh linked to /bin/dash Init: systemd (via /run/systemd/system) Versions of packages libfuzzy2 depends on: ii libc6 2.19-15 ii multiarch-support 2.19-15 libfuzzy2 recommends no packages. libfuzzy2 suggests no packages. -- no debconf information
Description: Fix incorrect digest comparison from relatively simple files fuzzy_compare function is supposed to return 100 if given digests are identical. However, this function in version 2.12 returns 100 if the first substring is identical and second one is not. . This bug affects comparison of digests from relatively simple files. Since it's easy to reproduce, it affects reliability of this software. Author: Tsukasa OI <l...@livegrid.org> Applied-Upstream: 2.13-rc1, http://sourceforge.net/p/ssdeep/code/231/tree/ --- --- ssdeep-2.12.orig/fuzzy.c +++ ssdeep-2.12/fuzzy.c @@ -711,11 +711,8 @@ int fuzzy_compare(const char *str1, cons return -1; } - // Chop the first substring. We terminate the first substring - // and then advance the pointer to the start of the second substring. - *s1_2 = 0; + // Advance the pointer to the start of the second substring. s1_2++; - *s2_2 = 0; s2_2++; // Chop the second string at the comma--just before the filename. @@ -741,6 +738,10 @@ int fuzzy_compare(const char *str1, cons } } + // Chop the first substring. + s1_2[-1] = 0; + s2_2[-1] = 0; + // each signature has a string for two block sizes. We now // choose how to combine the two block sizes. We checked above // that they have at least one block size in common
file1.gz
Description: Binary data
file2.gz
Description: Binary data