Date: Sat, 9 Sep 2017 01:41:01 +0000 (UTC) From: Conrad Meyer <cem@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r323338 - head/sys/geom/eli Message-ID: <201709090141.v891f1h4041553@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
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. */
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201709090141.v891f1h4041553>