Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[RFC] lib: don't allow xbps self-update to bypass integrity checks #597

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from
Draft
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
119 changes: 1 addition & 118 deletions lib/transaction_ops.c
Original file line number Diff line number Diff line change
Expand Up @@ -222,80 +222,6 @@ trans_find_pkg(struct xbps_handle *xhp, const char *pkg, bool force)
return 0;
}

/*
* Returns 1 if there's an update, 0 if none or -1 on error.
*/
static int
xbps_autoupdate(struct xbps_handle *xhp)
{
xbps_array_t rdeps;
xbps_dictionary_t pkgd;
const char *pkgver = NULL, *pkgname = NULL;
int rv;

/*
* Check if there's a new update for XBPS before starting
* another transaction.
*/
if (((pkgd = xbps_pkgdb_get_pkg(xhp, "xbps")) == NULL) &&
((pkgd = xbps_pkgdb_get_virtualpkg(xhp, "xbps")) == NULL))
return 0;

if (!xbps_dictionary_get_cstring_nocopy(pkgd, "pkgver", &pkgver)) {
return EINVAL;
}
if (!xbps_dictionary_get_cstring_nocopy(pkgd, "pkgname", &pkgname)) {
return EINVAL;
}

rv = trans_find_pkg(xhp, pkgname, false);

xbps_dbg_printf("%s: trans_find_pkg xbps: %d\n", __func__, rv);

if (rv == 0) {
if (xhp->flags & XBPS_FLAG_DOWNLOAD_ONLY) {
return 0;
}
/* a new xbps version is available, check its revdeps */
rdeps = xbps_pkgdb_get_pkg_revdeps(xhp, "xbps");
for (unsigned int i = 0; i < xbps_array_count(rdeps); i++) {
const char *curpkgver = NULL;
char curpkgn[XBPS_NAME_SIZE] = {0};

xbps_array_get_cstring_nocopy(rdeps, i, &curpkgver);
xbps_dbg_printf("%s: processing revdep %s\n", __func__, curpkgver);

if (!xbps_pkg_name(curpkgn, sizeof(curpkgn), curpkgver)) {
abort();
}
rv = trans_find_pkg(xhp, curpkgn, false);
xbps_dbg_printf("%s: trans_find_pkg revdep %s: %d\n", __func__, curpkgver, rv);
if (rv && rv != ENOENT && rv != EEXIST && rv != ENODEV)
return -1;
}
/*
* Set XBPS_FLAG_FORCE_REMOVE_REVDEPS to ignore broken
* reverse dependencies in xbps_transaction_prepare().
*
* This won't skip revdeps of the xbps pkg, rather other
* packages in rootdir that could be broken indirectly.
*
* A sysup transaction after updating xbps should fix them
* again.
*/
xhp->flags |= XBPS_FLAG_FORCE_REMOVE_REVDEPS;
return 1;
} else if (rv == ENOENT || rv == EEXIST || rv == ENODEV) {
/* no update */
return 0;
} else {
/* error */
return -1;
}

return 0;
}

int
xbps_transaction_update_packages(struct xbps_handle *xhp)
{
Expand All @@ -305,19 +231,7 @@ xbps_transaction_update_packages(struct xbps_handle *xhp)
bool newpkg_found = false;
int rv = 0;

rv = xbps_autoupdate(xhp);
switch (rv) {
case 1:
/* xbps needs to be updated, don't allow any other update */
return EBUSY;
case -1:
/* error */
return EINVAL;
default:
break;
}

iter = xbps_dictionary_iterator(xhp->pkgdb);
iter = xbps_pkgdb_init(xhp) == 0 ? xbps_dictionary_iterator(xhp->pkgdb) : NULL;
assert(iter);

while ((obj = xbps_object_iterator_next(iter))) {
Expand Down Expand Up @@ -355,22 +269,6 @@ xbps_transaction_update_pkg(struct xbps_handle *xhp, const char *pkg, bool force
xbps_array_t rdeps;
int rv;

rv = xbps_autoupdate(xhp);
xbps_dbg_printf("%s: xbps_autoupdate %d\n", __func__, rv);
switch (rv) {
case 1:
/* xbps needs to be updated, only allow xbps to be updated */
if (strcmp(pkg, "xbps"))
return EBUSY;
return 0;
case -1:
/* error */
return EINVAL;
default:
/* no update */
break;
}

/* update its reverse dependencies */
rdeps = xbps_pkgdb_get_pkg_revdeps(xhp, pkg);
if (xhp->flags & XBPS_FLAG_DOWNLOAD_ONLY) {
Expand Down Expand Up @@ -406,21 +304,6 @@ xbps_transaction_install_pkg(struct xbps_handle *xhp, const char *pkg, bool forc
xbps_array_t rdeps;
int rv;

rv = xbps_autoupdate(xhp);
switch (rv) {
case 1:
/* xbps needs to be updated, only allow xbps to be updated */
if (strcmp(pkg, "xbps"))
return EBUSY;
return 0;
case -1:
/* error */
return EINVAL;
default:
/* no update */
break;
}

/* update its reverse dependencies */
rdeps = xbps_pkgdb_get_pkg_revdeps(xhp, pkg);
if (xhp->flags & XBPS_FLAG_DOWNLOAD_ONLY) {
Expand Down
Loading