mirror of
https://github.com/moparisthebest/pacman
synced 2024-08-13 17:03:46 -04:00
validate %FILEPATH% when parsing repo dbs
Currently we make no effort to validate the %FILENAME% field in the repo db. This allows for relative paths to be considered valid. A carefully crafted db entry with a malicious relative path, (e.g. `../../../../etc/passwd`) will cause pacman to to overwrite _any_ file on the target's machine. Add the following validation: - doesn't start with '.' - doesn't contain a '/' - won't overflow PATH_MAX Signed-off-by: Simon Gomizelj <simongmzlj@gmail.com> Signed-off-by: Allan McRae <allan@archlinux.org>
This commit is contained in:
parent
fe794ccb25
commit
dd62fde53e
@ -479,6 +479,33 @@ cleanup:
|
||||
return count;
|
||||
}
|
||||
|
||||
/* This function validates %FILENAME%. filename must be between 3 and
|
||||
* PATH_MAX characters and cannot be contain a path */
|
||||
static int _alpm_validate_filename(alpm_db_t *db, const char *pkgname,
|
||||
const char *filename)
|
||||
{
|
||||
size_t len = strlen(filename);
|
||||
|
||||
if(filename[0] == '.') {
|
||||
errno = EINVAL;
|
||||
_alpm_log(db->handle, ALPM_LOG_ERROR, _("%s database is inconsistent: filename "
|
||||
"of package %s is illegal\n"), db->treename, pkgname);
|
||||
return -1;
|
||||
} else if(memchr(filename, '/', len) != NULL) {
|
||||
errno = EINVAL;
|
||||
_alpm_log(db->handle, ALPM_LOG_ERROR, _("%s database is inconsistent: filename "
|
||||
"of package %s is illegal\n"), db->treename, pkgname);
|
||||
return -1;
|
||||
} else if(len > PATH_MAX) {
|
||||
errno = EINVAL;
|
||||
_alpm_log(db->handle, ALPM_LOG_ERROR, _("%s database is inconsistent: filename "
|
||||
"of package %s is too long\n"), db->treename, pkgname);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define READ_NEXT() do { \
|
||||
if(_alpm_archive_fgets(archive, &buf) != ARCHIVE_OK) goto error; \
|
||||
line = buf.line; \
|
||||
@ -558,6 +585,9 @@ static int sync_db_read(alpm_db_t *db, struct archive *archive,
|
||||
}
|
||||
} else if(strcmp(line, "%FILENAME%") == 0) {
|
||||
READ_AND_STORE(pkg->filename);
|
||||
if(_alpm_validate_filename(db, pkg->name, pkg->filename) < 0) {
|
||||
return -1;
|
||||
}
|
||||
} else if(strcmp(line, "%DESC%") == 0) {
|
||||
READ_AND_STORE(pkg->desc);
|
||||
} else if(strcmp(line, "%GROUPS%") == 0) {
|
||||
|
Loading…
Reference in New Issue
Block a user