increasing HIVEX_MAX_SUBKEYS and HIVEX_MAX_VALUES
by Matt Coleman
Hello,
We've been seeing an increasing number of software hives containing subkey and value counts that exceed the limits defined in hivex-internal.h (https://github.com/libguestfs/hivex/blob/1.3.13/lib/hivex-internal.h#L325...). Since hivex abruptly aborts when it comes across a key with more subkeys or values than the defined limits, it's breaking some functionality in our cloud.
The purpose of this email is to open a discussion about these arbitrary limits and propose both a short-term hotfix and a long-term solution.
This issue has only been observed in our cloud on servers running Windows 2008R2 and newer (particularly systems with Exchange installed), but very few of the registry keys causing the problem are specific to server editions of Windows. It's likely that this could also happen on workstation variants and possible that we've only seen it on server variants, since that's what the majority of our cloud is comprised of.
Our code is particularly interested in 'Microsoft\Windows NT\CurrentVersion' within the software hive. Among the set of hives that hivex is unable to process, the largest number of subkeys found within 'Microsoft\Windows NT\CurrentVersion' is 45962, and the largest number of values is 37717.
If I check the entire software hive, I find a maximum of 2393689 subkeys and 74324 values.
I feel a conservative approach would be to increase the limits to approximately 1.5 times the largest observed counts:
• If we decide to go with the values observed from just the 'Microsoft\Windows NT\CurrentVersion' key in our cloud, then HIVEX_MAX_SUBKEYS would become 70000 and HIVEX_MAX_VALUES would become 55000. These are the initial values I was going to base my patch on, since (selfishly) that's all my code cares about, but I figured it makes more sense to account for all regions of the hive.
• If we decide to go with the values from the whole software hive, then HIVEX_MAX_SUBKEYS would become 3600000 and HIVEX_MAX_VALUES would become 110000. These are the values I used in the attached patch. The only thing that makes me hesitant is that they're both so significantly larger than the current limits.
What about removing the limits entirely? The registry format allows up to 2^32 subkeys and values. On IRC, rwmjones said, "the limits are there to stop malicious hives from using too much memory". I hadn't heard of malicious hives before. Have there been exploits that leveraged this, or is it just being cautious about a potential threat?
rwmjones suggested that the ideal solution would be adding the ability to set the limits at runtime or ignore them entirely. I agree that that's a better solution in the long run, but involves a much more significant reworking of the code than simply increasing some defined values.
Since we need a fix for our cloud in the short term and it might help other people experiencing the same problem, I propose two patches:
1. bump the limits to 1.5 times the highest observed counts; I've attached a patch that bumps HIVEX_MAX_SUBKEYS to 3.6m and HIVEX_MAX_VALUES to 110k
2. in a future patch, allow setting the limits or disabling them entirely at runtime
--
Matt Coleman
Senior Software Engineer
Datto, Inc.
www.datto.com
8 years
[PATCH] New API: cryptsetup_reencrypt: change the master volume key on LUKS partitions.
by Richard W.M. Jones
Note that cryptsetup-reencrypt is a separate package on Fedora, but is
already part of the appliance on Debian/Ubuntu.
---
appliance/packagelist.in | 1 +
daemon/luks.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++
generator/actions.ml | 18 ++++++++++++++++++
gobject/Makefile.inc | 2 ++
src/MAX_PROC_NR | 2 +-
5 files changed, 68 insertions(+), 1 deletion(-)
diff --git a/appliance/packagelist.in b/appliance/packagelist.in
index bbbe4b2..485e9cd 100644
--- a/appliance/packagelist.in
+++ b/appliance/packagelist.in
@@ -26,6 +26,7 @@ ifelse(REDHAT,1,
augeas-libs
cryptsetup
cryptsetup-luks dnl old name used before Fedora 17
+ cryptsetup-reencrypt
dhclient
genisoimage
gfs-utils
diff --git a/daemon/luks.c b/daemon/luks.c
index 53bb820..440caa2 100644
--- a/daemon/luks.c
+++ b/daemon/luks.c
@@ -29,6 +29,7 @@
#define MAX_ARGS 64
GUESTFSD_EXT_CMD(str_cryptsetup, cryptsetup);
+GUESTFSD_EXT_CMD(str_cryptsetup_reencrypt, cryptsetup_reencrypt);
int
optgroup_luks_available (void)
@@ -294,3 +295,48 @@ do_luks_kill_slot (const char *device, const char *key, int keyslot)
return 0;
}
+
+int
+optgroup_luksreencrypt_available (void)
+{
+ return prog_exists (str_cryptsetup_reencrypt);
+}
+
+/* Takes optional arguments, consult optargs_bitmask. */
+int
+do_cryptsetup_reencrypt (const char *device, const char *key, int keyslot,
+ const char *cipher)
+{
+ const char *argv[MAX_ARGS];
+ size_t i = 0;
+ char keyslot_s[16];
+
+ char *tempfile = write_key_to_temp (key);
+ if (!tempfile)
+ return -1;
+
+ ADD_ARG (argv, i, str_cryptsetup_reencrypt);
+ ADD_ARG (argv, i, "-q");
+ if ((optargs_bitmask & GUESTFS_CRYPTSETUP_REENCRYPT_CIPHER_BITMASK)) {
+ ADD_ARG (argv, i, "-c");
+ ADD_ARG (argv, i, cipher);
+ }
+ ADD_ARG (argv, i, "-d");
+ ADD_ARG (argv, i, tempfile);
+ ADD_ARG (argv, i, "-S");
+ snprintf (keyslot_s, sizeof keyslot_s, "%d", keyslot);
+ ADD_ARG (argv, i, keyslot_s);
+ ADD_ARG (argv, i, device);
+ ADD_ARG (argv, i, NULL);
+
+ CLEANUP_FREE char *err = NULL;
+ int r = commandv (NULL, &err, (const char * const *) argv);
+ remove_temp (tempfile);
+
+ if (r == -1) {
+ reply_with_error ("%s", err);
+ return -1;
+ }
+
+ return 0;
+}
diff --git a/generator/actions.ml b/generator/actions.ml
index 43de38b..057db8f 100644
--- a/generator/actions.ml
+++ b/generator/actions.ml
@@ -13265,6 +13265,24 @@ is removed." };
shortdesc = "search the entries associated to the given inode";
longdesc = "Internal function for find_inode." };
+ { defaults with
+ name = "cryptsetup_reencrypt"; added = (1, 35, 15);
+ style = RErr, [Device "device"; Key "key"; Int "keyslot"], [OString "cipher"];
+ proc_nr = Some 471;
+ optional = Some "luksreencrypt";
+ shortdesc = "change the master volume key on a LUKS partition";
+ longdesc = "\
+This reencrypts a LUKS device with a new random master volume key,
+using the L<cryptsetup-reencrypt(8)> tool. A new passphrase C<key>
+is added in key slot C<keyslot>, and all other keyslots are erased.
+
+With no optional parameters, the same type of cipher is used. To
+change to a different cipher, supply the optional C<cipher> parameter.
+
+This command has to rewrite the entire C<device>, and so is both
+long running and will destroy all the data on the device if the
+operation is interrupted." };
+
]
(* Non-API meta-commands available only in guestfish.
diff --git a/gobject/Makefile.inc b/gobject/Makefile.inc
index 149e4c6..bb1ee3a 100644
--- a/gobject/Makefile.inc
+++ b/gobject/Makefile.inc
@@ -68,6 +68,7 @@ guestfs_gobject_headers= \
include/guestfs-gobject/optargs-copy_file_to_device.h \
include/guestfs-gobject/optargs-copy_file_to_file.h \
include/guestfs-gobject/optargs-cpio_out.h \
+ include/guestfs-gobject/optargs-cryptsetup_reencrypt.h \
include/guestfs-gobject/optargs-disk_create.h \
include/guestfs-gobject/optargs-download_blocks.h \
include/guestfs-gobject/optargs-e2fsck.h \
@@ -159,6 +160,7 @@ guestfs_gobject_sources= \
src/optargs-copy_file_to_device.c \
src/optargs-copy_file_to_file.c \
src/optargs-cpio_out.c \
+ src/optargs-cryptsetup_reencrypt.c \
src/optargs-disk_create.c \
src/optargs-download_blocks.c \
src/optargs-e2fsck.c \
diff --git a/src/MAX_PROC_NR b/src/MAX_PROC_NR
index 5f476b6..c305aa5 100644
--- a/src/MAX_PROC_NR
+++ b/src/MAX_PROC_NR
@@ -1 +1 @@
-470
+471
--
2.10.2
8 years
[PATCH NOT TO BE APPLIED] builder: make-template: Add --encrypted
by Richard W.M. Jones
I was attempting one way to solve:
https://bugzilla.redhat.com/show_bug.cgi?id=1400332
"RFE: virt-builder should support templates with encrypted filesystems"
However this approach doesn't really work because templates containing
encrypted partitions cannot be compressed, and therefore the guest
template would be a multi-gigabyte download.
I better approach will likely be to use the new qcow2 encryption
(LUKS-based) recently written by Dan Berrange.
I am posting this patch just to record the code changes.
Rich.
8 years
[PATCH] packagelist: add initviocons package on SUSE
by Cédric Bosdonnat
initviocons package provides tools to resize the terminal. Having it
in the appliance will allow SUSE users to have proper line wrapping
in their terminal when using virt-rescue.
---
appliance/packagelist.in | 1 +
1 file changed, 1 insertion(+)
diff --git a/appliance/packagelist.in b/appliance/packagelist.in
index f278f66..bbbe4b2 100644
--- a/appliance/packagelist.in
+++ b/appliance/packagelist.in
@@ -139,6 +139,7 @@ ifelse(SUSE,1,
glibc-locale
gptfdisk
hivex
+ initviocons
iproute2
iputils
libcap2
--
2.10.2
8 years