Radish alpha
H
rad:z3QDZAW2FAfuLvihrhiyDC9fAD8G9
HardenedBSD Package Manager
Radicle
Git
libpkg: Fix database transaction leaks
Mark Johnston committed 2 years ago
commit 65f6aba3717fceec5954f3484f8fb18c522d8fb4
parent a3acd57
4 files changed +32 -17
modified libpkg/backup_lib.c
@@ -43,6 +43,7 @@ register_backup(struct pkgdb *db, int fd, const char *path)
	char *lpath;
	struct stat st;
	pkghash_entry *e;
+
	int retcode;

	sum = pkg_checksum_generate_fileat(fd, RELATIVE_PATH(path), PKG_HASH_TYPE_SHA256_HEX);

@@ -83,8 +84,10 @@ register_backup(struct pkgdb *db, int fd, const char *path)
		if (fstatat(pkg->rootfd, RELATIVE_PATH(f->path), &st, AT_SYMLINK_NOFOLLOW) != -1)
			pkg->flatsize += st.st_size;
	}
-
	pkgdb_register_finale(db, pkgdb_register_pkg(db, pkg, 0, "backuplib"), "backuplib");
-
	return (EPKG_OK);
+
	retcode = pkgdb_register_pkg(db, pkg, 0, "backuplib");
+
	if (retcode == EPKG_OK)
+
		pkgdb_register_finale(db, EPKG_OK, "backuplib");
+
	return (retcode);
}

void
modified libpkg/pkg_add.c
@@ -1208,7 +1208,7 @@ pkg_add_common(struct pkgdb *db, const char *path, unsigned flags,
	struct pkg_message	*msg;
	struct pkg_file		*f;
	const char		*msgstr;
-
	bool			 extract = true;
+
	bool			 extract = true, openxact = false;
	int			 retcode = EPKG_OK;
	int			 ret;
	int			 nfiles;
@@ -1289,12 +1289,14 @@ pkg_add_common(struct pkgdb *db, const char *path, unsigned flags,
		}
	}

-
	/* register the package before installing it in case there are
-
	 * problems that could be caught here. */
+
	/*
+
	 * Register the package before installing it in case there are problems
+
	 * that could be caught here.
+
	 */
	retcode = pkgdb_register_pkg(db, pkg, flags & PKG_ADD_FORCE, NULL);
-

	if (retcode != EPKG_OK)
		goto cleanup;
+
	openxact = true;

	/*
	 * Execute pre-install scripts
@@ -1319,10 +1321,8 @@ pkg_add_common(struct pkgdb *db, const char *path, unsigned flags,
		pkg_unregister_cleanup_callback(pkg_rollback_cb, pkg);
		if (retcode != EPKG_OK) {
			/* If the add failed, clean up (silently) */
-

			pkg_rollback_pkg(pkg);
			pkg_delete_dirs(db, pkg, NULL);
-
			pkgdb_register_finale(db, retcode, NULL);
			goto cleanup;
		}
	}
@@ -1347,6 +1347,8 @@ pkg_add_common(struct pkgdb *db, const char *path, unsigned flags,
	retcode = pkg_extract_finalize(pkg, &tempdirs);

	pkgdb_register_finale(db, retcode, NULL);
+
	openxact = false;
+

	/*
	 * Execute post install scripts
	 */
@@ -1413,6 +1415,8 @@ pkg_add_common(struct pkgdb *db, const char *path, unsigned flags,
	}

cleanup:
+
	if (openxact)
+
		pkgdb_register_finale(db, retcode, NULL);
	if (a != NULL) {
		archive_read_close(a);
		archive_read_free(a);
modified libpkg/pkg_ports.c
@@ -1204,9 +1204,10 @@ pkg_add_port(struct pkgdb *db, struct pkg *pkg, const char *input_path,

	if (db != NULL) {
		rc = pkgdb_register_pkg(db, pkg, 0, NULL);
-

-
		if (rc != EPKG_OK)
+
		if (rc != EPKG_OK) {
+
			db = NULL;
			goto cleanup;
+
		}
	}

	if (!testing) {
modified libpkg/pkgdb.c
@@ -1587,6 +1587,11 @@ prstmt_finalize(struct pkgdb *db)
	return;
}

+
/*
+
 * Register a package in the database.  If successful, the caller is required to
+
 * call pkgdb_register_finale() in order to either commit or roll back the
+
 * transaction.  Otherwise, the caller does not need to do any extra cleanup.
+
 */
int
pkgdb_register_pkg(struct pkgdb *db, struct pkg *pkg, int forced,
    const char *savepoint)
@@ -1889,8 +1894,9 @@ pkgdb_register_pkg(struct pkgdb *db, struct pkg *pkg, int forced,

	retcode = EPKG_OK;

-
	cleanup:
-

+
cleanup:
+
	if (retcode != EPKG_OK)
+
		(void)pkgdb_transaction_rollback_sqlite(s, savepoint);
	free(msg);

	return (retcode);
@@ -2221,7 +2227,9 @@ pkgdb_delete_annotation(struct pkgdb *db, struct pkg *pkg, const char *tag)
	return (rows_changed == 1 ? EPKG_OK : EPKG_WARN);
}

-

+
/*
+
 * Complete a transaction started by pkgdb_register_pkg().
+
 */
int
pkgdb_register_finale(struct pkgdb *db, int retcode, const char *savepoint)
{
@@ -2245,11 +2253,10 @@ pkgdb_register_ports(struct pkgdb *db, struct pkg *pkg)
	pkg_emit_install_begin(pkg);

	ret = pkgdb_register_pkg(db, pkg, 0, NULL);
-
	if (ret == EPKG_OK)
+
	if (ret == EPKG_OK) {
		pkg_emit_install_finished(pkg, NULL);
-

-
	pkgdb_register_finale(db, ret, NULL);
-

+
		pkgdb_register_finale(db, ret, NULL);
+
	}
	return (ret);
}