Пример #1
0
static void *do_fuzz(void *data)
{
	int i = 1000;
	int thread = (unsigned long)data;
	char filename[PATH_MAXLEN];
	int ret;

	printf("Thread %i: Fuzzing %s vs %s\n", thread, from_files[thread], to_files[thread]);

	sprintf(filename, OUTDIR "tempfile.%i", thread);

	make_bsdiff_delta(from_files[thread], to_files[thread], filename, (rand() % 10 > 8));

	apply_bsdiff_delta(from_files[thread], OUTDIR "testout", filename);

	/* do a large number of runs and then exit, so that we can randomly pick files from an outer script */
	while (i-- > 0) {
		char *command;

		/* step 3: randomly corrupt the "tempfile" into a "corrupt" file*/
		corrupt_file(thread);
		/* step 4: run valgrind on the bspatch program with the "corrupt" file */
		if (asprintf(&command, "valgrind --leak-check=no --log-file=" OUTDIR "valgrind.log.%i bspatch %s " OUTDIR "output.%i " OUTDIR "corrupt.%i > /dev/null",
			     thread, from_files[thread], thread, thread) <= 0) {
			assert(0);
		}

		ret = system(command);
		free(command);
		/* step 5: check valgrind output for failures, if failed, copy corrupt to "failed" dir */

		if (check_valgrind(thread)) {
			int t;
			char *command2;

			t = time(NULL);
			if (asprintf(&command2, "mv " OUTDIR "corrupt.%i " OUTDIR "failed/corrupt.%i-%i",
				     thread, thread, t) <= 0) {
				assert(0);
			}
			ret = system(command2);
			assert(ret == 0);
			free(command2);
			if (asprintf(&command2, "mv " OUTDIR "valgrind.log.%i " OUTDIR "failed/valgrind.%i-%i",
				     thread, thread, t) <= 0) {
				assert(0);
			}
			ret = system(command2);
			assert(ret == 0);
			free(command2);
			if (asprintf(&command2, "cp %s " OUTDIR "failed/original.%i-%i",
				     from_files[thread], thread, t) <= 0) {
				assert(0);
			}
			ret = system(command2);
			assert(ret == 0);
			free(command2);
			printf("x");
			sleep(1); /* make sure no duplicates exist */
		} else if (i % 10 == 0) {
			printf(".");
		}
		fflush(stdout);
	}
	return NULL;
}
Пример #2
0
void __create_delta(struct file *file, int from_version)
{
	char *original, *newfile, *outfile, *dotfile, *testnewfile, *sanitycheck;
	char *conf;
	int ret;

	if (file->is_link) {
		return;
	}

	if (file->is_deleted) {
		return; /* file got deleted -> by definition we cannot make a delta */
	}

	if (file->is_dir) {
		return; /* cannot do this for directories yet */
	}

	conf = config_image_base();
	string_or_die(&newfile, "%s/%i/full/%s", conf, file->last_change, file->filename);

	string_or_die(&original, "%s/%i/full/%s", conf, from_version, file->peer->filename);

	free(conf);

	conf = config_output_dir();

	string_or_die(&outfile, "%s/%i/delta/%i-%i-%s", conf, file->last_change, from_version, file->last_change, file->hash);
	string_or_die(&dotfile, "%s/%i/delta/.%i-%i-%s", conf, file->last_change, from_version, file->last_change, file->hash);
	string_or_die(&testnewfile, "%s/%i/delta/.%i-%i-%s.testnewfile", conf, file->last_change, from_version, file->last_change, file->hash);
	string_or_die(&sanitycheck, "cmp -s \"%s\" \"%s\"", newfile, testnewfile);

	LOG(file, "Making delta", "%s->%s", original, newfile);

	ret = xattrs_compare(original, newfile);
	if (ret != 0) {
		LOG(NULL, "xattrs have changed, don't create diff ", "%s", newfile);
		goto out;
	}
	ret = make_bsdiff_delta(original, newfile, dotfile, 0);
	if (ret < 0) {
		LOG(file, "Delta creation failed", "%s->%s ret is %i", original, newfile, ret);
		goto out;
	}
	if (ret == 1) {
		LOG(file, "...delta larger than newfile: FULLDL", "%s", newfile);
		unlink(dotfile);
		goto out;
	}

	/* does delta properly recreate expected content? */
	ret = apply_bsdiff_delta(original, testnewfile, dotfile);
	if (ret != 0) {
		printf("Delta application failed.\n");
		printf("Attempted %s->%s via diff %s\n", original, testnewfile, dotfile);
		LOG(file, "Delta application failed.", "Attempted %s->%s via diff %s", original, testnewfile, dotfile);

#warning the above is racy..tolerate it temporarily
		// ok fine
		//unlink(testnewfile);
		//unlink(dotfile);
		ret = 0;
		goto out;
	}
	xattrs_copy(original, newfile);

	/* does xattrs have been correctly copied?*/
	if (xattrs_compare(original, testnewfile) != 0) {
		printf("Delta application resulted in xattrs mismatch.\n");
		printf("%s->%s via diff %s yielded %s\n", original, newfile, dotfile, testnewfile);
		LOG(file, "Delta xattrs mismatch:", "%s->%s via diff %s yielded %s", original, newfile, dotfile, testnewfile);
		assert(0);
		goto out;
	}

	ret = system(sanitycheck);
	if (ret == -1 || !WIFEXITED(ret) || WEXITSTATUS(ret) == 2) {
		printf("Sanity check system command failed %i. \n", ret);
		printf("%s->%s via diff %s yielded %s\n", original, newfile, dotfile, testnewfile);
		assert(0);
		goto out;
	} else if (WEXITSTATUS(ret) == 1) {
		printf("Delta application resulted in file mismatch %i. \n", ret);
		printf("%s->%s via diff %s yielded %s\n", original, newfile, dotfile, testnewfile);
		LOG(file, "Delta mismatch:", "%s->%s via diff %s yielded %s", original, newfile, dotfile, testnewfile);

#warning this too will have failures due to races
		//unlink(testnewfile);
		//unlink(dotfile);
		ret = 0;
		goto out;
	}

	unlink(testnewfile);

	if (rename(dotfile, outfile) != 0) {
		if (errno == ENOENT) {
			LOG(NULL, "dotfile:", " %s does not exist", dotfile);
		}
		LOG(NULL, "Failed to rename", "");
	}
out:	free(sanitycheck);
	free(testnewfile);
	free(conf);
	free(newfile);
	free(original);
	free(outfile);
	free(dotfile);
}
Пример #3
0
int main(int UNUSED_PARAM argc, char UNUSED_PARAM **argv)
{
	int ret;
	int algo;
	struct timeval before, after;
	struct stat st1, st2;
	struct file *file1, *file2;

	ret = stat(argv[1], &st1);
	if (ret) {
		exit(0);
	}
	ret = stat(argv[2], &st2);
	if (ret) {
		exit(0);
	}

	file1 = calloc(1, sizeof(struct file));
	assert(file1);
	file1->use_xattrs = true;
	file1->filename = strdup(argv[2]);

	file2 = calloc(1, sizeof(struct file));
	assert(file2);
	file2->use_xattrs = true;
	file1->filename = strdup("result");

	populate_file_struct(file1, argv[2]);
	ret = compute_hash(file1, argv[2]);
	if ((ret != 0) || hash_is_zeros(file1->hash)) {
		printf("Hash computation failed\n");
		exit(0);
	}

	for (algo = 0; algo < BSDIFF_ENC_LAST; algo++) {
		struct stat bu;
		int i;
		time_t start;

		unlink("output.bsdiff");
		make_bsdiff_delta(argv[1], argv[2], "output.bsdiff", algo);

		stat("output.bsdiff", &bu);

		start = time(NULL);
		gettimeofday(&before, NULL);
		for (i = 0; i < 10000; i++) {
			ret = apply_bsdiff_delta(argv[1], "result", "output.bsdiff");
			if (i > 500 && time(NULL) - start > 5) {
				break;
			}
		}
		gettimeofday(&after, NULL);
		populate_file_struct(file1, "result");
		ret = compute_hash(file2, "result");
		if ((ret != 0) || hash_is_zeros(file2->hash)) {
			printf("Hash computation failed\n");
			exit(0);
		}
		if (!hash_equal(file1->hash, file2->hash)) {
			printf("Hash mismatch for algorithm %i \n", algo);
			exit(0);
		}
		unlink("result");

		b[algo] = before.tv_sec + before.tv_usec / 1000000.0;
		a[algo] = after.tv_sec + after.tv_usec / 1000000.0;
		count[algo] = i / 5000.0;
		size[algo] = bu.st_size;
	}

	printf("file, %s, orgsize, %i, best, %i, unc, %i, %5.3f, bzip, %i, %5.3f, gzip, %i, %5.3f, xz, %i, %5.3f, zeros, %i, %5.3f\n",
	       argv[1], (int)(st1.st_size + st2.st_size) / 2, size[0],
	       size[1], (a[1] - b[1]) / count[1],
	       size[2], (a[2] - b[2]) / count[2],
	       size[3], (a[3] - b[3]) / count[3],
	       size[4], (a[4] - b[4]) / count[4],
	       size[5], (a[5] - b[5]) / count[5]);

	return ret;
}