shithub: git9

Download patch

ref: 92718a91d63cefe61f9f631703c42702861ef8c5
parent: b305bb74762ba253ab2f477c8559605a6525bcc1
author: Ori Bernstein <[email protected]>
date: Sun Aug 30 23:46:56 EDT 2020

git/serve: verify the object we're updating to

We used to allow updating a ref to a hash that didnt'
exist, or wasn't a commit. Stop doing that.

--- a/push
+++ b/push
@@ -18,7 +18,7 @@
 	die 'no branches'
 if(~ $force 1)
 	force=-f
-if(~ $#debug 1)
+if(~ $debug 1)
 	debug='-d'
 
 if(~ $#upstream 0)
--- a/serve.c
+++ b/serve.c
@@ -309,8 +309,8 @@
 	}
 	return 0;
 
-error2://	remove(Idxtmp);
-error1://	remove(Packtmp);
+error2:	remove(Idxtmp);
+error1:	remove(Packtmp);
 	return -1;
 }	
 
@@ -332,6 +332,7 @@
 {
 	char refpath[512];
 	int i, fd, ret, lockfd;
+	Object *o;
 	Hash h;
 
 	ret = -1;
@@ -342,6 +343,15 @@
 	for(i = 0; i < nupd; i++){
 		if(resolveref(&h, ref[i]) == 0 && !hasheq(&h, &cur[i])){
 			fmtpkt(c, "ERR old ref changed: %s", ref[i]);
+			goto error;
+		}
+		if((o = readobject(upd[i])) == nil){
+			fmtpkt(c, "ERR update to nonexistent hash %H", upd[i]);
+			goto error;
+		}
+		unref(o);
+		if(o->type != GCommit){
+			fmtpkt(c, "ERR not commit: %H", upd[i]);
 			goto error;
 		}
 		if(snprint(refpath, sizeof(refpath), ".git/%s", ref[i]) == sizeof(refpath)){