aboutsummaryrefslogtreecommitdiff
path: root/lib/geom
diff options
context:
space:
mode:
authorPawel Jakub Dawidek <pjd@FreeBSD.org>2019-04-03 23:57:37 +0000
committerPawel Jakub Dawidek <pjd@FreeBSD.org>2019-04-03 23:57:37 +0000
commit2f07cdf871b8fd7081cfbe0d3c965650ea135e12 (patch)
tree0f0a851e23d31d69bed71bead96b591edd22c7fb /lib/geom
parentb4f850c0064cb796b77e3eed5aed43412b99c034 (diff)
downloadsrc-2f07cdf871b8fd7081cfbe0d3c965650ea135e12.tar.gz
src-2f07cdf871b8fd7081cfbe0d3c965650ea135e12.zip
Implement automatic online expansion of GELI providers - if the underlying
provider grows, GELI will expand automatically and will move the metadata to the new location of the last sector. This functionality is turned on by default. It can be turned off with the -R flag, but it is not recommended - if the underlying provider grows and automatic expansion is turned off, it won't be possible to attach this provider again, as the metadata is no longer located in the last sector. If the automatic expansion is turned off and the underlying provider grows, GELI will only log a message with the previous size of the provider, so recovery can be easier. Obtained from: Fudo Security
Notes
Notes: svn path=/head/; revision=345862
Diffstat (limited to 'lib/geom')
-rw-r--r--lib/geom/eli/geli.834
-rw-r--r--lib/geom/eli/geom_eli.c59
2 files changed, 75 insertions, 18 deletions
diff --git a/lib/geom/eli/geli.8 b/lib/geom/eli/geli.8
index cdbb1586f0fc..876f46687868 100644
--- a/lib/geom/eli/geli.8
+++ b/lib/geom/eli/geli.8
@@ -1,4 +1,4 @@
-.\" Copyright (c) 2005-2011 Pawel Jakub Dawidek <pawel@dawidek.net>
+.\" Copyright (c) 2005-2019 Pawel Jakub Dawidek <pawel@dawidek.net>
.\" All rights reserved.
.\"
.\" Redistribution and use in source and binary forms, with or without
@@ -24,7 +24,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd July 24, 2018
+.Dd April 3, 2019
.Dt GELI 8
.Os
.Sh NAME
@@ -51,7 +51,7 @@ utility:
.Pp
.Nm
.Cm init
-.Op Fl bdgPTv
+.Op Fl bdgPRTv
.Op Fl a Ar aalgo
.Op Fl B Ar backupfile
.Op Fl e Ar ealgo
@@ -81,7 +81,7 @@ utility:
.Cm detach
.Nm
.Cm onetime
-.Op Fl dT
+.Op Fl dRT
.Op Fl a Ar aalgo
.Op Fl e Ar ealgo
.Op Fl l Ar keylen
@@ -89,7 +89,7 @@ utility:
.Ar prov
.Nm
.Cm configure
-.Op Fl bBdDgGtT
+.Op Fl bBdDgGrRtT
.Ar prov ...
.Nm
.Cm setkey
@@ -375,6 +375,18 @@ Change decrypted provider's sector size.
Increasing the sector size allows increased performance,
because encryption/decryption which requires an initialization vector
is done per sector; fewer sectors means less computational work.
+.It Fl R
+Turn off automatic expansion.
+By default, if the underlying provider grows, the encrypted provider will
+grow automatically too.
+The metadata will be moved to the new location.
+If automatic expansion if turned off and the underlying provider changes
+size, attaching encrypted provider will no longer be possible as the metadata
+will no longer be located in the last sector.
+In this case
+.Nm GELI
+will only log the previous size of the underlying provider, so metadata can
+be found easier, if resize was done by mistake.
.It Fl T
Don't pass through
.Dv BIO_DELETE
@@ -506,6 +518,11 @@ Change decrypted provider's sector size.
For more information, see the description of the
.Cm init
subcommand.
+.It Fl R
+Turn off automatic expansion.
+For more information, see the description of the
+.Cm init
+subcommand.
.It Fl T
Disable TRIM/UNMAP passthru.
For more information, see the description of the
@@ -540,6 +557,13 @@ The boot loader prompts for the passphrase and loads
from the encrypted partition.
.It Fl G
Deactivate booting from this encrypted root partition.
+.It Fl r
+Turn on automatic expansion.
+For more information, see the description of the
+.Cm init
+subcommand.
+.It Fl R
+Turn off automatic expansion.
.It Fl t
Enable TRIM/UNMAP passthru.
For more information, see the description of the
diff --git a/lib/geom/eli/geom_eli.c b/lib/geom/eli/geom_eli.c
index 2da4b56c2ed0..2b08bf14a185 100644
--- a/lib/geom/eli/geom_eli.c
+++ b/lib/geom/eli/geom_eli.c
@@ -1,7 +1,7 @@
/*-
* SPDX-License-Identifier: BSD-2-Clause-FreeBSD
*
- * Copyright (c) 2004-2010 Pawel Jakub Dawidek <pjd@FreeBSD.org>
+ * Copyright (c) 2004-2019 Pawel Jakub Dawidek <pawel@dawidek.net>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -91,13 +91,13 @@ static int eli_backup_create(struct gctl_req *req, const char *prov,
/*
* Available commands:
*
- * init [-bdgPTv] [-a aalgo] [-B backupfile] [-e ealgo] [-i iterations] [-l keylen] [-J newpassfile] [-K newkeyfile] [-s sectorsize] [-V version] prov ...
+ * init [-bdgPRTv] [-a aalgo] [-B backupfile] [-e ealgo] [-i iterations] [-l keylen] [-J newpassfile] [-K newkeyfile] [-s sectorsize] [-V version] prov ...
* label - alias for 'init'
* attach [-Cdprv] [-n keyno] [-j passfile] [-k keyfile] prov ...
* detach [-fl] prov ...
* stop - alias for 'detach'
- * onetime [-dT] [-a aalgo] [-e ealgo] [-l keylen] prov
- * configure [-bBgGtT] prov ...
+ * onetime [-dRT] [-a aalgo] [-e ealgo] [-l keylen] prov
+ * configure [-bBgGrRtT] prov ...
* setkey [-pPv] [-n keyno] [-j passfile] [-J newpassfile] [-k keyfile] [-K newkeyfile] prov
* delkey [-afv] [-n keyno] prov
* suspend [-v] -a | prov ...
@@ -124,12 +124,13 @@ struct g_command class_commands[] = {
{ 'K', "newkeyfile", G_VAL_OPTIONAL, G_TYPE_STRING | G_TYPE_MULTI },
{ 'l', "keylen", "0", G_TYPE_NUMBER },
{ 'P', "nonewpassphrase", NULL, G_TYPE_BOOL },
+ { 'R', "noautoresize", NULL, G_TYPE_BOOL },
{ 's', "sectorsize", "0", G_TYPE_NUMBER },
{ 'T', "notrim", NULL, G_TYPE_BOOL },
{ 'V', "mdversion", "-1", G_TYPE_NUMBER },
G_OPT_SENTINEL
},
- "[-bdgPTv] [-a aalgo] [-B backupfile] [-e ealgo] [-i iterations] [-l keylen] [-J newpassfile] [-K newkeyfile] [-s sectorsize] [-V version] prov ..."
+ "[-bdgPRTv] [-a aalgo] [-B backupfile] [-e ealgo] [-i iterations] [-l keylen] [-J newpassfile] [-K newkeyfile] [-s sectorsize] [-V version] prov ..."
},
{ "label", G_FLAG_VERBOSE, eli_main,
{
@@ -144,6 +145,7 @@ struct g_command class_commands[] = {
{ 'K', "newkeyfile", G_VAL_OPTIONAL, G_TYPE_STRING | G_TYPE_MULTI },
{ 'l', "keylen", "0", G_TYPE_NUMBER },
{ 'P', "nonewpassphrase", NULL, G_TYPE_BOOL },
+ { 'R', "noautoresize", NULL, G_TYPE_BOOL },
{ 's', "sectorsize", "0", G_TYPE_NUMBER },
{ 'T', "notrim", NULL, G_TYPE_BOOL },
{ 'V', "mdversion", "-1", G_TYPE_NUMBER },
@@ -186,11 +188,12 @@ struct g_command class_commands[] = {
{ 'd', "detach", NULL, G_TYPE_BOOL },
{ 'e', "ealgo", GELI_ENC_ALGO, G_TYPE_STRING },
{ 'l', "keylen", "0", G_TYPE_NUMBER },
+ { 'R', "noautoresize", NULL, G_TYPE_BOOL },
{ 's', "sectorsize", "0", G_TYPE_NUMBER },
{ 'T', "notrim", NULL, G_TYPE_BOOL },
G_OPT_SENTINEL
},
- "[-dT] [-a aalgo] [-e ealgo] [-l keylen] [-s sectorsize] prov"
+ "[-dRT] [-a aalgo] [-e ealgo] [-l keylen] [-s sectorsize] prov"
},
{ "configure", G_FLAG_VERBOSE, eli_main,
{
@@ -200,11 +203,13 @@ struct g_command class_commands[] = {
{ 'D', "nodisplaypass", NULL, G_TYPE_BOOL },
{ 'g', "geliboot", NULL, G_TYPE_BOOL },
{ 'G', "nogeliboot", NULL, G_TYPE_BOOL },
+ { 'r', "autoresize", NULL, G_TYPE_BOOL },
+ { 'R', "noautoresize", NULL, G_TYPE_BOOL },
{ 't', "trim", NULL, G_TYPE_BOOL },
{ 'T', "notrim", NULL, G_TYPE_BOOL },
G_OPT_SENTINEL
},
- "[-bBdDgGtT] prov ..."
+ "[-bBdDgGrRtT] prov ..."
},
{ "setkey", G_FLAG_VERBOSE, eli_main,
{
@@ -728,7 +733,7 @@ eli_init(struct gctl_req *req)
version = val;
}
md.md_version = version;
- md.md_flags = 0;
+ md.md_flags = G_ELI_FLAG_AUTORESIZE;
if (gctl_get_int(req, "boot"))
md.md_flags |= G_ELI_FLAG_BOOT;
if (gctl_get_int(req, "geliboot"))
@@ -737,6 +742,8 @@ eli_init(struct gctl_req *req)
md.md_flags |= G_ELI_FLAG_GELIDISPLAYPASS;
if (gctl_get_int(req, "notrim"))
md.md_flags |= G_ELI_FLAG_NODELETE;
+ if (gctl_get_int(req, "noautoresize"))
+ md.md_flags &= ~G_ELI_FLAG_AUTORESIZE;
md.md_ealgo = CRYPTO_ALGORITHM_MIN - 1;
str = gctl_get_ascii(req, "aalgo");
if (*str != '\0') {
@@ -1095,7 +1102,7 @@ out:
static void
eli_configure_detached(struct gctl_req *req, const char *prov, int boot,
- int geliboot, int displaypass, int trim)
+ int geliboot, int displaypass, int trim, int autoresize)
{
struct g_eli_metadata md;
bool changed = 0;
@@ -1160,6 +1167,20 @@ eli_configure_detached(struct gctl_req *req, const char *prov, int boot,
changed = 1;
}
+ if (autoresize == 1 && (md.md_flags & G_ELI_FLAG_AUTORESIZE)) {
+ if (verbose)
+ printf("AUTORESIZE flag already configured for %s.\n", prov);
+ } else if (autoresize == 0 && !(md.md_flags & G_ELI_FLAG_AUTORESIZE)) {
+ if (verbose)
+ printf("AUTORESIZE flag not configured for %s.\n", prov);
+ } else if (autoresize >= 0) {
+ if (autoresize)
+ md.md_flags |= G_ELI_FLAG_AUTORESIZE;
+ else
+ md.md_flags &= ~G_ELI_FLAG_AUTORESIZE;
+ changed = 1;
+ }
+
if (changed)
eli_metadata_store(req, prov, &md);
explicit_bzero(&md, sizeof(md));
@@ -1170,8 +1191,8 @@ eli_configure(struct gctl_req *req)
{
const char *prov;
bool boot, noboot, geliboot, nogeliboot, displaypass, nodisplaypass;
- bool trim, notrim;
- int doboot, dogeliboot, dodisplaypass, dotrim;
+ bool autoresize, noautoresize, trim, notrim;
+ int doboot, dogeliboot, dodisplaypass, dotrim, doautoresize;
int i, nargs;
nargs = gctl_get_int(req, "nargs");
@@ -1188,6 +1209,8 @@ eli_configure(struct gctl_req *req)
nodisplaypass = gctl_get_int(req, "nodisplaypass");
trim = gctl_get_int(req, "trim");
notrim = gctl_get_int(req, "notrim");
+ autoresize = gctl_get_int(req, "autoresize");
+ noautoresize = gctl_get_int(req, "noautoresize");
doboot = -1;
if (boot && noboot) {
@@ -1229,8 +1252,18 @@ eli_configure(struct gctl_req *req)
else if (notrim)
dotrim = 0;
+ doautoresize = -1;
+ if (autoresize && noautoresize) {
+ gctl_error(req, "Options -r and -R are mutually exclusive.");
+ return;
+ }
+ if (autoresize)
+ doautoresize = 1;
+ else if (noautoresize)
+ doautoresize = 0;
+
if (doboot == -1 && dogeliboot == -1 && dodisplaypass == -1 &&
- dotrim == -1) {
+ dotrim == -1 && doautoresize == -1) {
gctl_error(req, "No option given.");
return;
}
@@ -1242,7 +1275,7 @@ eli_configure(struct gctl_req *req)
prov = gctl_get_ascii(req, "arg%d", i);
if (!eli_is_attached(prov)) {
eli_configure_detached(req, prov, doboot, dogeliboot,
- dodisplaypass, dotrim);
+ dodisplaypass, dotrim, doautoresize);
}
}
}