Commit 5855b099 authored by Eduard Zingerman's avatar Eduard Zingerman Committed by Andrii Nakryiko
Browse files

selftests/bpf: Prevent infinite loop in veristat when base file is too short



The following example forces veristat to loop indefinitely:

$ cat two-ok
file_name,prog_name,verdict,total_states
file-a,a,success,12
file-b,b,success,67

$ cat add-failure
file_name,prog_name,verdict,total_states
file-a,a,success,12
file-b,b,success,67
file-b,c,failure,32

$ veristat -C two-ok add-failure
  <does not return>

The loop is caused by handle_comparison_mode() not checking if `base`
variable points to `fallback_stats` prior advancing joined results
using `base`.

Signed-off-by: default avatarEduard Zingerman <eddyz87@gmail.com>
Signed-off-by: default avatarAndrii Nakryiko <andrii@kernel.org>
Link: https://lore.kernel.org/bpf/20230407154125.896927-1-eddyz87@gmail.com
parent b24f0b04
Loading
Loading
Loading
Loading
+6 −2
Original line number Diff line number Diff line
@@ -1824,18 +1824,22 @@ static int handle_comparison_mode(void)
			join->stats_b = comp;
			i++;
			j++;
		} else if (comp == &fallback_stats || r < 0) {
		} else if (base != &fallback_stats && (comp == &fallback_stats || r < 0)) {
			join->file_name = base->file_name;
			join->prog_name = base->prog_name;
			join->stats_a = base;
			join->stats_b = NULL;
			i++;
		} else {
		} else if (comp != &fallback_stats && (base == &fallback_stats || r > 0)) {
			join->file_name = comp->file_name;
			join->prog_name = comp->prog_name;
			join->stats_a = NULL;
			join->stats_b = comp;
			j++;
		} else {
			fprintf(stderr, "%s:%d: should never reach here i=%i, j=%i",
				__FILE__, __LINE__, i, j);
			return -EINVAL;
		}
		env.join_stat_cnt += 1;
	}