[ostree] core: Validate structure of objects in fsck
- From: Colin Walters <walters src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [ostree] core: Validate structure of objects in fsck
- Date: Wed, 4 Apr 2012 03:10:42 +0000 (UTC)
commit 8792007bc10ebb74ab009059e2edc69a1f9cdd61
Author: Colin Walters <walters verbum org>
Date: Tue Apr 3 08:52:58 2012 -0400
core: Validate structure of objects in fsck
src/libostree/ostree-core.c | 205 +++++++++++++++++++++++++++++++++++++-----
src/libostree/ostree-core.h | 21 ++++-
src/ostree/ot-builtin-fsck.c | 23 +++++
3 files changed, 222 insertions(+), 27 deletions(-)
---
diff --git a/src/libostree/ostree-core.c b/src/libostree/ostree-core.c
index 06897a2..947bc6d 100644
--- a/src/libostree/ostree-core.c
+++ b/src/libostree/ostree-core.c
@@ -35,30 +35,7 @@ gboolean
ostree_validate_checksum_string (const char *sha256,
GError **error)
{
- int i = 0;
- size_t len = strlen (sha256);
-
- if (len != 64)
- {
- g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
- "Invalid rev '%s'", sha256);
- return FALSE;
- }
-
- for (i = 0; i < len; i++)
- {
- guint8 c = ((guint8*) sha256)[i];
-
- if (!((c >= 48 && c <= 57)
- || (c >= 97 && c <= 102)))
- {
- g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
- "Invalid character '%d' in rev '%s'",
- c, sha256);
- return FALSE;
- }
- }
- return TRUE;
+ return ostree_validate_structureof_checksum_string (sha256, error);
}
gboolean
@@ -1477,6 +1454,36 @@ ostree_validate_structureof_checksum (GVariant *checksum,
return TRUE;
}
+gboolean
+ostree_validate_structureof_checksum_string (const char *checksum,
+ GError **error)
+{
+ int i = 0;
+ size_t len = strlen (checksum);
+
+ if (len != 64)
+ {
+ g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
+ "Invalid rev '%s'", checksum);
+ return FALSE;
+ }
+
+ for (i = 0; i < len; i++)
+ {
+ guint8 c = ((guint8*) checksum)[i];
+
+ if (!((c >= 48 && c <= 57)
+ || (c >= 97 && c <= 102)))
+ {
+ g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
+ "Invalid character '%d' in rev '%s'",
+ c, checksum);
+ return FALSE;
+ }
+ }
+ return TRUE;
+}
+
static gboolean
validate_variant (GVariant *variant,
const GVariantType *variant_type,
@@ -1499,6 +1506,156 @@ validate_variant (GVariant *variant,
}
gboolean
+ostree_validate_structureof_commit (GVariant *commit,
+ GError **error)
+{
+ gboolean ret = FALSE;
+ const char *parent;
+ const char *contents;
+ const char *metadata;
+
+ if (!validate_variant (commit, OSTREE_COMMIT_GVARIANT_FORMAT, error))
+ goto out;
+
+ g_variant_get_child (commit, 2, "&s", &parent);
+
+ if (*parent)
+ {
+ if (!ostree_validate_structureof_checksum_string (parent, error))
+ goto out;
+ }
+
+ g_variant_get_child (commit, 6, "&s", &contents);
+ if (!ostree_validate_structureof_checksum_string (contents, error))
+ goto out;
+
+ g_variant_get_child (commit, 7, "&s", &metadata);
+ if (!ostree_validate_structureof_checksum_string (metadata, error))
+ goto out;
+
+ ret = TRUE;
+ out:
+ return ret;
+}
+
+gboolean
+ostree_validate_structureof_dirtree (GVariant *dirtree,
+ GError **error)
+{
+ gboolean ret = FALSE;
+ GVariantIter *contents_iter = NULL;
+ const char *filename;
+ const char *meta_checksum;
+ const char *content_checksum;
+
+ if (!validate_variant (dirtree, OSTREE_TREE_GVARIANT_FORMAT, error))
+ goto out;
+
+ g_variant_get_child (dirtree, 2, "a(ss)", &contents_iter);
+
+ while (g_variant_iter_loop (contents_iter, "(&s&s)",
+ &filename, &content_checksum))
+ {
+ if (!ot_util_filename_validate (filename, error))
+ goto out;
+ if (!ostree_validate_structureof_checksum_string (content_checksum, error))
+ goto out;
+ }
+
+ g_variant_iter_free (contents_iter);
+ g_variant_get_child (dirtree, 3, "a(sss)", &contents_iter);
+
+ while (g_variant_iter_loop (contents_iter, "(&s&s&s)",
+ &filename, &content_checksum, &meta_checksum))
+ {
+ if (!ot_util_filename_validate (filename, error))
+ goto out;
+ if (!ostree_validate_structureof_checksum_string (content_checksum, error))
+ goto out;
+ if (!ostree_validate_structureof_checksum_string (meta_checksum, error))
+ goto out;
+ }
+
+ ret = TRUE;
+ out:
+ if (contents_iter)
+ g_variant_iter_free (contents_iter);
+ return ret;
+}
+
+static gboolean
+validate_stat_mode_perms (guint32 mode,
+ GError **error)
+{
+ gboolean ret = FALSE;
+ guint32 otherbits = (~S_IFMT & ~S_IRWXU & ~S_IRWXG & ~S_IRWXO);
+
+ if (mode & otherbits)
+ {
+ g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
+ "Invalid mode %u; invalid bits in mode", mode);
+ goto out;
+ }
+
+ ret = TRUE;
+ out:
+ return ret;
+}
+
+gboolean
+ostree_validate_structureof_file_mode (guint32 mode,
+ GError **error)
+{
+ gboolean ret = FALSE;
+
+ if (!(S_ISREG (mode)
+ || S_ISLNK (mode)
+ || S_ISCHR (mode)
+ || S_ISBLK (mode)
+ || S_ISFIFO (mode)))
+ {
+ g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
+ "Invalid file metadata mode %u; not a valid file type", mode);
+ goto out;
+ }
+
+ if (!validate_stat_mode_perms (mode, error))
+ goto out;
+
+ ret = TRUE;
+ out:
+ return ret;
+}
+
+gboolean
+ostree_validate_structureof_dirmeta (GVariant *dirmeta,
+ GError **error)
+{
+ gboolean ret = FALSE;
+ guint32 mode;
+
+ if (!validate_variant (dirmeta, OSTREE_DIRMETA_GVARIANT_FORMAT, error))
+ goto out;
+
+ g_variant_get_child (dirmeta, 3, "u", &mode);
+ mode = GUINT32_FROM_BE (mode);
+
+ if (!S_ISDIR (mode))
+ {
+ g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
+ "Invalid directory metadata mode %u; not a directory", mode);
+ goto out;
+ }
+
+ if (!validate_stat_mode_perms (mode, error))
+ goto out;
+
+ ret = TRUE;
+ out:
+ return ret;
+}
+
+gboolean
ostree_validate_structureof_pack_index (GVariant *index,
GError **error)
{
diff --git a/src/libostree/ostree-core.h b/src/libostree/ostree-core.h
index e733f51..1df8a6a 100644
--- a/src/libostree/ostree-core.h
+++ b/src/libostree/ostree-core.h
@@ -60,7 +60,7 @@ typedef enum {
* u - mode
* a(ayay) - xattrs
*/
-#define OSTREE_DIRMETA_GVARIANT_FORMAT "(uuuua(ayay))"
+#define OSTREE_DIRMETA_GVARIANT_FORMAT G_VARIANT_TYPE ("(uuuua(ayay))")
#define OSTREE_TREE_VERSION 0
/*
@@ -70,7 +70,7 @@ typedef enum {
* a(ss) - array of (filename, checksum) for files
* a(sss) - array of (dirname, tree_checksum, meta_checksum) for directories
*/
-#define OSTREE_TREE_GVARIANT_FORMAT "(ua{sv}a(ss)a(sss)"
+#define OSTREE_TREE_GVARIANT_FORMAT G_VARIANT_TYPE ("(ua{sv}a(ss)a(sss))")
#define OSTREE_COMMIT_VERSION 0
/*
@@ -84,7 +84,7 @@ typedef enum {
* s - Root tree contents
* s - Root tree metadata
*/
-#define OSTREE_COMMIT_GVARIANT_FORMAT "(ua{sv}ssstss)"
+#define OSTREE_COMMIT_GVARIANT_FORMAT G_VARIANT_TYPE ("(ua{sv}ssstss)")
/* Archive file objects:
* u - Version
@@ -300,6 +300,21 @@ gboolean ostree_validate_structureof_objtype (guint32 objtype,
gboolean ostree_validate_structureof_checksum (GVariant *checksum,
GError **error);
+gboolean ostree_validate_structureof_checksum_string (const char *checksum,
+ GError **error);
+
+gboolean ostree_validate_structureof_file_mode (guint32 mode,
+ GError **error);
+
+gboolean ostree_validate_structureof_commit (GVariant *index,
+ GError **error);
+
+gboolean ostree_validate_structureof_dirtree (GVariant *index,
+ GError **error);
+
+gboolean ostree_validate_structureof_dirmeta (GVariant *index,
+ GError **error);
+
gboolean ostree_validate_structureof_pack_index (GVariant *index,
GError **error);
diff --git a/src/ostree/ot-builtin-fsck.c b/src/ostree/ot-builtin-fsck.c
index 5b9b964..ee45dc3 100644
--- a/src/ostree/ot-builtin-fsck.c
+++ b/src/ostree/ot-builtin-fsck.c
@@ -200,6 +200,24 @@ fsck_reachable_objects_from_commits (OtFsckData *data,
if (!ostree_repo_load_variant (data->repo, objtype,
checksum, &metadata, error))
goto out;
+
+ if (objtype == OSTREE_OBJECT_TYPE_COMMIT)
+ {
+ if (!ostree_validate_structureof_commit (metadata, error))
+ goto out;
+ }
+ else if (objtype == OSTREE_OBJECT_TYPE_DIR_TREE)
+ {
+ if (!ostree_validate_structureof_dirtree (metadata, error))
+ goto out;
+ }
+ else if (objtype == OSTREE_OBJECT_TYPE_DIR_META)
+ {
+ if (!ostree_validate_structureof_dirmeta (metadata, error))
+ goto out;
+ }
+ else
+ g_assert_not_reached ();
ot_clear_gvariant (&metadata_wrapped);
metadata_wrapped = ostree_wrap_metadata_variant (objtype, metadata);
@@ -216,10 +234,15 @@ fsck_reachable_objects_from_commits (OtFsckData *data,
else if (objtype == OSTREE_OBJECT_TYPE_RAW_FILE
|| objtype == OSTREE_OBJECT_TYPE_ARCHIVED_FILE_META)
{
+ guint32 mode;
if (!ostree_repo_load_file (data->repo, checksum, &input, &file_info,
&xattrs, cancellable, error))
goto out;
checksum_objtype = OSTREE_OBJECT_TYPE_RAW_FILE; /* Override */
+
+ mode = g_file_info_get_attribute_uint32 (file_info, "unix::mode");
+ if (!ostree_validate_structureof_file_mode (mode, error))
+ goto out;
}
else
{
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]