X-Git-Url: http://git.annexia.org/?p=libguestfs.git;a=blobdiff_plain;f=src%2Finspect_fs_unix.c;h=3046e026fa9b2a58a3347bfc29b2a5612a6e0c4a;hp=6b1a05baabb2f48d194e3244e7666684e59c3c70;hb=373dca7d12a8741e116205b4a3ac67a7d82cc782;hpb=6aa3ece129d04a588ceb161c4b203a20664ddcd8 diff --git a/src/inspect_fs_unix.c b/src/inspect_fs_unix.c index 6b1a05b..3046e02 100644 --- a/src/inspect_fs_unix.c +++ b/src/inspect_fs_unix.c @@ -143,7 +143,7 @@ static int check_fstab (guestfs_h *g, struct inspect_fs *fs); static int add_fstab_entry (guestfs_h *g, struct inspect_fs *fs, const char *spec, const char *mp); static char *resolve_fstab_device (guestfs_h *g, const char *spec); -static int inspect_with_augeas (guestfs_h *g, struct inspect_fs *fs, const char *filename, int (*f) (guestfs_h *, struct inspect_fs *)); +static int inspect_with_augeas (guestfs_h *g, struct inspect_fs *fs, const char **configfiles, int (*f) (guestfs_h *, struct inspect_fs *)); /* Set fs->product_name to the first line of the release file. */ static int @@ -446,7 +446,8 @@ guestfs___check_linux_root (guestfs_h *g, struct inspect_fs *fs) * which filesystems are used by the operating system and how they * are mounted. */ - if (inspect_with_augeas (g, fs, "/etc/fstab", check_fstab) == -1) + const char *configfiles[] = { "/etc/fstab", NULL }; + if (inspect_with_augeas (g, fs, configfiles, check_fstab) == -1) return -1; /* Determine hostname. */ @@ -479,7 +480,8 @@ guestfs___check_freebsd_root (guestfs_h *g, struct inspect_fs *fs) check_architecture (g, fs); /* We already know /etc/fstab exists because it's part of the test above. */ - if (inspect_with_augeas (g, fs, "/etc/fstab", check_fstab) == -1) + const char *configfiles[] = { "/etc/fstab", NULL }; + if (inspect_with_augeas (g, fs, configfiles, check_fstab) == -1) return -1; /* Determine hostname. */ @@ -520,7 +522,8 @@ guestfs___check_netbsd_root (guestfs_h *g, struct inspect_fs *fs) check_architecture (g, fs); /* We already know /etc/fstab exists because it's part of the test above. */ - if (inspect_with_augeas (g, fs, "/etc/fstab", check_fstab) == -1) + const char *configfiles[] = { "/etc/fstab", NULL }; + if (inspect_with_augeas (g, fs, configfiles, check_fstab) == -1) return -1; /* Determine hostname. */ @@ -583,7 +586,8 @@ check_hostname_unix (guestfs_h *g, struct inspect_fs *fs) return -1; } else if (guestfs_is_file (g, "/etc/sysconfig/network")) { - if (inspect_with_augeas (g, fs, "/etc/sysconfig/network", + const char *configfiles[] = { "/etc/sysconfig/network", NULL }; + if (inspect_with_augeas (g, fs, configfiles, check_hostname_redhat) == -1) return -1; } @@ -685,13 +689,11 @@ static int check_fstab (guestfs_h *g, struct inspect_fs *fs) { char **lines = guestfs_aug_ls (g, "/files/etc/fstab"); - if (lines == NULL) - return -1; + if (lines == NULL) goto error; if (lines[0] == NULL) { error (g, _("could not parse /etc/fstab or empty file")); - guestfs___free_string_list (lines); - return -1; + goto error; } size_t i; @@ -703,32 +705,29 @@ check_fstab (guestfs_h *g, struct inspect_fs *fs) if (match (g, lines[i], re_aug_seq)) { snprintf (augpath, sizeof augpath, "%s/spec", lines[i]); char *spec = guestfs_aug_get (g, augpath); - if (spec == NULL) { - guestfs___free_string_list (lines); - return -1; - } + if (spec == NULL) goto error; snprintf (augpath, sizeof augpath, "%s/file", lines[i]); char *mp = guestfs_aug_get (g, augpath); if (mp == NULL) { - guestfs___free_string_list (lines); free (spec); - return -1; + goto error; } int r = add_fstab_entry (g, fs, spec, mp); free (spec); free (mp); - if (r == -1) { - guestfs___free_string_list (lines); - return -1; - } + if (r == -1) goto error; } } guestfs___free_string_list (lines); return 0; + +error: + if (lines) guestfs___free_string_list (lines); + return -1; } /* Add a filesystem and possibly a mountpoint entry for @@ -946,18 +945,23 @@ resolve_fstab_device (guestfs_h *g, const char *spec) * Augeas is closed. */ static int -inspect_with_augeas (guestfs_h *g, struct inspect_fs *fs, const char *filename, +inspect_with_augeas (guestfs_h *g, struct inspect_fs *fs, + const char **configfiles, int (*f) (guestfs_h *, struct inspect_fs *)) { - /* Security: Refuse to do this if filename is too large. */ - int64_t size = guestfs_filesize (g, filename); - if (size == -1) - /* guestfs_filesize failed and has already set error in handle */ - return -1; - if (size > MAX_AUGEAS_FILE_SIZE) { - error (g, _("size of %s is unreasonably large (%" PRIi64 " bytes)"), - filename, size); - return -1; + /* Security: Refuse to do this if a config file is too large. */ + for (const char **i = configfiles; *i != NULL; i++) { + if (guestfs_exists(g, *i) == 0) continue; + + int64_t size = guestfs_filesize (g, *i); + if (size == -1) + /* guestfs_filesize failed and has already set error in handle */ + return -1; + if (size > MAX_AUGEAS_FILE_SIZE) { + error (g, _("size of %s is unreasonably large (%" PRIi64 " bytes)"), + *i, size); + return -1; + } } /* If !feature_available (g, "augeas") then the next call will fail. @@ -970,11 +974,42 @@ inspect_with_augeas (guestfs_h *g, struct inspect_fs *fs, const char *filename, int r = -1; /* Tell Augeas to only load one file (thanks Raphaël Pinson). */ - char buf[strlen (filename) + 64]; - snprintf (buf, strlen (filename) + 64, "/augeas/load//incl[. != \"%s\"]", - filename); - if (guestfs_aug_rm (g, buf) == -1) +#define AUGEAS_LOAD "/augeas/load//incl[. != \"" +#define AUGEAS_LOAD_LEN (strlen(AUGEAS_LOAD)) + size_t conflen = strlen(configfiles[0]); + size_t buflen = AUGEAS_LOAD_LEN + conflen + 1 /* Closing " */; + char *buf = safe_malloc(g, buflen + 2 /* Closing ] + null terminator */); + + memcpy(buf, AUGEAS_LOAD, AUGEAS_LOAD_LEN); + memcpy(buf + AUGEAS_LOAD_LEN, configfiles[0], conflen); + buf[buflen - 1] = '"'; +#undef AUGEAS_LOAD_LEN +#undef AUGEAS_LOAD + +#define EXCL " and . != \"" +#define EXCL_LEN (strlen(EXCL)) + for (const char **i = &configfiles[1]; *i != NULL; i++) { + size_t orig_buflen = buflen; + conflen = strlen(*i); + buflen += EXCL_LEN + conflen + 1 /* Closing " */; + buf = safe_realloc(g, buf, buflen + 2 /* Closing ] + null terminator */); + char *s = buf + orig_buflen; + + memcpy(s, EXCL, EXCL_LEN); + memcpy(s + EXCL_LEN, *i, conflen); + buf[buflen - 1] = '"'; + } +#undef EXCL_LEN +#undef EXCL + + buf[buflen] = ']'; + buf[buflen + 1] = '\0'; + + if (guestfs_aug_rm (g, buf) == -1) { + free(buf); goto out; + } + free(buf); if (guestfs_aug_load (g) == -1) goto out;