db, fix: more secure way to choose effective directory permissions
And implement --directory-permissions for fix-applet to reset all directory uid, gid and modes.cute-signatures
parent
f2e41a488e
commit
9ac8d87102
|
@ -38,6 +38,8 @@ static int audit_file(struct apk_database *db, struct apk_db_file *dbf,
|
||||||
if (S_ISLNK(fi.mode) && dbf->csum.type == APK_CHECKSUM_NONE)
|
if (S_ISLNK(fi.mode) && dbf->csum.type == APK_CHECKSUM_NONE)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
/* FIXME: check uid/gid/mode; but they are not in DB */
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -74,8 +76,10 @@ static int audit_directory(apk_hash_item item, void *ctx)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (S_ISDIR(fi.mode)) {
|
if (S_ISDIR(fi.mode)) {
|
||||||
if (apk_db_dir_query(db, APK_BLOB_STR(tmp)) != NULL)
|
if (apk_db_dir_query(db, APK_BLOB_STR(tmp)) != NULL) {
|
||||||
|
/* FIXME: check uid/gid/mode */
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
reason = 'D';
|
reason = 'D';
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -220,6 +220,13 @@ struct apk_name *apk_db_get_name(struct apk_database *db, apk_blob_t name)
|
||||||
|
|
||||||
static void apk_db_dir_mkdir(struct apk_database *db, struct apk_db_dir *dir)
|
static void apk_db_dir_mkdir(struct apk_database *db, struct apk_db_dir *dir)
|
||||||
{
|
{
|
||||||
|
if (apk_flags & APK_SIMULATE)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* Don't mess with root, as no package provides it directly */
|
||||||
|
if (dir->namelen == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
if ((dir->refs == 1) ||
|
if ((dir->refs == 1) ||
|
||||||
(fchmodat(db->root_fd, dir->name, dir->mode, AT_SYMLINK_NOFOLLOW) != 0 &&
|
(fchmodat(db->root_fd, dir->name, dir->mode, AT_SYMLINK_NOFOLLOW) != 0 &&
|
||||||
errno == ENOENT))
|
errno == ENOENT))
|
||||||
|
@ -363,19 +370,14 @@ static void apk_db_dir_apply_diri_permissions(struct apk_db_dir_instance *diri)
|
||||||
{
|
{
|
||||||
struct apk_db_dir *dir = diri->dir;
|
struct apk_db_dir *dir = diri->dir;
|
||||||
|
|
||||||
if (diri->uid < dir->uid) {
|
if (diri->uid < dir->uid ||
|
||||||
|
(diri->uid == dir->uid && diri->gid < dir->gid)) {
|
||||||
dir->uid = diri->uid;
|
dir->uid = diri->uid;
|
||||||
dir->mode = (dir->mode & ~S_IRWXU) | (diri->mode & S_IRWXU);
|
|
||||||
} else if (diri->uid == dir->uid) {
|
|
||||||
dir->mode |= diri->mode & S_IRWXU;
|
|
||||||
}
|
|
||||||
if (diri->gid < dir->gid) {
|
|
||||||
dir->gid = diri->gid;
|
dir->gid = diri->gid;
|
||||||
dir->mode = (dir->mode & ~S_IRWXG) | (diri->mode & S_IRWXG);
|
dir->mode = diri->mode;
|
||||||
} else if (diri->gid == dir->gid) {
|
} else if (diri->uid == dir->uid && diri->gid == dir->gid) {
|
||||||
dir->mode |= diri->mode & S_IRWXG;
|
dir->mode &= diri->mode;
|
||||||
}
|
}
|
||||||
dir->mode |= diri->mode & S_IRWXO;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void apk_db_diri_set(struct apk_db_dir_instance *diri, mode_t mode,
|
static void apk_db_diri_set(struct apk_db_dir_instance *diri, mode_t mode,
|
||||||
|
|
15
src/fix.c
15
src/fix.c
|
@ -21,6 +21,7 @@
|
||||||
struct fix_ctx {
|
struct fix_ctx {
|
||||||
unsigned short solver_flags;
|
unsigned short solver_flags;
|
||||||
int fix_depends : 1;
|
int fix_depends : 1;
|
||||||
|
int fix_directory_permissions : 1;
|
||||||
};
|
};
|
||||||
|
|
||||||
static int fix_parse(void *pctx, struct apk_db_options *dbopts,
|
static int fix_parse(void *pctx, struct apk_db_options *dbopts,
|
||||||
|
@ -37,12 +38,22 @@ static int fix_parse(void *pctx, struct apk_db_options *dbopts,
|
||||||
case 'r':
|
case 'r':
|
||||||
ctx->solver_flags |= APK_SOLVERF_REINSTALL;
|
ctx->solver_flags |= APK_SOLVERF_REINSTALL;
|
||||||
break;
|
break;
|
||||||
|
case 0x10000:
|
||||||
|
ctx->fix_directory_permissions = 1;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int mark_recalculate(apk_hash_item item, void *ctx)
|
||||||
|
{
|
||||||
|
struct apk_db_dir *dir = (struct apk_db_dir *) item;
|
||||||
|
dir->flags |= APK_DBDIRF_RECALC_MODE;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int fix_main(void *pctx, struct apk_database *db, int argc, char **argv)
|
static int fix_main(void *pctx, struct apk_database *db, int argc, char **argv)
|
||||||
{
|
{
|
||||||
struct fix_ctx *ctx = (struct fix_ctx *) pctx;
|
struct fix_ctx *ctx = (struct fix_ctx *) pctx;
|
||||||
|
@ -53,6 +64,9 @@ static int fix_main(void *pctx, struct apk_database *db, int argc, char **argv)
|
||||||
if (!ctx->solver_flags)
|
if (!ctx->solver_flags)
|
||||||
ctx->solver_flags = APK_SOLVERF_REINSTALL;
|
ctx->solver_flags = APK_SOLVERF_REINSTALL;
|
||||||
|
|
||||||
|
if (ctx->fix_directory_permissions)
|
||||||
|
apk_hash_foreach(&db->installed.dirs, mark_recalculate, db);
|
||||||
|
|
||||||
for (i = 0; i < argc; i++) {
|
for (i = 0; i < argc; i++) {
|
||||||
pkg = NULL;
|
pkg = NULL;
|
||||||
if (strstr(argv[i], ".apk") != NULL) {
|
if (strstr(argv[i], ".apk") != NULL) {
|
||||||
|
@ -95,6 +109,7 @@ static struct apk_option fix_options[] = {
|
||||||
{ 'd', "depends", "Fix all dependencies too" },
|
{ 'd', "depends", "Fix all dependencies too" },
|
||||||
{ 'u', "upgrade", "Upgrade package if possible" },
|
{ 'u', "upgrade", "Upgrade package if possible" },
|
||||||
{ 'r', "reinstall", "Reinstall the package" },
|
{ 'r', "reinstall", "Reinstall the package" },
|
||||||
|
{ 0x10000, "directory-permissions", "Reset all directory permissions" },
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct apk_applet apk_fix = {
|
static struct apk_applet apk_fix = {
|
||||||
|
|
Loading…
Reference in New Issue