FreeBSD Bugzilla – Attachment 158599 Details for
Bug 198863
[patch] geli: TRIM passthru
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
Patch to geli to enable passthru
new.geli.patch (text/plain), 12.89 KB, created by
fullermd
on 2015-07-11 04:22:05 UTC
(
hide
)
Description:
Patch to geli to enable passthru
Filename:
MIME Type:
Creator:
fullermd
Created:
2015-07-11 04:22:05 UTC
Size:
12.89 KB
patch
obsolete
>Index: sbin/geom/class/eli/geli.8 >=================================================================== >--- sbin/geom/class/eli/geli.8 (revision 285365) >+++ sbin/geom/class/eli/geli.8 (working copy) >@@ -24,7 +24,7 @@ > .\" > .\" $FreeBSD$ > .\" >-.Dd June 2, 2015 >+.Dd July 10, 2015 > .Dt GELI 8 > .Os > .Sh NAME >@@ -51,7 +51,7 @@ > .Pp > .Nm > .Cm init >-.Op Fl bPv >+.Op Fl bPTv > .Op Fl a Ar aalgo > .Op Fl B Ar backupfile > .Op Fl e Ar ealgo >@@ -80,7 +80,7 @@ > .Cm detach > .Nm > .Cm onetime >-.Op Fl d >+.Op Fl dT > .Op Fl a Ar aalgo > .Op Fl e Ar ealgo > .Op Fl l Ar keylen >@@ -88,7 +88,7 @@ > .Ar prov > .Nm > .Cm configure >-.Op Fl bB >+.Op Fl bBtT > .Ar prov ... > .Nm > .Cm setkey >@@ -351,6 +351,17 @@ > 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 T >+Don't pass through >+.Dv BIO_DELETE >+calls (i.e., TRIM/UNMAP). >+This can prevent an attacker from knowing how much space you're actually >+using and which sectors contain live data, but will also prevent the >+backing store (SSD, etc) from reclaiming space you're not using, which >+may degrade its performance and lifespan. >+The underlying provider may or may not actually obliterate the deleted >+sectors when TRIM is enabled, so it should not be considered to add any >+security. > .It Fl V Ar version > Metadata version to use. > This option is helpful when creating a provider that may be used by older >@@ -456,6 +467,11 @@ > 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 >+.Cm init >+subcommand. > .El > .It Cm configure > Change configuration of the given providers. >@@ -469,6 +485,13 @@ > subcommand. > .It Fl B > Remove the BOOT flag from the given providers. >+.It Fl t >+Enable TRIM/UNMAP passthru. >+For more information, see the description of the >+.Cm init >+subcommand. >+.It Fl T >+Disable TRIM/UNMAP passthru. > .El > .It Cm setkey > Install a copy of the Master Key into the selected slot, encrypted with >Index: sbin/geom/class/eli/geom_eli.c >=================================================================== >--- sbin/geom/class/eli/geom_eli.c (revision 285365) >+++ sbin/geom/class/eli/geom_eli.c (working copy) >@@ -114,10 +114,11 @@ > { 'l', "keylen", "0", G_TYPE_NUMBER }, > { 'P', "nonewpassphrase", 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 > }, >- "[-bPv] [-a aalgo] [-B backupfile] [-e ealgo] [-i iterations] [-l keylen] [-J newpassfile] [-K newkeyfile] [-s sectorsize] [-V version] prov" >+ "[-bPTv] [-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, > { >@@ -170,17 +171,20 @@ > { 'e', "ealgo", GELI_ENC_ALGO, G_TYPE_STRING }, > { 'l', "keylen", "0", G_TYPE_NUMBER }, > { 's', "sectorsize", "0", G_TYPE_NUMBER }, >+ { 'T', "notrim", NULL, G_TYPE_BOOL }, > G_OPT_SENTINEL > }, >- "[-d] [-a aalgo] [-e ealgo] [-l keylen] [-s sectorsize] prov" >+ "[-dT] [-a aalgo] [-e ealgo] [-l keylen] [-s sectorsize] prov" > }, > { "configure", G_FLAG_VERBOSE, eli_main, > { > { 'b', "boot", NULL, G_TYPE_BOOL }, > { 'B', "noboot", NULL, G_TYPE_BOOL }, >+ { 't', "trim", NULL, G_TYPE_BOOL }, >+ { 'T', "notrim", NULL, G_TYPE_BOOL }, > G_OPT_SENTINEL > }, >- "[-bB] prov ..." >+ "[-bBtT] prov ..." > }, > { "setkey", G_FLAG_VERBOSE, eli_main, > { >@@ -698,6 +702,8 @@ > md.md_flags = 0; > if (gctl_get_int(req, "boot")) > md.md_flags |= G_ELI_FLAG_BOOT; >+ if (gctl_get_int(req, "notrim")) >+ md.md_flags |= G_ELI_FLAG_NODELETE; > md.md_ealgo = CRYPTO_ALGORITHM_MIN - 1; > str = gctl_get_ascii(req, "aalgo"); > if (*str != '\0') { >@@ -899,26 +905,45 @@ > } > > static void >-eli_configure_detached(struct gctl_req *req, const char *prov, bool boot) >+eli_configure_detached(struct gctl_req *req, const char *prov, int boot, >+ int trim) > { > struct g_eli_metadata md; >+ bool changed = 0; > > if (eli_metadata_read(req, prov, &md) == -1) > return; > >- if (boot && (md.md_flags & G_ELI_FLAG_BOOT)) { >+ if (boot == 1 && (md.md_flags & G_ELI_FLAG_BOOT)) { > if (verbose) > printf("BOOT flag already configured for %s.\n", prov); >- } else if (!boot && !(md.md_flags & G_ELI_FLAG_BOOT)) { >+ } else if (boot == 0 && !(md.md_flags & G_ELI_FLAG_BOOT)) { > if (verbose) > printf("BOOT flag not configured for %s.\n", prov); >- } else { >+ } else if (boot >= 0) { > if (boot) > md.md_flags |= G_ELI_FLAG_BOOT; > else > md.md_flags &= ~G_ELI_FLAG_BOOT; >+ changed = 1; >+ } >+ >+ if (trim == 0 && (md.md_flags & G_ELI_FLAG_NODELETE)) { >+ if (verbose) >+ printf("TRIM disable flag already configured for %s.\n", prov); >+ } else if (trim == 1 && !(md.md_flags & G_ELI_FLAG_NODELETE)) { >+ if (verbose) >+ printf("TRIM disable flag not configured for %s.\n", prov); >+ } else if (trim >= 0) { >+ if (trim) >+ md.md_flags &= ~G_ELI_FLAG_NODELETE; >+ else >+ md.md_flags |= G_ELI_FLAG_NODELETE; >+ changed = 1; >+ } >+ >+ if (changed) > eli_metadata_store(req, prov, &md); >- } > bzero(&md, sizeof(md)); > } > >@@ -926,7 +951,8 @@ > eli_configure(struct gctl_req *req) > { > const char *prov; >- bool boot, noboot; >+ bool boot, noboot, trim, notrim; >+ int doboot, dotrim; > int i, nargs; > > nargs = gctl_get_int(req, "nargs"); >@@ -937,12 +963,30 @@ > > boot = gctl_get_int(req, "boot"); > noboot = gctl_get_int(req, "noboot"); >+ trim = gctl_get_int(req, "trim"); >+ notrim = gctl_get_int(req, "notrim"); > >+ doboot = -1; > if (boot && noboot) { > gctl_error(req, "Options -b and -B are mutually exclusive."); > return; > } >- if (!boot && !noboot) { >+ if (boot) >+ doboot = 1; >+ else if (noboot) >+ doboot = 0; >+ >+ dotrim = -1; >+ if (trim && notrim) { >+ gctl_error(req, "Options -t and -T are mutually exclusive."); >+ return; >+ } >+ if (trim) >+ dotrim = 1; >+ else if (notrim) >+ dotrim = 0; >+ >+ if (doboot == -1 && dotrim == -1) { > gctl_error(req, "No option given."); > return; > } >@@ -953,7 +997,7 @@ > for (i = 0; i < nargs; i++) { > prov = gctl_get_ascii(req, "arg%d", i); > if (!eli_is_attached(prov)) >- eli_configure_detached(req, prov, boot); >+ eli_configure_detached(req, prov, doboot, dotrim); > } > } > >Index: sys/geom/eli/g_eli.c >=================================================================== >--- sys/geom/eli/g_eli.c (revision 285365) >+++ sys/geom/eli/g_eli.c (working copy) >@@ -312,10 +312,15 @@ > break; > case BIO_DELETE: > /* >- * We could eventually support BIO_DELETE request. >- * It could be done by overwritting requested sector with >- * random data g_eli_overwrites number of times. >+ * If the user hasn't set the NODELETE flag, we just pass >+ * it down the stack and let the layers beneath us do (or >+ * not) whatever they do with it. If they have, we >+ * reject it. A possible extension would be an >+ * additional flag to take it as a hint to shred the data >+ * with [multiple?] overwrites. > */ >+ if (!(sc->sc_flags & G_ELI_FLAG_NODELETE)) >+ break; > default: > g_io_deliver(bp, EOPNOTSUPP); > return; >@@ -342,6 +347,7 @@ > break; > case BIO_GETATTR: > case BIO_FLUSH: >+ case BIO_DELETE: > cbp->bio_done = g_std_done; > cp = LIST_FIRST(&sc->sc_geom->consumer); > cbp->bio_to = cp->provider; >@@ -1255,6 +1261,7 @@ > ADD_FLAG(G_ELI_FLAG_WOPEN, "W-OPEN"); > ADD_FLAG(G_ELI_FLAG_DESTROY, "DESTROY"); > ADD_FLAG(G_ELI_FLAG_RO, "READ-ONLY"); >+ ADD_FLAG(G_ELI_FLAG_NODELETE, "NODELETE"); > #undef ADD_FLAG > } > sbuf_printf(sb, "</Flags>\n"); >Index: sys/geom/eli/g_eli.h >=================================================================== >--- sys/geom/eli/g_eli.h (revision 285365) >+++ sys/geom/eli/g_eli.h (working copy) >@@ -94,6 +94,8 @@ > #define G_ELI_FLAG_AUTH 0x00000010 > /* Provider is read-only, we should deny all write attempts. */ > #define G_ELI_FLAG_RO 0x00000020 >+/* Don't pass through BIO_DELETE requests. */ >+#define G_ELI_FLAG_NODELETE 0x00000040 > /* RUNTIME FLAGS. */ > /* Provider was open for writing. */ > #define G_ELI_FLAG_WOPEN 0x00010000 >Index: sys/geom/eli/g_eli_ctl.c >=================================================================== >--- sys/geom/eli/g_eli_ctl.c (revision 285365) >+++ sys/geom/eli/g_eli_ctl.c (working copy) >@@ -236,7 +236,7 @@ > const char *name; > intmax_t *keylen, *sectorsize; > u_char mkey[G_ELI_DATAIVKEYLEN]; >- int *nargs, *detach; >+ int *nargs, *detach, *notrim; > > g_topology_assert(); > bzero(&md, sizeof(md)); >@@ -251,17 +251,16 @@ > return; > } > >- detach = gctl_get_paraml(req, "detach", sizeof(*detach)); >- if (detach == NULL) { >- gctl_error(req, "No '%s' argument.", "detach"); >- return; >- } >- > strlcpy(md.md_magic, G_ELI_MAGIC, sizeof(md.md_magic)); > md.md_version = G_ELI_VERSION; > md.md_flags |= G_ELI_FLAG_ONETIME; >- if (*detach) >+ >+ detach = gctl_get_paraml(req, "detach", sizeof(*detach)); >+ if (detach != NULL && *detach) > md.md_flags |= G_ELI_FLAG_WO_DETACH; >+ notrim = gctl_get_paraml(req, "notrim", sizeof(*notrim)); >+ if (notrim != NULL && *notrim) >+ md.md_flags |= G_ELI_FLAG_NODELETE; > > md.md_ealgo = CRYPTO_ALGORITHM_MIN - 1; > name = gctl_get_asciiparam(req, "aalgo"); >@@ -377,12 +376,15 @@ > char param[16]; > const char *prov; > u_char *sector; >- int *nargs, *boot, *noboot; >- int error; >+ int *nargs, *boot, *noboot, *trim, *notrim; >+ int zero, error, changed; > u_int i; > > g_topology_assert(); > >+ changed = 0; >+ zero = 0; >+ > nargs = gctl_get_paraml(req, "nargs", sizeof(*nargs)); > if (nargs == NULL) { > gctl_error(req, "No '%s' argument.", "nargs"); >@@ -394,20 +396,32 @@ > } > > boot = gctl_get_paraml(req, "boot", sizeof(*boot)); >- if (boot == NULL) { >- gctl_error(req, "No '%s' argument.", "boot"); >- return; >- } >+ if (boot == NULL) >+ boot = &zero; > noboot = gctl_get_paraml(req, "noboot", sizeof(*noboot)); >- if (noboot == NULL) { >- gctl_error(req, "No '%s' argument.", "noboot"); >- return; >- } >+ if (noboot == NULL) >+ noboot = &zero; > if (*boot && *noboot) { > gctl_error(req, "Options -b and -B are mutually exclusive."); > return; > } >- if (!*boot && !*noboot) { >+ if (*boot || *noboot) >+ changed = 1; >+ >+ trim = gctl_get_paraml(req, "trim", sizeof(*trim)); >+ if (trim == NULL) >+ trim = &zero; >+ notrim = gctl_get_paraml(req, "notrim", sizeof(*notrim)); >+ if (notrim == NULL) >+ notrim = &zero; >+ if (*trim && *notrim) { >+ gctl_error(req, "Options -t and -T are mutually exclusive."); >+ return; >+ } >+ if (*trim || *notrim) >+ changed = 1; >+ >+ if (!changed) { > gctl_error(req, "No option given."); > return; > } >@@ -429,38 +443,72 @@ > "provider %s.", prov); > continue; > } >+ if (sc->sc_flags & G_ELI_FLAG_RO) { >+ gctl_error(req, "Cannot change configuration of " >+ "read-only provider %s.", prov); >+ continue; >+ } >+ > if (*boot && (sc->sc_flags & G_ELI_FLAG_BOOT)) { > G_ELI_DEBUG(1, "BOOT flag already configured for %s.", > prov); > continue; >- } else if (!*boot && !(sc->sc_flags & G_ELI_FLAG_BOOT)) { >+ } else if (*noboot && !(sc->sc_flags & G_ELI_FLAG_BOOT)) { > G_ELI_DEBUG(1, "BOOT flag not configured for %s.", > prov); > continue; > } >- if (sc->sc_flags & G_ELI_FLAG_RO) { >- gctl_error(req, "Cannot change configuration of " >- "read-only provider %s.", prov); >+ >+ if (*notrim && (sc->sc_flags & G_ELI_FLAG_NODELETE)) { >+ G_ELI_DEBUG(1, "TRIM disable flag already configured for %s.", >+ prov); > continue; >- } >- cp = LIST_FIRST(&sc->sc_geom->consumer); >- pp = cp->provider; >- error = g_eli_read_metadata(mp, pp, &md); >- if (error != 0) { >- gctl_error(req, >- "Cannot read metadata from %s (error=%d).", >- prov, error); >+ } else if (*trim && !(sc->sc_flags & G_ELI_FLAG_NODELETE)) { >+ G_ELI_DEBUG(1, "TRIM disable flag not configured for %s.", >+ prov); > continue; > } > >+ if (!(sc->sc_flags & G_ELI_FLAG_ONETIME)) { >+ /* >+ * ONETIME providers don't write metadata to >+ * disk, so don't try reading it. This means >+ * we're bit-flipping uninitialized memory in md >+ * below, but that's OK; we don't do anything >+ * with it later. >+ */ >+ cp = LIST_FIRST(&sc->sc_geom->consumer); >+ pp = cp->provider; >+ error = g_eli_read_metadata(mp, pp, &md); >+ if (error != 0) { >+ gctl_error(req, >+ "Cannot read metadata from %s (error=%d).", >+ prov, error); >+ continue; >+ } >+ } >+ > if (*boot) { > md.md_flags |= G_ELI_FLAG_BOOT; > sc->sc_flags |= G_ELI_FLAG_BOOT; >- } else { >+ } else if (*noboot) { > md.md_flags &= ~G_ELI_FLAG_BOOT; > sc->sc_flags &= ~G_ELI_FLAG_BOOT; > } > >+ if (*notrim) { >+ md.md_flags |= G_ELI_FLAG_NODELETE; >+ sc->sc_flags |= G_ELI_FLAG_NODELETE; >+ } else if (*trim) { >+ md.md_flags &= ~G_ELI_FLAG_NODELETE; >+ sc->sc_flags &= ~G_ELI_FLAG_NODELETE; >+ } >+ >+ if (sc->sc_flags & G_ELI_FLAG_ONETIME) { >+ /* There's no metadata on disk so we are done here. */ >+ continue; >+ } >+ > sector = malloc(pp->sectorsize, M_ELI, M_WAITOK | M_ZERO); > eli_metadata_encode(&md, sector); > error = g_write_data(cp, pp->mediasize - pp->sectorsize, sector,
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 198863
:
154746
|
154855
|
156615
| 158599 |
158601