pkgsrc-Bugs archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
pkg/45077: pkgtools/pkg_install catch circular dependencies in add/perform.c
>Number: 45077
>Category: pkg
>Synopsis: pkgtools/pkg_install catch circular dependencies in
>add/perform.c
>Confidential: no
>Severity: non-critical
>Priority: medium
>Responsible: pkg-manager
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Fri Jun 17 14:30:00 +0000 2011
>Originator: Thomas Cort
>Release: N/A
>Organization:
Minix3
>Environment:
Minix 192.168.122.210 3.2.0 i686
>Description:
During the porting of pkgsrc to Minix, a developer ran into an issue
where the pkg_do() function in add/perform.c would go into an infinite
recursion due to a circular dependency. The dependency issue was caused
by different versions of the pkgsrc tree being used to compile different
packages.
The patch below adds a counter to pkg_do(). Every time pkg_do() gets
called recursively, the counter is incremented. If the counter exceeds
MAX_PKG_DO_RECURSION_DEPTH it is assumed that a circular dependency
has been detected, a warning is printed, and the recursion is stopped.
This patch was moved from pkg/45047 so that the PR would
only deal with one problem.
>How-To-Repeat:
I wasn't able to recreate the conditions that caused the
circular dependency.
>Fix:
--- a/pkg_install/files/add/perform.c Thu Jun 16 19:34:17 2011
+++ b/pkg_install/files/add/perform.c Thu Jun 16 19:38:27 2011
@@ -60,6 +60,8 @@
#include "add.h"
#include "version.h"
+#define MAX_PKG_DO_RECURSION_DEPTH (1024)
+
struct pkg_meta {
char *meta_contents;
char *meta_comment;
@@ -126,7 +128,7 @@
{ 0, NULL, 0, 0 },
};
-static int pkg_do(const char *, int, int);
+static int pkg_do(const char *, int, int, int);
static int
end_of_version(const char *opsys, const char *version_end)
@@ -738,7 +740,7 @@
continue;
case PLIST_CMD:
- if (format_cmd(cmd, sizeof(cmd), p->name, pkg->prefix,
last_file))
+ if (format_cmd(cmd, sizeof(cmd), p->name,
pkg->install_prefix, last_file))
return -1;
printf("Executing '%s'\n", cmd);
if (!Fake && system(cmd))
@@ -1093,7 +1095,7 @@
}
static int
-check_dependencies(struct pkg_task *pkg)
+check_dependencies(struct pkg_task *pkg, int depth)
{
plist_t *p;
char *best_installed;
@@ -1124,7 +1126,7 @@
p->name);
continue;
}
- if (pkg_do(p->name, 1, 0)) {
+ if (pkg_do(p->name, 1, 0, depth)) {
if (ForceDepends) {
warnx("Can't install dependency %s, "
"continuing", p->name);
@@ -1373,12 +1375,17 @@
* Install a single package.
*/
static int
-pkg_do(const char *pkgpath, int mark_automatic, int top_level)
+pkg_do(const char *pkgpath, int mark_automatic, int top_level, int depth)
{
char *archive_name;
int status, invalid_sig;
struct pkg_task *pkg;
+ if (++depth > MAX_PKG_DO_RECURSION_DEPTH) {
+ warnx("circular dependency detected");
+ return -1;
+ }
+
pkg = xcalloc(1, sizeof(*pkg));
status = -1;
@@ -1490,7 +1497,7 @@
pkg->install_logdir_real = NULL;
}
- if (check_dependencies(pkg))
+ if (check_dependencies(pkg, depth))
goto nuke_pkgdb;
} else {
/*
@@ -1498,7 +1505,7 @@
* Install/update dependencies first and
* write the current package to disk afterwards.
*/
- if (check_dependencies(pkg))
+ if (check_dependencies(pkg, depth))
goto clean_memory;
if (write_meta_data(pkg))
@@ -1582,7 +1589,7 @@
lpkg_t *lpp;
while ((lpp = TAILQ_FIRST(pkgs)) != NULL) {
- if (pkg_do(lpp->lp_name, Automatic, 1))
+ if (pkg_do(lpp->lp_name, Automatic, 1, 0))
++errors;
TAILQ_REMOVE(pkgs, lpp, lp_link);
free_lpkg(lpp);
Home |
Main Index |
Thread Index |
Old Index