"GOT", but the "O" is a cute, smiling pufferfish. Index | Thread | Search

From:
Stefan Sperling <stsp@stsp.name>
Subject:
validate reference names in open_ref()
To:
gameoftrees@openbsd.org
Date:
Thu, 20 May 2021 12:08:37 +0200

Download raw body.

Thread
There are code paths which can attempt to use a reference name
which hasn't been validated yet. This patch prevents such issues.

In particular, it catches invalid reference names passed to 'got ref -l'.
This will also be needed to validate reference names passed to a
future 'gotadmin pack' command which I am working on.

ok?


diff 9069347b693ed2803ca224d77823b2e4e2f2e4e5 /home/stsp/src/got
blob - 4b530db4089bee13c3808f740ec124254aa41fca
file + lib/reference.c
--- lib/reference.c
+++ lib/reference.c
@@ -409,6 +409,9 @@ open_ref(struct got_reference **ref, const char *path_
 
 	*ref = NULL;
 
+	if (!is_valid_ref_name(name))
+		return got_error_path(name, GOT_ERR_BAD_REF_NAME);
+
 	if (ref_is_absolute || ref_is_well_known) {
 		if (asprintf(&path, "%s/%s", path_refs, name) == -1)
 			return got_error_from_errno("asprintf");
blob - f680079f8821648decd0d8f2ee5fb463bf45484a
file + regress/cmdline/ref.sh
--- regress/cmdline/ref.sh
+++ regress/cmdline/ref.sh
@@ -389,10 +389,11 @@ test_ref_list() {
 		fi
 	done
 
-	for r in refs//foo/bar refs//foo//bar refs////////foo//bar; do
-		got ref -r $testroot/repo -l $r > $testroot/stdout
+	for r in /refs/abc refs//foo/bar refs//foo//bar refs////////foo//bar; do
+		got ref -r $testroot/repo -l $r > $testroot/stdout \
+			2> $testroot/stderr
 
-		echo "refs/foo/bar/baz: $commit_id" > $testroot/stdout.expected
+		echo -n > $testroot/stdout.expected
 		cmp -s $testroot/stdout $testroot/stdout.expected
 		ret="$?"
 		if [ "$ret" != "0" ]; then
@@ -400,10 +401,19 @@ test_ref_list() {
 			test_done "$testroot" "$ret"
 			return 1
 		fi
+
+		echo "got: $r: bad reference name" > $testroot/stderr.expected
+		cmp -s $testroot/stderr $testroot/stderr.expected
+		ret="$?"
+		if [ "$ret" != "0" ]; then
+			diff -u $testroot/stderr.expected $testroot/stderr
+			test_done "$testroot" "$ret"
+			return 1
+		fi
 	done
 
 	# attempt to list non-existing references
-	for r in refs/fo bar baz moo riffs /refs/abc refs/foo/bar/baz/moo; do
+	for r in refs/fo bar baz moo riffs refs/abc refs/foo/bar/baz/moo; do
 		got ref -r $testroot/repo -l $r > $testroot/stdout
 
 		echo -n > $testroot/stdout.expected