tech-kern archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: bin/52512: Duplicate files prevent veriexecctl from loading signature file



It is unclear whether we should modify veriexecctl to not set the error for EEXIST, or if we should modify veriexecgen to not generate multiple entries (with different names) for the same file. (It seems to me unreasonable to expect the user to remove the duplicates.)

A third option would be to modify the kernel code to not complain when attempting to add a new entry, as long as the new fingerprint type and value match the existing values.

The attached patch implements this option.

Comments/suggestions welcomed.
Index: kern_veriexec.c
===================================================================
RCS file: /cvsroot/src/sys/kern/kern_veriexec.c,v
retrieving revision 1.14
diff -u -p -r1.14 kern_veriexec.c
--- kern_veriexec.c	29 Aug 2017 10:23:12 -0000	1.14
+++ kern_veriexec.c	29 Aug 2017 10:37:17 -0000
@@ -1050,9 +1050,11 @@ veriexec_file_add(struct lwp *l, prop_di
 {
 	struct veriexec_table_entry *vte;
 	struct veriexec_file_entry *vfe = NULL;
+	struct veriexec_file_entry *ovfe;
 	struct vnode *vp;
 	const char *file, *fp_type;
 	int error;
+	bool ignore_dup = false;
 
 	if (!prop_dictionary_get_cstring_nocopy(dict, "file", &file))
 		return (EINVAL);
@@ -1096,12 +1098,6 @@ veriexec_file_add(struct lwp *l, prop_di
 
 	rw_enter(&veriexec_op_lock, RW_WRITER);
 
-	if (veriexec_get(vp)) {
-		/* We already have an entry for this file. */
-		error = EEXIST;
-		goto unlock_out;
-	}
-
 	/* Continue entry initialization. */
 	if (prop_dictionary_get_uint8(dict, "entry-type", &vfe->type) == FALSE)
 		vfe->type = 0;
@@ -1140,6 +1136,22 @@ veriexec_file_add(struct lwp *l, prop_di
 		vfe->status = status;
 	}
 
+	/*
+	 * If we already have an entry for this file, and it matches
+	 * the new entry exactly (except for the filename, since it
+	 * might be hard-linked!), we just ignore the new entry.  If
+	 * the new entry differs, report the error.
+	 */
+	if ((ovfe = veriexec_get(vp)) != NULL) {
+		error = EEXIST;
+		if (vfe->type == ovfe->type &&
+		    vfe->status == ovfe->status &&
+		    vfe->ops == ovfe->ops &&
+		    memcmp(vfe->fp, ovfe->fp, vfs->ops->hash_len) == 0)
+			ignore_dup = true;
+		goto unlock_out;
+	}
+
 	vte = veriexec_table_lookup(vp->v_mount);
 	if (vte == NULL)
 		vte = veriexec_table_add(l, vp->v_mount);
@@ -1174,6 +1186,9 @@ veriexec_file_add(struct lwp *l, prop_di
 	if (error)
 		veriexec_file_free(vfe);
 
+	if (ignore_dup && error == EEXIST)
+		error = 0;
+
 	return (error);
 }
 


Home | Main Index | Thread Index | Old Index