lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Message-Id: <20200618221541.247643-3-korben@google.com>
Date:   Thu, 18 Jun 2020 15:15:41 -0700
From:   Korben Rusek <korben@...gle.com>
To:     Steven Rostedt <rostedt@...dmis.org>,
        Ingo Molnar <mingo@...hat.com>,
        Jonathan Corbet <corbet@....net>
Cc:     Peter Shier <pshier@...gle.com>, linux-doc@...r.kernel.org,
        linux-kernel@...r.kernel.org, jbehmer@...gle.com,
        franksie@...gle.com, Korben Rusek <korben@...gle.com>
Subject: [PATCH 2/2] tests for absolute timestamp

Tested:
kselftest output:

Found regular timestamps when force-abs-timestamp flag is off - [PASS]
Found absolute timestamps when force-abs-timestamp flag is on - [PASS]

Reviewed-by: Peter Shier <pshier@...gle.com>
Signed-off-by: Korben Rusek <korben@...gle.com>
---
 tools/testing/selftests/Makefile              |   1 +
 tools/testing/selftests/timestamp/Makefile    |  25 +++
 tools/testing/selftests/timestamp/abs-test.sh | 156 ++++++++++++++
 .../selftests/timestamp/abs-timestamp.c       | 198 ++++++++++++++++++
 4 files changed, 380 insertions(+)
 create mode 100644 tools/testing/selftests/timestamp/Makefile
 create mode 100644 tools/testing/selftests/timestamp/abs-test.sh
 create mode 100644 tools/testing/selftests/timestamp/abs-timestamp.c

diff --git a/tools/testing/selftests/Makefile b/tools/testing/selftests/Makefile
index 1195bd85af38..bda1cd0a608f 100644
--- a/tools/testing/selftests/Makefile
+++ b/tools/testing/selftests/Makefile
@@ -58,6 +58,7 @@ TARGETS += timens
 ifneq (1, $(quicktest))
 TARGETS += timers
 endif
+TARGETS += timestamp
 TARGETS += tmpfs
 TARGETS += tpm2
 TARGETS += user
diff --git a/tools/testing/selftests/timestamp/Makefile b/tools/testing/selftests/timestamp/Makefile
new file mode 100644
index 000000000000..a8aa3b7278cf
--- /dev/null
+++ b/tools/testing/selftests/timestamp/Makefile
@@ -0,0 +1,25 @@
+TEST_PROGS := abs-test.sh
+
+.PHONY: all clean
+
+include ../lib.mk
+
+override define RUN_TESTS
+	@cd $(OUTPUT); ./abs-test.sh
+endef
+
+override define INSTALL_RULE
+	mkdir -p $(INSTALL_PATH)
+	$(CC) -o $(INSTALL_PATH)/abs-timestamp abs-timestamp.c -static
+	echo $(INSTALL_PATH)
+	cp abs-test.sh $(INSTALL_PATH)/abs-test.sh
+	chmod u+x $(INSTALL_PATH)/abs-test.sh
+endef
+
+override define CLEAN
+	rm -f abs-timestamp
+endef
+
+override define EMIT_TESTS
+	echo "./abs-test.sh"
+endef
diff --git a/tools/testing/selftests/timestamp/abs-test.sh b/tools/testing/selftests/timestamp/abs-test.sh
new file mode 100644
index 000000000000..067a09c2e77d
--- /dev/null
+++ b/tools/testing/selftests/timestamp/abs-test.sh
@@ -0,0 +1,156 @@
+#!/bin/sh
+# SPDX-License-Identifier: GPL-2.0
+# description: event tracing - enable/disable abs_timestamp option
+
+TMPDIR=`mktemp -d /tmp/ftracetest-dir.XXXXXX`
+# Parameters
+DEBUGFS_DIR=`grep debugfs /proc/mounts | cut -f2 -d' ' | head -1`
+if [ -z "$DEBUGFS_DIR" ]; then
+	TRACING_DIR=`grep tracefs /proc/mounts | cut -f2 -d' ' | head -1`
+else
+	TRACING_DIR=$DEBUGFS_DIR/tracing
+fi
+
+clear_trace() {
+	echo > $TRACING_DIR/trace
+}
+
+disable_tracing() {
+	echo 0 > $TRACING_DIR/tracing_on
+}
+
+enable_tracing() {
+	echo 1 > $TRACING_DIR/tracing_on
+}
+
+reset_tracer() {
+	echo nop > $TRACING_DIR/current_tracer
+}
+
+do_reset() {
+	clear_trace
+	echo > $TRACING_DIR/set_event
+}
+
+exit_fail() {
+	exit 1
+}
+
+if [ -z `grep "force-abs-timestamp" $TRACING_DIR/trace_options` ]; then
+	echo "force-abs-timestamp is unsupported - [FAIL]"
+	exit 2
+fi
+
+# select all supported event types
+available=$( cat $TRACING_DIR/available_events | tr "\n" " " )
+events=($available)
+
+BUFSIZEK=1024
+
+emit_events() {
+	# give the system several opportunities to emit trace events
+	ping localhost -c 1 || sleep .001 || usleep 1 || sleep 1
+}
+
+check_absolute_timestamps() {
+	pids=()
+	PAGE_SIZE=`tail -n 1 $TRACING_DIR/events/header_page | awk -F";" '{print $3}' | awk -F":" '{print $2}'`
+	CORRECT=0
+	ERROR=0
+	FAILURE=""
+	for cf in $TRACING_DIR/per_cpu/cpu*
+	do
+		cpuname="${cf##*/}"
+		touch "${TMPDIR}/${cpuname}"
+		cat "${cf}/trace_pipe_raw" > "${TMPDIR}/${cpuname}" &
+		pids+=($!)
+		disown
+
+		RET=`./abs-timestamp "${TMPDIR}/${cpuname}" "$PAGE_SIZE" $1`
+		if [ $RET != $1 ]; then
+			if [ $RET != "empty" ]; then
+				ERROR=1
+				FAILURE=$cpuname
+			fi
+		fi
+		if [ "$RET" == "$1" ]; then
+			CORRECT=1
+		fi
+	done
+
+	if [ $ERROR == "1" ]; then
+		echo $FAILURE
+	elif [ $CORRECT == "1" ]; then
+		rm $TMPDIR/$cpuname
+		echo "SUCCESS"
+	else
+		echo "EMPTY"
+	fi
+}
+
+clean() {
+	do_reset
+	rm -rf $TMPDIR
+}
+
+fail() {
+	clean
+	echo $1
+	exit_fail
+}
+
+disable_tracing
+
+reset_tracer
+
+# Set buffer size
+echo ${BUFSIZEK} > $TRACING_DIR/buffer_size_kb
+# Remove newest events when the buffer overflows instead of oldest.
+echo "overwrite" > $TRACING_DIR/trace_options
+# Turn off absolute timestamp option
+echo "noforce-abs-timestamp" > $TRACING_DIR/trace_options
+# Enable events
+echo > $TRACING_DIR/set_event
+for event in "${events[@]}"
+do
+	echo "${event}" >> $TRACING_DIR/set_event
+done
+
+clear_trace
+enable_tracing
+emit_events
+disable_tracing
+RET=`check_absolute_timestamps "noabs-timestamp"`
+if [ $RET == "EMPTY" ]; then
+	echo "No traces found when force-abs-timestamp flag is off - [UNRESOLVED]"
+elif [ "$RET" != "SUCCESS" ]; then
+	fail "found unexpected absolute timestamps with noforce-abs-timestamp - [FAIL]"
+else
+	echo "Found regular timestamps when force-abs-timestamp flag is off - [PASS]"
+fi
+
+rm -rf $TMPDIR/*
+
+# Turn on absolute timestamp option
+echo "force-abs-timestamp" > $TRACING_DIR/trace_options
+for event in "${events[@]}"
+do
+	echo "${event}" >> $TRACING_DIR/set_event
+done
+
+clear_trace
+enable_tracing
+emit_events
+disable_tracing
+
+RET=`check_absolute_timestamps "abs-timestamp"`
+if [ $RET == "EMPTY" ]; then
+	echo "No traces found when force-abs-timestamp flag is on - [UNRESOLVED]"
+elif [ $RET != "SUCCESS" ]; then
+  echo $RET
+	fail "did not find absolute timestamps - [FAIL]"
+else
+	echo "Found absolute timestamps when force-abs-timestamp flag is on - [PASS]"
+fi
+
+clean
diff --git a/tools/testing/selftests/timestamp/abs-timestamp.c b/tools/testing/selftests/timestamp/abs-timestamp.c
new file mode 100644
index 000000000000..134268464a5a
--- /dev/null
+++ b/tools/testing/selftests/timestamp/abs-timestamp.c
@@ -0,0 +1,200 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * ftrace absolute timestamp test helper.
+ *
+ * ./abs-timestamp [FILE] [PAGE_SIZE] [METHOD]
+ *
+ *  - FILE: path to a raw cpu trace
+ *  - PAGE_SIZE: expected page size for the trace
+ *  - METHOD: should be either abs-timestamp or noabs-timestamp
+ *
+ * This program reads the trace data in [FILE]. It checks whether
+ * every data element contains an absolute timestamp element
+ * before it. If this is the case for every event it prints
+ * "abs-timestamp" otherwise it prints "noabs-timestamp".
+ * If no data is found then "no-data" is printed.
+ *
+ * It returns 0 if METHOD matches what is found or if no
+ * data is found.
+ */
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define INT32_SIZE 4
+
+#define EVENT_TYPE_VARIABLE_SIZE 0
+#define EVENT_TYPE_LEN_MAX 28
+#define EVENT_TYPE_PADDING 29
+#define EVENT_TYPE_EXTEND 30
+#define EVENT_TYPE_ABSTIME 31
+
+#define EVENT_TYPE_MASK 0b11111
+
+#define MINIMUM_EVENT_SIZE 16
+
+#define PAGE_HEADER_SIZE 16
+
+#define RET_PASS	 0
+#define RET_FAIL	-2
+
+int page_size = 4080 + PAGE_HEADER_SIZE;
+
+int skip_bytes(int bytes, FILE *file)
+{
+	return fseek(file, bytes, SEEK_CUR) == 0;
+}
+
+unsigned long read_int64(FILE *file)
+{
+	unsigned long data;
+
+	if (!fread(&data, 8, 1, file))
+		return 0;
+	return data;
+}
+
+unsigned int read_int32(FILE *file)
+{
+	unsigned int data;
+
+	fread(&data, 4, 1, file);
+	return data;
+}
+
+char peek_byte(FILE *file)
+{
+	char byte;
+
+	fread(&byte, 1, 1, file);
+	skip_bytes(-1, file);
+	return byte;
+}
+
+int peek_event_type(FILE *file)
+{
+	if (feof(file))
+		return -1;
+	return peek_byte(file) & EVENT_TYPE_MASK;
+}
+
+// Extract the length of the page data from the page header. This length does
+// not include the size of the header (16 bytes).
+unsigned long page_data_length(FILE *file)
+{
+	unsigned long position = ftell(file);
+
+	if (position) {
+		int remaining =
+			(page_size - (position % page_size)) % page_size;
+
+		if (!skip_bytes(remaining, file))
+			return -1;
+	}
+	if (feof(file))
+		return 0;
+	if (!skip_bytes(8, file))
+		return 0;
+	return read_int64(file) & 0xFFFFF;
+}
+
+// Move to the next page if it exists. If successful the ending position of the
+// page is returned. It returns zero if there are no more pages.
+int move_next_page(FILE *file)
+{
+	unsigned long length = page_data_length(file);
+
+	if (length == 0)
+		return 0;
+	return ftell(file) + length;
+}
+
+void skip_event(int type, FILE *file)
+{
+	switch (type) {
+	// Time extend and absolute timestamp events are fixed length.
+	case EVENT_TYPE_EXTEND:
+	case EVENT_TYPE_ABSTIME:
+		skip_bytes(8, file);
+		return;
+	// Padding events and event type 0 are both variable length events where
+	// the next 32 bits indicate the length of the event. We also skip the
+	// next 4 bytes which indicate timestamp delta.
+	case EVENT_TYPE_PADDING:
+	case EVENT_TYPE_VARIABLE_SIZE: {
+		skip_bytes(4, file);
+		unsigned int length = read_int32(file);
+
+		skip_bytes(length - INT32_SIZE, file);
+		return;
+	}
+	// Other events (type 1...32) have a length of 4*type. We also skip the
+	// next 4 bytes which indicate timestamp delta.
+	default: {
+		skip_bytes(4, file);
+		unsigned int length = type << 2;
+
+		skip_bytes(length, file);
+		return;
+	}
+	}
+}
+
+int main(int argc, char *argv[])
+{
+	char absolute[] = "abs-timestamp";
+	FILE *file = fopen(argv[1], "r");
+	unsigned long page_end = page_data_length(file) + PAGE_HEADER_SIZE;
+	bool checking_abs = (argc > 3) && (strcmp(absolute, argv[3]) == 0);
+	bool satisfies_abs = true;
+	bool unaccounted_abs = false;
+	bool data_seen = false;
+
+	if (argc > 2) {
+		int base_page_size = strtol(argv[2], NULL, 10);
+
+		if (!base_page_size) {
+			printf("invalid format - header size missing");
+			return RET_FAIL;
+		}
+		page_size = base_page_size + PAGE_HEADER_SIZE;
+	}
+
+	while (!feof(file)) {
+		int type;
+
+		type = peek_event_type(file);
+		if (type == EVENT_TYPE_ABSTIME) {
+			unaccounted_abs = true;
+		} else if (type <= EVENT_TYPE_LEN_MAX) {
+			data_seen = true;
+			satisfies_abs = unaccounted_abs;
+			unaccounted_abs = false;
+		}
+		if (!satisfies_abs)
+			break;
+
+		skip_event(type, file);
+
+		if (ftell(file) + MINIMUM_EVENT_SIZE > page_end) {
+			page_end = move_next_page(file);
+			if (!page_end)
+				break;
+		}
+	}
+
+	if (!data_seen) {
+		printf("empty");
+		return RET_PASS;
+	}
+	if (satisfies_abs)
+		printf("abs-timestamp");
+	else
+		printf("noabs-timestamp");
+
+	if (satisfies_abs == checking_abs)
+		return RET_PASS;
+	return RET_FAIL;
+}
+
-- 
2.27.0.290.gba653c62da-goog

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ