Date: Wed, 30 May 2012 12:01:29 +0000 (UTC) From: "Bjoern A. Zeeb" <bz@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-releng@freebsd.org Subject: svn commit: r236304 - head/crypto/openssl/crypto/buffer head/crypto/openssl/ssl head/secure/lib/libcrypt releng/7.4 releng/7.4/crypto/openssl/crypto/buffer releng/7.4/crypto/openssl/ssl releng/7.4/... Message-ID: <201205301201.q4UC1TUr047246@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: bz Date: Wed May 30 12:01:28 2012 New Revision: 236304 URL: http://svn.freebsd.org/changeset/base/236304 Log: Update the previous openssl fix. [12:01] Fix a bug in crypt(3) ignoring characters of a passphrase. [12:02] Security: FreeBSD-SA-12:01.openssl (revised) Security: FreeBSD-SA-12:02.crypt Approved by: so (bz, simon) Modified: releng/7.4/UPDATING releng/7.4/crypto/openssl/crypto/buffer/buffer.c releng/7.4/crypto/openssl/ssl/s3_srvr.c releng/7.4/secure/lib/libcrypt/crypt-des.c releng/7.4/sys/conf/newvers.sh releng/8.1/UPDATING releng/8.1/crypto/openssl/crypto/buffer/buffer.c releng/8.1/crypto/openssl/ssl/s3_srvr.c releng/8.1/secure/lib/libcrypt/crypt-des.c releng/8.1/sys/conf/newvers.sh releng/8.2/UPDATING releng/8.2/crypto/openssl/crypto/buffer/buffer.c releng/8.2/crypto/openssl/ssl/s3_srvr.c releng/8.2/secure/lib/libcrypt/crypt-des.c releng/8.2/sys/conf/newvers.sh releng/8.3/UPDATING releng/8.3/crypto/openssl/crypto/buffer/buffer.c releng/8.3/crypto/openssl/ssl/s3_srvr.c releng/8.3/secure/lib/libcrypt/crypt-des.c releng/8.3/sys/conf/newvers.sh releng/9.0/UPDATING releng/9.0/crypto/openssl/crypto/buffer/buffer.c releng/9.0/crypto/openssl/ssl/s3_srvr.c releng/9.0/secure/lib/libcrypt/crypt-des.c releng/9.0/sys/conf/newvers.sh Changes in other areas also in this revision: Modified: head/crypto/openssl/crypto/buffer/buffer.c head/crypto/openssl/ssl/s3_srvr.c head/secure/lib/libcrypt/crypt-des.c stable/7/crypto/openssl/crypto/buffer/buffer.c stable/7/crypto/openssl/ssl/s3_srvr.c stable/7/secure/lib/libcrypt/crypt-des.c stable/8/crypto/openssl/crypto/buffer/buffer.c stable/8/crypto/openssl/ssl/s3_srvr.c stable/8/secure/lib/libcrypt/crypt-des.c stable/9/crypto/openssl/crypto/buffer/buffer.c stable/9/crypto/openssl/ssl/s3_srvr.c stable/9/secure/lib/libcrypt/crypt-des.c Modified: releng/7.4/UPDATING ============================================================================== --- releng/7.4/UPDATING Wed May 30 11:48:57 2012 (r236303) +++ releng/7.4/UPDATING Wed May 30 12:01:28 2012 (r236304) @@ -8,6 +8,12 @@ Items affecting the ports and packages s /usr/ports/UPDATING. Please read that file before running portupgrade. +20120530: p8 FreeBSD-SA-12:01.openssl (revised), + FreeBSD-SA-12:02.crypt + Update the previous openssl fix. [12:01] + + Fix a bug in crypt(3) ignoring characters of a passphrase. [12:02] + 20120503: p7 FreeBSD-SA-12:01.openssl Fix multiple OpenSSL vulnerabilities. Modified: releng/7.4/crypto/openssl/crypto/buffer/buffer.c ============================================================================== --- releng/7.4/crypto/openssl/crypto/buffer/buffer.c Wed May 30 11:48:57 2012 (r236303) +++ releng/7.4/crypto/openssl/crypto/buffer/buffer.c Wed May 30 12:01:28 2012 (r236304) @@ -166,7 +166,7 @@ int BUF_MEM_grow_clean(BUF_MEM *str, int /* This limit is sufficient to ensure (len+3)/3*4 < 2**31 */ if (len > LIMIT_BEFORE_EXPANSION) { - BUFerr(BUF_F_BUF_MEM_GROW,ERR_R_MALLOC_FAILURE); + BUFerr(BUF_F_BUF_MEM_GROW_CLEAN,ERR_R_MALLOC_FAILURE); return 0; } n=(len+3)/3*4; Modified: releng/7.4/crypto/openssl/ssl/s3_srvr.c ============================================================================== --- releng/7.4/crypto/openssl/ssl/s3_srvr.c Wed May 30 11:48:57 2012 (r236303) +++ releng/7.4/crypto/openssl/ssl/s3_srvr.c Wed May 30 12:01:28 2012 (r236304) @@ -698,14 +698,6 @@ int ssl3_check_client_hello(SSL *s) int ok; long n; - /* We only allow the client to restart the handshake once per - * negotiation. */ - if (s->s3->flags & SSL3_FLAGS_SGC_RESTART_DONE) - { - SSLerr(SSL_F_SSL3_CHECK_CLIENT_HELLO, SSL_R_MULTIPLE_SGC_RESTARTS); - return -1; - } - /* this function is called when we really expect a Certificate message, * so permit appropriate message length */ n=s->method->ssl_get_message(s, @@ -718,6 +710,13 @@ int ssl3_check_client_hello(SSL *s) s->s3->tmp.reuse_message = 1; if (s->s3->tmp.message_type == SSL3_MT_CLIENT_HELLO) { + /* We only allow the client to restart the handshake once per + * negotiation. */ + if (s->s3->flags & SSL3_FLAGS_SGC_RESTART_DONE) + { + SSLerr(SSL_F_SSL3_CHECK_CLIENT_HELLO, SSL_R_MULTIPLE_SGC_RESTARTS); + return -1; + } /* Throw away what we have done so far in the current handshake, * which will now be aborted. (A full SSL_clear would be too much.) * I hope that tmp.dh is the only thing that may need to be cleared Modified: releng/7.4/secure/lib/libcrypt/crypt-des.c ============================================================================== --- releng/7.4/secure/lib/libcrypt/crypt-des.c Wed May 30 11:48:57 2012 (r236303) +++ releng/7.4/secure/lib/libcrypt/crypt-des.c Wed May 30 12:01:28 2012 (r236304) @@ -606,7 +606,7 @@ crypt_des(const char *key, const char *s q = (u_char *)keybuf; while (q - (u_char *)keybuf - 8) { *q++ = *key << 1; - if (*(q - 1)) + if (*key != '\0') key++; } if (des_setkey((char *)keybuf)) Modified: releng/7.4/sys/conf/newvers.sh ============================================================================== --- releng/7.4/sys/conf/newvers.sh Wed May 30 11:48:57 2012 (r236303) +++ releng/7.4/sys/conf/newvers.sh Wed May 30 12:01:28 2012 (r236304) @@ -32,7 +32,7 @@ TYPE="FreeBSD" REVISION="7.4" -BRANCH="RELEASE-p7" +BRANCH="RELEASE-p8" if [ "X${BRANCH_OVERRIDE}" != "X" ]; then BRANCH=${BRANCH_OVERRIDE} fi Modified: releng/8.1/UPDATING ============================================================================== --- releng/8.1/UPDATING Wed May 30 11:48:57 2012 (r236303) +++ releng/8.1/UPDATING Wed May 30 12:01:28 2012 (r236304) @@ -15,6 +15,12 @@ NOTE TO PEOPLE WHO THINK THAT FreeBSD 8. debugging tools present in HEAD were left in place because sun4v support still needs work to become production ready. +20120530: p10 FreeBSD-SA-12:01.openssl (revised), + FreeBSD-SA-12:02.crypt + Update the previous openssl fix. [12:01] + + Fix a bug in crypt(3) ignoring characters of a passphrase. [12:02] + 20120503: p9 FreeBSD-SA-12:01.openssl Fix multiple OpenSSL vulnerabilities. Modified: releng/8.1/crypto/openssl/crypto/buffer/buffer.c ============================================================================== --- releng/8.1/crypto/openssl/crypto/buffer/buffer.c Wed May 30 11:48:57 2012 (r236303) +++ releng/8.1/crypto/openssl/crypto/buffer/buffer.c Wed May 30 12:01:28 2012 (r236304) @@ -166,7 +166,7 @@ int BUF_MEM_grow_clean(BUF_MEM *str, int /* This limit is sufficient to ensure (len+3)/3*4 < 2**31 */ if (len > LIMIT_BEFORE_EXPANSION) { - BUFerr(BUF_F_BUF_MEM_GROW,ERR_R_MALLOC_FAILURE); + BUFerr(BUF_F_BUF_MEM_GROW_CLEAN,ERR_R_MALLOC_FAILURE); return 0; } n=(len+3)/3*4; Modified: releng/8.1/crypto/openssl/ssl/s3_srvr.c ============================================================================== --- releng/8.1/crypto/openssl/ssl/s3_srvr.c Wed May 30 11:48:57 2012 (r236303) +++ releng/8.1/crypto/openssl/ssl/s3_srvr.c Wed May 30 12:01:28 2012 (r236304) @@ -698,14 +698,6 @@ int ssl3_check_client_hello(SSL *s) int ok; long n; - /* We only allow the client to restart the handshake once per - * negotiation. */ - if (s->s3->flags & SSL3_FLAGS_SGC_RESTART_DONE) - { - SSLerr(SSL_F_SSL3_CHECK_CLIENT_HELLO, SSL_R_MULTIPLE_SGC_RESTARTS); - return -1; - } - /* this function is called when we really expect a Certificate message, * so permit appropriate message length */ n=s->method->ssl_get_message(s, @@ -718,6 +710,13 @@ int ssl3_check_client_hello(SSL *s) s->s3->tmp.reuse_message = 1; if (s->s3->tmp.message_type == SSL3_MT_CLIENT_HELLO) { + /* We only allow the client to restart the handshake once per + * negotiation. */ + if (s->s3->flags & SSL3_FLAGS_SGC_RESTART_DONE) + { + SSLerr(SSL_F_SSL3_CHECK_CLIENT_HELLO, SSL_R_MULTIPLE_SGC_RESTARTS); + return -1; + } /* Throw away what we have done so far in the current handshake, * which will now be aborted. (A full SSL_clear would be too much.) * I hope that tmp.dh is the only thing that may need to be cleared Modified: releng/8.1/secure/lib/libcrypt/crypt-des.c ============================================================================== --- releng/8.1/secure/lib/libcrypt/crypt-des.c Wed May 30 11:48:57 2012 (r236303) +++ releng/8.1/secure/lib/libcrypt/crypt-des.c Wed May 30 12:01:28 2012 (r236304) @@ -606,7 +606,7 @@ crypt_des(const char *key, const char *s q = (u_char *)keybuf; while (q - (u_char *)keybuf - 8) { *q++ = *key << 1; - if (*(q - 1)) + if (*key != '\0') key++; } if (des_setkey((char *)keybuf)) Modified: releng/8.1/sys/conf/newvers.sh ============================================================================== --- releng/8.1/sys/conf/newvers.sh Wed May 30 11:48:57 2012 (r236303) +++ releng/8.1/sys/conf/newvers.sh Wed May 30 12:01:28 2012 (r236304) @@ -32,7 +32,7 @@ TYPE="FreeBSD" REVISION="8.1" -BRANCH="RELEASE-p9" +BRANCH="RELEASE-p10" if [ "X${BRANCH_OVERRIDE}" != "X" ]; then BRANCH=${BRANCH_OVERRIDE} fi Modified: releng/8.2/UPDATING ============================================================================== --- releng/8.2/UPDATING Wed May 30 11:48:57 2012 (r236303) +++ releng/8.2/UPDATING Wed May 30 12:01:28 2012 (r236304) @@ -15,6 +15,12 @@ NOTE TO PEOPLE WHO THINK THAT FreeBSD 8. debugging tools present in HEAD were left in place because sun4v support still needs work to become production ready. +20120530: p8 FreeBSD-SA-12:01.openssl (revised), + FreeBSD-SA-12:02.crypt + Update the previous openssl fix. [12:01] + + Fix a bug in crypt(3) ignoring characters of a passphrase. [12:02] + 20120503: p7 FreeBSD-SA-12:01.openssl Fix multiple OpenSSL vulnerabilities. Modified: releng/8.2/crypto/openssl/crypto/buffer/buffer.c ============================================================================== --- releng/8.2/crypto/openssl/crypto/buffer/buffer.c Wed May 30 11:48:57 2012 (r236303) +++ releng/8.2/crypto/openssl/crypto/buffer/buffer.c Wed May 30 12:01:28 2012 (r236304) @@ -166,7 +166,7 @@ int BUF_MEM_grow_clean(BUF_MEM *str, int /* This limit is sufficient to ensure (len+3)/3*4 < 2**31 */ if (len > LIMIT_BEFORE_EXPANSION) { - BUFerr(BUF_F_BUF_MEM_GROW,ERR_R_MALLOC_FAILURE); + BUFerr(BUF_F_BUF_MEM_GROW_CLEAN,ERR_R_MALLOC_FAILURE); return 0; } n=(len+3)/3*4; Modified: releng/8.2/crypto/openssl/ssl/s3_srvr.c ============================================================================== --- releng/8.2/crypto/openssl/ssl/s3_srvr.c Wed May 30 11:48:57 2012 (r236303) +++ releng/8.2/crypto/openssl/ssl/s3_srvr.c Wed May 30 12:01:28 2012 (r236304) @@ -698,14 +698,6 @@ int ssl3_check_client_hello(SSL *s) int ok; long n; - /* We only allow the client to restart the handshake once per - * negotiation. */ - if (s->s3->flags & SSL3_FLAGS_SGC_RESTART_DONE) - { - SSLerr(SSL_F_SSL3_CHECK_CLIENT_HELLO, SSL_R_MULTIPLE_SGC_RESTARTS); - return -1; - } - /* this function is called when we really expect a Certificate message, * so permit appropriate message length */ n=s->method->ssl_get_message(s, @@ -718,6 +710,13 @@ int ssl3_check_client_hello(SSL *s) s->s3->tmp.reuse_message = 1; if (s->s3->tmp.message_type == SSL3_MT_CLIENT_HELLO) { + /* We only allow the client to restart the handshake once per + * negotiation. */ + if (s->s3->flags & SSL3_FLAGS_SGC_RESTART_DONE) + { + SSLerr(SSL_F_SSL3_CHECK_CLIENT_HELLO, SSL_R_MULTIPLE_SGC_RESTARTS); + return -1; + } /* Throw away what we have done so far in the current handshake, * which will now be aborted. (A full SSL_clear would be too much.) * I hope that tmp.dh is the only thing that may need to be cleared Modified: releng/8.2/secure/lib/libcrypt/crypt-des.c ============================================================================== --- releng/8.2/secure/lib/libcrypt/crypt-des.c Wed May 30 11:48:57 2012 (r236303) +++ releng/8.2/secure/lib/libcrypt/crypt-des.c Wed May 30 12:01:28 2012 (r236304) @@ -606,7 +606,7 @@ crypt_des(const char *key, const char *s q = (u_char *)keybuf; while (q - (u_char *)keybuf - 8) { *q++ = *key << 1; - if (*(q - 1)) + if (*key != '\0') key++; } if (des_setkey((char *)keybuf)) Modified: releng/8.2/sys/conf/newvers.sh ============================================================================== --- releng/8.2/sys/conf/newvers.sh Wed May 30 11:48:57 2012 (r236303) +++ releng/8.2/sys/conf/newvers.sh Wed May 30 12:01:28 2012 (r236304) @@ -32,7 +32,7 @@ TYPE="FreeBSD" REVISION="8.2" -BRANCH="RELEASE-p7" +BRANCH="RELEASE-p8" if [ "X${BRANCH_OVERRIDE}" != "X" ]; then BRANCH=${BRANCH_OVERRIDE} fi Modified: releng/8.3/UPDATING ============================================================================== --- releng/8.3/UPDATING Wed May 30 11:48:57 2012 (r236303) +++ releng/8.3/UPDATING Wed May 30 12:01:28 2012 (r236304) @@ -15,6 +15,12 @@ NOTE TO PEOPLE WHO THINK THAT FreeBSD 8. debugging tools present in HEAD were left in place because sun4v support still needs work to become production ready. +20120530: p2 FreeBSD-SA-12:01.openssl (revised), + FreeBSD-SA-12:02.crypt + Update the previous openssl fix. [12:01] + + Fix a bug in crypt(3) ignoring characters of a passphrase. [12:02] + 20120503: p1 FreeBSD-SA-12:01.openssl Fix multiple OpenSSL vulnerabilities. Modified: releng/8.3/crypto/openssl/crypto/buffer/buffer.c ============================================================================== --- releng/8.3/crypto/openssl/crypto/buffer/buffer.c Wed May 30 11:48:57 2012 (r236303) +++ releng/8.3/crypto/openssl/crypto/buffer/buffer.c Wed May 30 12:01:28 2012 (r236304) @@ -166,7 +166,7 @@ int BUF_MEM_grow_clean(BUF_MEM *str, int /* This limit is sufficient to ensure (len+3)/3*4 < 2**31 */ if (len > LIMIT_BEFORE_EXPANSION) { - BUFerr(BUF_F_BUF_MEM_GROW,ERR_R_MALLOC_FAILURE); + BUFerr(BUF_F_BUF_MEM_GROW_CLEAN,ERR_R_MALLOC_FAILURE); return 0; } n=(len+3)/3*4; Modified: releng/8.3/crypto/openssl/ssl/s3_srvr.c ============================================================================== --- releng/8.3/crypto/openssl/ssl/s3_srvr.c Wed May 30 11:48:57 2012 (r236303) +++ releng/8.3/crypto/openssl/ssl/s3_srvr.c Wed May 30 12:01:28 2012 (r236304) @@ -698,14 +698,6 @@ int ssl3_check_client_hello(SSL *s) int ok; long n; - /* We only allow the client to restart the handshake once per - * negotiation. */ - if (s->s3->flags & SSL3_FLAGS_SGC_RESTART_DONE) - { - SSLerr(SSL_F_SSL3_CHECK_CLIENT_HELLO, SSL_R_MULTIPLE_SGC_RESTARTS); - return -1; - } - /* this function is called when we really expect a Certificate message, * so permit appropriate message length */ n=s->method->ssl_get_message(s, @@ -718,6 +710,13 @@ int ssl3_check_client_hello(SSL *s) s->s3->tmp.reuse_message = 1; if (s->s3->tmp.message_type == SSL3_MT_CLIENT_HELLO) { + /* We only allow the client to restart the handshake once per + * negotiation. */ + if (s->s3->flags & SSL3_FLAGS_SGC_RESTART_DONE) + { + SSLerr(SSL_F_SSL3_CHECK_CLIENT_HELLO, SSL_R_MULTIPLE_SGC_RESTARTS); + return -1; + } /* Throw away what we have done so far in the current handshake, * which will now be aborted. (A full SSL_clear would be too much.) */ #ifndef OPENSSL_NO_DH Modified: releng/8.3/secure/lib/libcrypt/crypt-des.c ============================================================================== --- releng/8.3/secure/lib/libcrypt/crypt-des.c Wed May 30 11:48:57 2012 (r236303) +++ releng/8.3/secure/lib/libcrypt/crypt-des.c Wed May 30 12:01:28 2012 (r236304) @@ -606,7 +606,7 @@ crypt_des(const char *key, const char *s q = (u_char *)keybuf; while (q - (u_char *)keybuf - 8) { *q++ = *key << 1; - if (*(q - 1)) + if (*key != '\0') key++; } if (des_setkey((char *)keybuf)) Modified: releng/8.3/sys/conf/newvers.sh ============================================================================== --- releng/8.3/sys/conf/newvers.sh Wed May 30 11:48:57 2012 (r236303) +++ releng/8.3/sys/conf/newvers.sh Wed May 30 12:01:28 2012 (r236304) @@ -32,7 +32,7 @@ TYPE="FreeBSD" REVISION="8.3" -BRANCH="RELEASE-p1" +BRANCH="RELEASE-p2" if [ "X${BRANCH_OVERRIDE}" != "X" ]; then BRANCH=${BRANCH_OVERRIDE} fi Modified: releng/9.0/UPDATING ============================================================================== --- releng/9.0/UPDATING Wed May 30 11:48:57 2012 (r236303) +++ releng/9.0/UPDATING Wed May 30 12:01:28 2012 (r236304) @@ -9,6 +9,12 @@ handbook. Items affecting the ports and packages system can be found in /usr/ports/UPDATING. Please read that file before running portupgrade. +20120530: p2 FreeBSD-SA-12:01.openssl (revised), + FreeBSD-SA-12:02.crypt + Update the previous openssl fix. [12:01] + + Fix a bug in crypt(3) ignoring characters of a passphrase. [12:02] + 20120503: p1 FreeBSD-SA-12:01.openssl Fix multiple OpenSSL vulnerabilities. Modified: releng/9.0/crypto/openssl/crypto/buffer/buffer.c ============================================================================== --- releng/9.0/crypto/openssl/crypto/buffer/buffer.c Wed May 30 11:48:57 2012 (r236303) +++ releng/9.0/crypto/openssl/crypto/buffer/buffer.c Wed May 30 12:01:28 2012 (r236304) @@ -166,7 +166,7 @@ int BUF_MEM_grow_clean(BUF_MEM *str, int /* This limit is sufficient to ensure (len+3)/3*4 < 2**31 */ if (len > LIMIT_BEFORE_EXPANSION) { - BUFerr(BUF_F_BUF_MEM_GROW,ERR_R_MALLOC_FAILURE); + BUFerr(BUF_F_BUF_MEM_GROW_CLEAN,ERR_R_MALLOC_FAILURE); return 0; } n=(len+3)/3*4; Modified: releng/9.0/crypto/openssl/ssl/s3_srvr.c ============================================================================== --- releng/9.0/crypto/openssl/ssl/s3_srvr.c Wed May 30 11:48:57 2012 (r236303) +++ releng/9.0/crypto/openssl/ssl/s3_srvr.c Wed May 30 12:01:28 2012 (r236304) @@ -698,14 +698,6 @@ int ssl3_check_client_hello(SSL *s) int ok; long n; - /* We only allow the client to restart the handshake once per - * negotiation. */ - if (s->s3->flags & SSL3_FLAGS_SGC_RESTART_DONE) - { - SSLerr(SSL_F_SSL3_CHECK_CLIENT_HELLO, SSL_R_MULTIPLE_SGC_RESTARTS); - return -1; - } - /* this function is called when we really expect a Certificate message, * so permit appropriate message length */ n=s->method->ssl_get_message(s, @@ -718,6 +710,13 @@ int ssl3_check_client_hello(SSL *s) s->s3->tmp.reuse_message = 1; if (s->s3->tmp.message_type == SSL3_MT_CLIENT_HELLO) { + /* We only allow the client to restart the handshake once per + * negotiation. */ + if (s->s3->flags & SSL3_FLAGS_SGC_RESTART_DONE) + { + SSLerr(SSL_F_SSL3_CHECK_CLIENT_HELLO, SSL_R_MULTIPLE_SGC_RESTARTS); + return -1; + } /* Throw away what we have done so far in the current handshake, * which will now be aborted. (A full SSL_clear would be too much.) */ #ifndef OPENSSL_NO_DH Modified: releng/9.0/secure/lib/libcrypt/crypt-des.c ============================================================================== --- releng/9.0/secure/lib/libcrypt/crypt-des.c Wed May 30 11:48:57 2012 (r236303) +++ releng/9.0/secure/lib/libcrypt/crypt-des.c Wed May 30 12:01:28 2012 (r236304) @@ -606,7 +606,7 @@ crypt_des(const char *key, const char *s q = (u_char *)keybuf; while (q - (u_char *)keybuf - 8) { *q++ = *key << 1; - if (*(q - 1)) + if (*key != '\0') key++; } if (des_setkey((char *)keybuf)) Modified: releng/9.0/sys/conf/newvers.sh ============================================================================== --- releng/9.0/sys/conf/newvers.sh Wed May 30 11:48:57 2012 (r236303) +++ releng/9.0/sys/conf/newvers.sh Wed May 30 12:01:28 2012 (r236304) @@ -32,7 +32,7 @@ TYPE="FreeBSD" REVISION="9.0" -BRANCH="RELEASE-p1" +BRANCH="RELEASE-p2" if [ "X${BRANCH_OVERRIDE}" != "X" ]; then BRANCH=${BRANCH_OVERRIDE} fi
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201205301201.q4UC1TUr047246>