DragonFlyBSD Kernel Audit
DF-2666 / fix.diff
← back to finding ↓ download raw
--- a/sys/vfs/hammer2/hammer2_ioctl.c
+++ b/sys/vfs/hammer2/hammer2_ioctl.c
@@ -209,27 +209,30 @@ static int
 hammer2_ioctl_recluster(hammer2_inode_t *ip, void *data)
 {
 	hammer2_ioc_recluster_t *recl = data;
 	struct vnode *vproot;
 	struct file *fp;
 	hammer2_cluster_t *cluster;
 	int error;
 
 	fp = holdfp(curthread, recl->fd, -1);
 	if (fp) {
 		error = VFS_ROOT(ip->pmp->mp, &vproot);
 		if (error == 0) {
 			cluster = &ip->pmp->iroot->cluster;
 			if (cluster->focus != NULL) {
 				hammer2_cluster_reconnect(cluster->focus->hmp,
 							  fp);
 				error = 0;
 			} else if (cluster->nchains == 1 &&
 				   cluster->array[0].chain != NULL) {
 				hammer2_cluster_reconnect(
 					cluster->array[0].chain->hmp, fp);
 				error = 0;
 			} else {
 				kprintf("hammer2: recluster: "
 					"nchains=%d focus=%p\n",
 					cluster->nchains, cluster->focus);
 				error = EINVAL;
 			}
 			vput(vproot);
 		}
+		if (error)
+			fdrop(fp);	/* ref not transferred on failure */
 	} else {
 		error = EINVAL;
 	}
 	return error;
 }