Author: cem
Date: Sat Sep  9 01:41:01 2017
New Revision: 323338
URL: https://svnweb.freebsd.org/changeset/base/323338

Log:
  Fix information leak in geli(8) integrity mode
  
  In integrity mode, a larger logical sector (e.g., 4096 bytes) spans several
  physical sectors (e.g., 512 bytes) on the backing device.  Due to hash
  overhead, a 4096 byte logical sector takes 8.5625 512-byte physical sectors.
  This means that only 288 bytes (256 data + 32 hash) of the last 512 byte
  sector are used.
  
  The memory allocation used to store the encrypted data to be written to the
  physical sectors comes from malloc(9) and does not use M_ZERO.
  
  Previously, nothing initialized the final physical sector backing each
  logical sector, aside from the hash + encrypted data portion.  So 224 bytes
  of kernel heap memory was leaked to every block :-(.
  
  This patch addresses the issue by initializing the trailing portion of the
  physical sector in every logical sector to zeros before use.  A much simpler
  but higher overhead fix would be to tag the entire allocation M_ZERO.
  
  PR:           222077
  Reported by:  Maxim Khitrov <max AT mxcrypt.com>
  Reviewed by:  emaste
  Security:     yes
  Sponsored by: Dell EMC Isilon
  Differential Revision:        https://reviews.freebsd.org/D12272

Modified:
  head/sys/geom/eli/g_eli_integrity.c

Modified: head/sys/geom/eli/g_eli_integrity.c
==============================================================================
--- head/sys/geom/eli/g_eli_integrity.c Sat Sep  9 01:23:30 2017        
(r323337)
+++ head/sys/geom/eli/g_eli_integrity.c Sat Sep  9 01:41:01 2017        
(r323338)
@@ -463,8 +463,16 @@ g_eli_auth_run(struct g_eli_worker *wr, struct bio *bp
                authkey = (u_char *)p;          p += G_ELI_AUTH_SECKEYLEN;
 
                data_secsize = sc->sc_data_per_sector;
-               if ((i % lsec) == 0)
+               if ((i % lsec) == 0) {
                        data_secsize = decr_secsize % data_secsize;
+                       /*
+                        * Last encrypted sector of each decrypted sector is
+                        * only partially filled.
+                        */
+                       if (bp->bio_cmd == BIO_WRITE)
+                               memset(data + sc->sc_alen + data_secsize, 0,
+                                   encr_secsize - sc->sc_alen - data_secsize);
+               }
 
                if (bp->bio_cmd == BIO_READ) {
                        /* Remember read HMAC. */
_______________________________________________
[email protected] mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "[email protected]"

Reply via email to