aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTimo Teräs <timo.teras@iki.fi>2012-07-16 14:44:15 +0300
committerTimo Teräs <timo.teras@iki.fi>2012-07-16 14:44:15 +0300
commitea5b08d1d574ae90ad6347a4d2f0a69bb656c7af (patch)
treeaf262b5e75472a38ff9f618afa71220ac8349698
parent5aa69984595c8f63899a39cbeae8c86913bfb2d2 (diff)
downloadapk-tools-ea5b08d1d574ae90ad6347a4d2f0a69bb656c7af.tar.bz2
apk-tools-ea5b08d1d574ae90ad6347a4d2f0a69bb656c7af.tar.xz
audit: fix protection mask of non-db directories
If a directory has protection mask, but does not exist in db, we do not handle it right unless we calculate the protection mask by hand, or create temporary db dir entry for it. For simplicity create always the db dir entry -- depending on audit type we likely need to create it anyway. This commit also caches the db dir entry in the audit tree context to avoid duplicate lookups. ref #1241.
-rw-r--r--src/apk_database.h2
-rw-r--r--src/audit.c46
-rw-r--r--src/database.c5
3 files changed, 27 insertions, 26 deletions
diff --git a/src/apk_database.h b/src/apk_database.h
index 7b1d20d..235030c 100644
--- a/src/apk_database.h
+++ b/src/apk_database.h
@@ -173,6 +173,8 @@ struct apk_name *apk_db_get_name(struct apk_database *db, apk_blob_t name);
struct apk_name *apk_db_query_name(struct apk_database *db, apk_blob_t name);
int apk_db_get_tag_id(struct apk_database *db, apk_blob_t tag);
+struct apk_db_dir *apk_db_dir_ref(struct apk_db_dir *dir);
+void apk_db_dir_unref(struct apk_database *db, struct apk_db_dir *dir, int allow_rmdir);
struct apk_db_dir *apk_db_dir_get(struct apk_database *db, apk_blob_t name);
struct apk_db_dir *apk_db_dir_query(struct apk_database *db, apk_blob_t name);
struct apk_db_file *apk_db_file_query(struct apk_database *db,
diff --git a/src/audit.c b/src/audit.c
index 3a7cd3c..a3382a3 100644
--- a/src/audit.c
+++ b/src/audit.c
@@ -62,6 +62,7 @@ static int audit_parse(void *ctx, struct apk_db_options *dbopts,
struct audit_tree_ctx {
struct audit_ctx *actx;
struct apk_database *db;
+ struct apk_db_dir *dir;
size_t pathlen;
char path[PATH_MAX];
};
@@ -144,17 +145,13 @@ static int audit_directory_tree_item(void *ctx, int dirfd, const char *name)
apk_blob_t bfull;
struct audit_ctx *actx = atctx->actx;
struct apk_database *db = atctx->db;
- struct apk_db_dir *dbd;
+ struct apk_db_dir *dir = atctx->dir, *child = NULL;
struct apk_file_info fi;
int reason = 0;
if (bdir.len + bent.len + 1 >= sizeof(atctx->path))
return -ENOMEM;
- dbd = apk_db_dir_get(db, bdir);
- if (dbd == NULL)
- return -ENOMEM;
-
if (apk_file_get_info(dirfd, name, APK_FI_NOFOLLOW, &fi) < 0)
return -EPERM;
@@ -163,26 +160,20 @@ static int audit_directory_tree_item(void *ctx, int dirfd, const char *name)
bfull = APK_BLOB_PTR_LEN(atctx->path, atctx->pathlen);
if (S_ISDIR(fi.mode)) {
- struct apk_db_dir *child;
int recurse = TRUE;
- child = apk_db_dir_query(db, bfull);
- if (child != NULL) {
- if (actx->mode == MODE_BACKUP) {
- if (!child->has_protected_children)
- recurse = FALSE;
- if (!child->protected)
- goto recurse_check;
- }
+ if (actx->mode == MODE_BACKUP) {
+ child = apk_db_dir_get(db, bfull);
+ if (!child->has_protected_children)
+ recurse = FALSE;
+ if (!child->protected)
+ goto recurse_check;
} else {
- if (actx->mode == MODE_BACKUP) {
- if (!dbd->has_protected_children)
- recurse = FALSE;
- if (!dbd->protected)
- goto recurse_check;
- } else {
+ child = apk_db_dir_query(db, bfull);
+ if (child == NULL)
recurse = FALSE;
- }
+ else
+ child = apk_db_dir_ref(child);
}
reason = audit_directory(actx, db, child, &fi);
@@ -200,16 +191,18 @@ recurse_check:
bfull.len++;
report_audit(actx, reason, bfull, NULL);
if (recurse) {
+ atctx->dir = child;
reason = apk_dir_foreach_file(
openat(dirfd, name, O_RDONLY|O_CLOEXEC),
audit_directory_tree_item, atctx);
+ atctx->dir = dir;
}
bfull.len--;
atctx->pathlen--;
} else {
struct apk_db_file *dbf;
- struct apk_protected_path_array *ppaths = dbd->protected_paths;
- int i, protected = dbd->protected, symlinks_only = dbd->symlinks_only;
+ struct apk_protected_path_array *ppaths = dir->protected_paths;
+ int i, protected = dir->protected, symlinks_only = dir->symlinks_only;
/* inherit file's protection mask */
for (i = 0; i < ppaths->num; i++) {
@@ -243,6 +236,9 @@ recurse_check:
}
done:
+ if (child)
+ apk_db_dir_unref(db, child, FALSE);
+
atctx->pathlen -= bent.len;
return reason < 0 ? reason : 0;
}
@@ -258,7 +254,9 @@ static int audit_main(void *ctx, struct apk_database *db, int argc, char **argv)
atctx.path[0] = 0;
if (argc == 0) {
+ atctx.dir = apk_db_dir_get(db, APK_BLOB_PTR_LEN(atctx.path, atctx.pathlen));
r = apk_dir_foreach_file(dup(db->root_fd), audit_directory_tree_item, &atctx);
+ apk_db_dir_unref(db, atctx.dir, FALSE);
} else {
for (i = 0; i < argc; i++) {
if (argv[i][0] != '/') {
@@ -272,9 +270,11 @@ static int audit_main(void *ctx, struct apk_database *db, int argc, char **argv)
if (atctx.path[atctx.pathlen-1] != '/')
atctx.path[atctx.pathlen++] = '/';
+ atctx.dir = apk_db_dir_get(db, APK_BLOB_PTR_LEN(atctx.path, atctx.pathlen));
r |= apk_dir_foreach_file(
openat(db->root_fd, argv[i], O_RDONLY|O_CLOEXEC),
audit_directory_tree_item, &atctx);
+ apk_db_dir_unref(db, atctx.dir, FALSE);
}
}
return r;
diff --git a/src/database.c b/src/database.c
index bcc707f..efff29f 100644
--- a/src/database.c
+++ b/src/database.c
@@ -240,8 +240,7 @@ static void apk_db_dir_mkdir(struct apk_database *db, struct apk_db_dir *dir)
;
}
-static void apk_db_dir_unref(struct apk_database *db, struct apk_db_dir *dir,
- int allow_rmdir)
+void apk_db_dir_unref(struct apk_database *db, struct apk_db_dir *dir, int allow_rmdir)
{
dir->refs--;
if (dir->refs > 0) {
@@ -274,7 +273,7 @@ static void apk_db_dir_unref(struct apk_database *db, struct apk_db_dir *dir,
apk_db_dir_unref(db, dir->parent, allow_rmdir);
}
-static struct apk_db_dir *apk_db_dir_ref(struct apk_db_dir *dir)
+struct apk_db_dir *apk_db_dir_ref(struct apk_db_dir *dir)
{
dir->refs++;
return dir;