summaryrefslogtreecommitdiff
path: root/src/audit.c
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 /src/audit.c
parent5aa69984595c8f63899a39cbeae8c86913bfb2d2 (diff)
downloadapk-tools-ea5b08d1d574ae90ad6347a4d2f0a69bb656c7af.tar.gz
apk-tools-ea5b08d1d574ae90ad6347a4d2f0a69bb656c7af.tar.bz2
apk-tools-ea5b08d1d574ae90ad6347a4d2f0a69bb656c7af.tar.xz
apk-tools-ea5b08d1d574ae90ad6347a4d2f0a69bb656c7af.zip
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.
Diffstat (limited to 'src/audit.c')
-rw-r--r--src/audit.c46
1 files changed, 23 insertions, 23 deletions
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;