Bug 10686

Summary: hush does not terminate on variable substitution with empty pattern
Product: Busybox Reporter: Julian Büning <julian.buening>
Component: OtherAssignee: unassigned
Status: RESOLVED FIXED    
Severity: normal CC: busybox-cvs, daniel.schemmel
Priority: P5    
Version: unspecified   
Target Milestone: ---   
Hardware: All   
OS: Linux   
Host: Target:
Build:

Description Julian Büning 2018-01-25 09:32:23 UTC
Observed behavior:
$ echo -en "echo \${_//}" | ./busybox hush &
[1] 1000
$ jobs
[1]+  Running                 echo -en "echo \${_//}" | ./busybox hush &

Expected behavior:
$ echo -en "echo \${_//}" | ./busybox hush &
[1] 1000
./busybox
[1]+  Done                    echo -en "echo \${_//}" | ./busybox hush

When, instead of leaving it empty, a pattern that does not match is provided, the command works as expected.

We found this behavior in version 1.27.2 and can also reproduce it with busybox 1.28.0 as well as the current master (commit d8fd88a09) compiled with make defconfig && make.

The function that is called to compute the location of any matches, strstr_pattern() in hush.c, has the following behavior on an empty pattern: It computes the size of the match, which is 0, and returns the pointer given to it as start of the input. This return value is checked by replace_pattern():

	while (1) {
		int size;
		char *s = strstr_pattern(val, pattern, &size);
		if (!s)
			break;

		// ...

		val = s + size;

		// ...
	}

As the return value is not NULL (it points to the same address as val), the loop is not broken. As the size is zero, the pointer is not advanced, thus provoking the same behavior of strstr_pattern() as before.

This behavior was found using Symbolic Execution techniques developed in the course of the SYMBIOSYS research project at COMSYS, RWTH Aachen University. This research is supported by the European Research Council (ERC) under the EU's Horizon 2020 Research and Innovation Programme grant agreement n. 647295 (SYMBIOSYS).
Comment 1 Denys Vlasenko 2018-01-25 13:10:25 UTC
Fixed in git, thanks!