Do not add root prefix twice when checking database files

When checking .INSTALL and .CHANGELOG files in the mtree file, we need to find
the path they are stored in the local database. This was appending the root
prefix twice as alpm_option_get_dbpath already returns the absolute path to
the database.

While fixing that issue I added checks that the paths for the database files
were not longer than PATH_MAX.

Fixes FS#48563.

Signed-off-by: Allan McRae <allan@archlinux.org>
This commit is contained in:
Allan McRae 2016-03-20 21:23:32 +10:00
parent 4cad2423a3
commit 2ee1706a72
1 changed files with 30 additions and 24 deletions

View File

@ -254,7 +254,6 @@ int check_pkg_full(alpm_pkg_t *pkg)
const char *root, *pkgname; const char *root, *pkgname;
size_t errors = 0; size_t errors = 0;
size_t rootlen; size_t rootlen;
char filepath[PATH_MAX];
struct archive *mtree; struct archive *mtree;
struct archive_entry *entry = NULL; struct archive_entry *entry = NULL;
size_t file_count = 0; size_t file_count = 0;
@ -267,7 +266,6 @@ int check_pkg_full(alpm_pkg_t *pkg)
pm_printf(ALPM_LOG_ERROR, _("path too long: %s%s\n"), root, ""); pm_printf(ALPM_LOG_ERROR, _("path too long: %s%s\n"), root, "");
return 1; return 1;
} }
strcpy(filepath, root);
pkgname = alpm_pkg_get_name(pkg); pkgname = alpm_pkg_get_name(pkg);
mtree = alpm_pkg_mtree_open(pkg); mtree = alpm_pkg_mtree_open(pkg);
@ -282,6 +280,8 @@ int check_pkg_full(alpm_pkg_t *pkg)
while(alpm_pkg_mtree_next(pkg, mtree, &entry) == ARCHIVE_OK) { while(alpm_pkg_mtree_next(pkg, mtree, &entry) == ARCHIVE_OK) {
struct stat st; struct stat st;
const char *path = archive_entry_pathname(entry); const char *path = archive_entry_pathname(entry);
char filepath[PATH_MAX];
int filepath_len;
mode_t type; mode_t type;
size_t file_errors = 0; size_t file_errors = 0;
int backup = 0; int backup = 0;
@ -292,32 +292,38 @@ int check_pkg_full(alpm_pkg_t *pkg)
path += 2; path += 2;
} }
if(strcmp(path, ".INSTALL") == 0) { if(*path == '.') {
char filename[PATH_MAX]; const char *dbfile = NULL;
snprintf(filename, PATH_MAX, "%slocal/%s-%s/install",
alpm_option_get_dbpath(config->handle) + 1, if(strcmp(path, ".INSTALL") == 0) {
pkgname, alpm_pkg_get_version(pkg)); dbfile = "install";
archive_entry_set_pathname(entry, filename); } else if(strcmp(path, ".CHANGELOG") == 0) {
path = archive_entry_pathname(entry); dbfile = "changelog";
} else if(strcmp(path, ".CHANGELOG") == 0) { } else {
char filename[PATH_MAX]; continue;
snprintf(filename, PATH_MAX, "%slocal/%s-%s/changelog", }
alpm_option_get_dbpath(config->handle) + 1,
pkgname, alpm_pkg_get_version(pkg)); /* Do not append root directory as alpm_option_get_dbpath is already
archive_entry_set_pathname(entry, filename); * an absoute path */
path = archive_entry_pathname(entry); filepath_len = snprintf(filepath, PATH_MAX, "%slocal/%s-%s/%s",
} else if(*path == '.') { alpm_option_get_dbpath(config->handle),
continue; pkgname, alpm_pkg_get_version(pkg), dbfile);
if(filepath_len >= PATH_MAX) {
pm_printf(ALPM_LOG_WARNING, _("path too long: %slocal/%s-%s/%s\n"),
alpm_option_get_dbpath(config->handle),
pkgname, alpm_pkg_get_version(pkg), dbfile);
continue;
}
} else {
filepath_len = snprintf(filepath, PATH_MAX, "%s%s", root, path);
if(filepath_len >= PATH_MAX) {
pm_printf(ALPM_LOG_WARNING, _("path too long: %s%s\n"), root, path);
continue;
}
} }
file_count++; file_count++;
if(rootlen + 1 + strlen(path) > PATH_MAX) {
pm_printf(ALPM_LOG_WARNING, _("path too long: %s%s\n"), root, path);
continue;
}
strcpy(filepath + rootlen, path);
exists = check_file_exists(pkgname, filepath, rootlen, &st); exists = check_file_exists(pkgname, filepath, rootlen, &st);
if(exists == 1) { if(exists == 1) {
errors++; errors++;