From delphij at FreeBSD.org Tue Apr 8 18:27:49 2014 From: delphij at FreeBSD.org (Xin LI) Date: Tue, 8 Apr 2014 18:27:47 +0000 (UTC) Subject: svn commit: r264267 - in releng/10.0: . crypto/openssl/crypto/bn crypto/openssl/crypto/ec crypto/openssl/ssl sys/conf sys/fs/nfsserver Message-ID: <201404081827.s38IRlGS049095@svn.freebsd.org> Author: delphij Date: Tue Apr 8 18:27:46 2014 New Revision: 264267 URL: http://svnweb.freebsd.org/changeset/base/264267 Log: Fix NFS deadlock vulnerability. [SA-14:05] Fix "Heartbleed" vulnerability and ECDSA Cache Side-channel Attack in OpenSSL. [SA-14:06] Approved by: so Modified: releng/10.0/UPDATING releng/10.0/crypto/openssl/crypto/bn/bn.h releng/10.0/crypto/openssl/crypto/bn/bn_lib.c releng/10.0/crypto/openssl/crypto/ec/ec2_mult.c releng/10.0/crypto/openssl/ssl/d1_both.c releng/10.0/crypto/openssl/ssl/t1_lib.c releng/10.0/sys/conf/newvers.sh releng/10.0/sys/fs/nfsserver/nfs_nfsdserv.c Modified: releng/10.0/UPDATING ============================================================================== --- releng/10.0/UPDATING Tue Apr 8 18:27:39 2014 (r264266) +++ releng/10.0/UPDATING Tue Apr 8 18:27:46 2014 (r264267) @@ -16,6 +16,12 @@ from older versions of FreeBSD, try WITH stable/10, and then rebuild without this option. The bootstrap process from older version of current is a bit fragile. +20140408: p1 FreeBSD-SA-14:05.nfsserver + FreeBSD-SA-14:06.openssl + Fix deadlock in the NFS server. [SA-14:05] + + Fix multiple vulnerabilities in OpenSSL. [SA-14:06] + 20131223: The behavior of gss_pseudo_random() for the krb5 mechanism has changed, for applications requesting a longer random string Modified: releng/10.0/crypto/openssl/crypto/bn/bn.h ============================================================================== --- releng/10.0/crypto/openssl/crypto/bn/bn.h Tue Apr 8 18:27:39 2014 (r264266) +++ releng/10.0/crypto/openssl/crypto/bn/bn.h Tue Apr 8 18:27:46 2014 (r264267) @@ -538,6 +538,8 @@ BIGNUM *BN_mod_inverse(BIGNUM *ret, BIGNUM *BN_mod_sqrt(BIGNUM *ret, const BIGNUM *a, const BIGNUM *n,BN_CTX *ctx); +void BN_consttime_swap(BN_ULONG swap, BIGNUM *a, BIGNUM *b, int nwords); + /* Deprecated versions */ #ifndef OPENSSL_NO_DEPRECATED BIGNUM *BN_generate_prime(BIGNUM *ret,int bits,int safe, @@ -774,11 +776,20 @@ int RAND_pseudo_bytes(unsigned char *buf #define bn_fix_top(a) bn_check_top(a) +#define bn_check_size(bn, bits) bn_wcheck_size(bn, ((bits+BN_BITS2-1))/BN_BITS2) +#define bn_wcheck_size(bn, words) \ + do { \ + const BIGNUM *_bnum2 = (bn); \ + assert(words <= (_bnum2)->dmax && words >= (_bnum2)->top); \ + } while(0) + #else /* !BN_DEBUG */ #define bn_pollute(a) #define bn_check_top(a) #define bn_fix_top(a) bn_correct_top(a) +#define bn_check_size(bn, bits) +#define bn_wcheck_size(bn, words) #endif Modified: releng/10.0/crypto/openssl/crypto/bn/bn_lib.c ============================================================================== --- releng/10.0/crypto/openssl/crypto/bn/bn_lib.c Tue Apr 8 18:27:39 2014 (r264266) +++ releng/10.0/crypto/openssl/crypto/bn/bn_lib.c Tue Apr 8 18:27:46 2014 (r264267) @@ -824,3 +824,55 @@ int bn_cmp_part_words(const BN_ULONG *a, } return bn_cmp_words(a,b,cl); } + +/* + * Constant-time conditional swap of a and b. + * a and b are swapped if condition is not 0. The code assumes that at most one bit of condition is set. + * nwords is the number of words to swap. The code assumes that at least nwords are allocated in both a and b, + * and that no more than nwords are used by either a or b. + * a and b cannot be the same number + */ +void BN_consttime_swap(BN_ULONG condition, BIGNUM *a, BIGNUM *b, int nwords) + { + BN_ULONG t; + int i; + + bn_wcheck_size(a, nwords); + bn_wcheck_size(b, nwords); + + assert(a != b); + assert((condition & (condition - 1)) == 0); + assert(sizeof(BN_ULONG) >= sizeof(int)); + + condition = ((condition - 1) >> (BN_BITS2 - 1)) - 1; + + t = (a->top^b->top) & condition; + a->top ^= t; + b->top ^= t; + +#define BN_CONSTTIME_SWAP(ind) \ + do { \ + t = (a->d[ind] ^ b->d[ind]) & condition; \ + a->d[ind] ^= t; \ + b->d[ind] ^= t; \ + } while (0) + + + switch (nwords) { + default: + for (i = 10; i < nwords; i++) + BN_CONSTTIME_SWAP(i); + /* Fallthrough */ + case 10: BN_CONSTTIME_SWAP(9); /* Fallthrough */ + case 9: BN_CONSTTIME_SWAP(8); /* Fallthrough */ + case 8: BN_CONSTTIME_SWAP(7); /* Fallthrough */ + case 7: BN_CONSTTIME_SWAP(6); /* Fallthrough */ + case 6: BN_CONSTTIME_SWAP(5); /* Fallthrough */ + case 5: BN_CONSTTIME_SWAP(4); /* Fallthrough */ + case 4: BN_CONSTTIME_SWAP(3); /* Fallthrough */ + case 3: BN_CONSTTIME_SWAP(2); /* Fallthrough */ + case 2: BN_CONSTTIME_SWAP(1); /* Fallthrough */ + case 1: BN_CONSTTIME_SWAP(0); + } +#undef BN_CONSTTIME_SWAP +} Modified: releng/10.0/crypto/openssl/crypto/ec/ec2_mult.c ============================================================================== --- releng/10.0/crypto/openssl/crypto/ec/ec2_mult.c Tue Apr 8 18:27:39 2014 (r264266) +++ releng/10.0/crypto/openssl/crypto/ec/ec2_mult.c Tue Apr 8 18:27:46 2014 (r264267) @@ -208,11 +208,15 @@ static int gf2m_Mxy(const EC_GROUP *grou return ret; } + /* Computes scalar*point and stores the result in r. * point can not equal r. - * Uses algorithm 2P of + * Uses a modified algorithm 2P of * Lopez, J. and Dahab, R. "Fast multiplication on elliptic curves over * GF(2^m) without precomputation" (CHES '99, LNCS 1717). + * + * To protect against side-channel attack the function uses constant time swap, + * avoiding conditional branches. */ static int ec_GF2m_montgomery_point_multiply(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar, const EC_POINT *point, BN_CTX *ctx) @@ -246,6 +250,11 @@ static int ec_GF2m_montgomery_point_mult x2 = &r->X; z2 = &r->Y; + bn_wexpand(x1, group->field.top); + bn_wexpand(z1, group->field.top); + bn_wexpand(x2, group->field.top); + bn_wexpand(z2, group->field.top); + if (!BN_GF2m_mod_arr(x1, &point->X, group->poly)) goto err; /* x1 = x */ if (!BN_one(z1)) goto err; /* z1 = 1 */ if (!group->meth->field_sqr(group, z2, x1, ctx)) goto err; /* z2 = x1^2 = x^2 */ @@ -270,16 +279,12 @@ static int ec_GF2m_montgomery_point_mult word = scalar->d[i]; while (mask) { - if (word & mask) - { - if (!gf2m_Madd(group, &point->X, x1, z1, x2, z2, ctx)) goto err; - if (!gf2m_Mdouble(group, x2, z2, ctx)) goto err; - } - else - { - if (!gf2m_Madd(group, &point->X, x2, z2, x1, z1, ctx)) goto err; - if (!gf2m_Mdouble(group, x1, z1, ctx)) goto err; - } + BN_consttime_swap(word & mask, x1, x2, group->field.top); + BN_consttime_swap(word & mask, z1, z2, group->field.top); + if (!gf2m_Madd(group, &point->X, x2, z2, x1, z1, ctx)) goto err; + if (!gf2m_Mdouble(group, x1, z1, ctx)) goto err; + BN_consttime_swap(word & mask, x1, x2, group->field.top); + BN_consttime_swap(word & mask, z1, z2, group->field.top); mask >>= 1; } mask = BN_TBIT; Modified: releng/10.0/crypto/openssl/ssl/d1_both.c ============================================================================== --- releng/10.0/crypto/openssl/ssl/d1_both.c Tue Apr 8 18:27:39 2014 (r264266) +++ releng/10.0/crypto/openssl/ssl/d1_both.c Tue Apr 8 18:27:46 2014 (r264267) @@ -1458,26 +1458,36 @@ dtls1_process_heartbeat(SSL *s) unsigned int payload; unsigned int padding = 16; /* Use minimum padding */ - /* Read type and payload length first */ - hbtype = *p++; - n2s(p, payload); - pl = p; - if (s->msg_callback) s->msg_callback(0, s->version, TLS1_RT_HEARTBEAT, &s->s3->rrec.data[0], s->s3->rrec.length, s, s->msg_callback_arg); + /* Read type and payload length first */ + if (1 + 2 + 16 > s->s3->rrec.length) + return 0; /* silently discard */ + hbtype = *p++; + n2s(p, payload); + if (1 + 2 + payload + 16 > s->s3->rrec.length) + return 0; /* silently discard per RFC 6520 sec. 4 */ + pl = p; + if (hbtype == TLS1_HB_REQUEST) { unsigned char *buffer, *bp; + unsigned int write_length = 1 /* heartbeat type */ + + 2 /* heartbeat length */ + + payload + padding; int r; + if (write_length > SSL3_RT_MAX_PLAIN_LENGTH) + return 0; + /* Allocate memory for the response, size is 1 byte * message type, plus 2 bytes payload length, plus * payload, plus padding */ - buffer = OPENSSL_malloc(1 + 2 + payload + padding); + buffer = OPENSSL_malloc(write_length); bp = buffer; /* Enter response type, length and copy payload */ @@ -1488,11 +1498,11 @@ dtls1_process_heartbeat(SSL *s) /* Random padding */ RAND_pseudo_bytes(bp, padding); - r = dtls1_write_bytes(s, TLS1_RT_HEARTBEAT, buffer, 3 + payload + padding); + r = dtls1_write_bytes(s, TLS1_RT_HEARTBEAT, buffer, write_length); if (r >= 0 && s->msg_callback) s->msg_callback(1, s->version, TLS1_RT_HEARTBEAT, - buffer, 3 + payload + padding, + buffer, write_length, s, s->msg_callback_arg); OPENSSL_free(buffer); Modified: releng/10.0/crypto/openssl/ssl/t1_lib.c ============================================================================== --- releng/10.0/crypto/openssl/ssl/t1_lib.c Tue Apr 8 18:27:39 2014 (r264266) +++ releng/10.0/crypto/openssl/ssl/t1_lib.c Tue Apr 8 18:27:46 2014 (r264267) @@ -2486,16 +2486,20 @@ tls1_process_heartbeat(SSL *s) unsigned int payload; unsigned int padding = 16; /* Use minimum padding */ - /* Read type and payload length first */ - hbtype = *p++; - n2s(p, payload); - pl = p; - if (s->msg_callback) s->msg_callback(0, s->version, TLS1_RT_HEARTBEAT, &s->s3->rrec.data[0], s->s3->rrec.length, s, s->msg_callback_arg); + /* Read type and payload length first */ + if (1 + 2 + 16 > s->s3->rrec.length) + return 0; /* silently discard */ + hbtype = *p++; + n2s(p, payload); + if (1 + 2 + payload + 16 > s->s3->rrec.length) + return 0; /* silently discard per RFC 6520 sec. 4 */ + pl = p; + if (hbtype == TLS1_HB_REQUEST) { unsigned char *buffer, *bp; Modified: releng/10.0/sys/conf/newvers.sh ============================================================================== --- releng/10.0/sys/conf/newvers.sh Tue Apr 8 18:27:39 2014 (r264266) +++ releng/10.0/sys/conf/newvers.sh Tue Apr 8 18:27:46 2014 (r264267) @@ -32,7 +32,7 @@ TYPE="FreeBSD" REVISION="10.0" -BRANCH="RELEASE" +BRANCH="RELEASE-p1" if [ "X${BRANCH_OVERRIDE}" != "X" ]; then BRANCH=${BRANCH_OVERRIDE} fi Modified: releng/10.0/sys/fs/nfsserver/nfs_nfsdserv.c ============================================================================== --- releng/10.0/sys/fs/nfsserver/nfs_nfsdserv.c Tue Apr 8 18:27:39 2014 (r264266) +++ releng/10.0/sys/fs/nfsserver/nfs_nfsdserv.c Tue Apr 8 18:27:46 2014 (r264267) @@ -1457,10 +1457,23 @@ nfsrvd_rename(struct nfsrv_descript *nd, nfsvno_relpathbuf(&fromnd); goto out; } + /* + * Unlock dp in this code section, so it is unlocked before + * tdp gets locked. This avoids a potential LOR if tdp is the + * parent directory of dp. + */ if (nd->nd_flag & ND_NFSV4) { tdp = todp; tnes = *toexp; - tdirfor_ret = nfsvno_getattr(tdp, &tdirfor, nd->nd_cred, p, 0); + if (dp != tdp) { + NFSVOPUNLOCK(dp, 0); + tdirfor_ret = nfsvno_getattr(tdp, &tdirfor, nd->nd_cred, + p, 0); /* Might lock tdp. */ + } else { + tdirfor_ret = nfsvno_getattr(tdp, &tdirfor, nd->nd_cred, + p, 1); + NFSVOPUNLOCK(dp, 0); + } } else { tfh.nfsrvfh_len = 0; error = nfsrv_mtofh(nd, &tfh); @@ -1481,10 +1494,12 @@ nfsrvd_rename(struct nfsrv_descript *nd, tnes = *exp; tdirfor_ret = nfsvno_getattr(tdp, &tdirfor, nd->nd_cred, p, 1); + NFSVOPUNLOCK(dp, 0); } else { + NFSVOPUNLOCK(dp, 0); nd->nd_cred->cr_uid = nd->nd_saveduid; nfsd_fhtovp(nd, &tfh, LK_EXCLUSIVE, &tdp, &tnes, NULL, - 0, p); + 0, p); /* Locks tdp. */ if (tdp) { tdirfor_ret = nfsvno_getattr(tdp, &tdirfor, nd->nd_cred, p, 1); @@ -1499,7 +1514,7 @@ nfsrvd_rename(struct nfsrv_descript *nd, if (error) { if (tdp) vrele(tdp); - vput(dp); + vrele(dp); nfsvno_relpathbuf(&fromnd); nfsvno_relpathbuf(&tond); goto out; @@ -1514,7 +1529,7 @@ nfsrvd_rename(struct nfsrv_descript *nd, } if (tdp) vrele(tdp); - vput(dp); + vrele(dp); nfsvno_relpathbuf(&fromnd); nfsvno_relpathbuf(&tond); goto out; @@ -1523,7 +1538,7 @@ nfsrvd_rename(struct nfsrv_descript *nd, /* * Done parsing, now down to business. */ - nd->nd_repstat = nfsvno_namei(nd, &fromnd, dp, 1, exp, p, &fdirp); + nd->nd_repstat = nfsvno_namei(nd, &fromnd, dp, 0, exp, p, &fdirp); if (nd->nd_repstat) { if (nd->nd_flag & ND_NFSV3) { nfsrv_wcc(nd, fdirfor_ret, &fdirfor, fdiraft_ret, From delphij at FreeBSD.org Tue Apr 8 23:16:11 2014 From: delphij at FreeBSD.org (Xin LI) Date: Tue, 8 Apr 2014 23:16:05 +0000 (UTC) Subject: svn commit: r264284 - in releng: 8.3 8.3/crypto/openssl/crypto/bn 8.3/crypto/openssl/crypto/ec 8.3/sys/conf 8.3/sys/fs/nfsserver 8.4 8.4/crypto/openssl/crypto/bn 8.4/crypto/openssl/crypto/ec 8.4/sy... Message-ID: <201404082316.s38NG5mu068730@svn.freebsd.org> Author: delphij Date: Tue Apr 8 23:16:05 2014 New Revision: 264284 URL: http://svnweb.freebsd.org/changeset/base/264284 Log: Fix NFS deadlock vulnerability. [SA-14:05] Fix ECDSA Cache Side-channel Attack in OpenSSL. [SA-14:06] Approved by: so Modified: releng/8.3/UPDATING releng/8.3/crypto/openssl/crypto/bn/bn.h releng/8.3/crypto/openssl/crypto/bn/bn_lib.c releng/8.3/crypto/openssl/crypto/ec/ec2_mult.c releng/8.3/sys/conf/newvers.sh releng/8.3/sys/fs/nfsserver/nfs_nfsdserv.c releng/8.4/UPDATING releng/8.4/crypto/openssl/crypto/bn/bn.h releng/8.4/crypto/openssl/crypto/bn/bn_lib.c releng/8.4/crypto/openssl/crypto/ec/ec2_mult.c releng/8.4/sys/conf/newvers.sh releng/8.4/sys/fs/nfsserver/nfs_nfsdserv.c releng/9.1/UPDATING releng/9.1/crypto/openssl/crypto/bn/bn.h releng/9.1/crypto/openssl/crypto/bn/bn_lib.c releng/9.1/crypto/openssl/crypto/ec/ec2_mult.c releng/9.1/sys/conf/newvers.sh releng/9.1/sys/fs/nfsserver/nfs_nfsdserv.c releng/9.2/UPDATING releng/9.2/crypto/openssl/crypto/bn/bn.h releng/9.2/crypto/openssl/crypto/bn/bn_lib.c releng/9.2/crypto/openssl/crypto/ec/ec2_mult.c releng/9.2/sys/conf/newvers.sh releng/9.2/sys/fs/nfsserver/nfs_nfsdserv.c Modified: releng/8.3/UPDATING ============================================================================== --- releng/8.3/UPDATING Tue Apr 8 22:36:39 2014 (r264283) +++ releng/8.3/UPDATING Tue Apr 8 23:16:05 2014 (r264284) @@ -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. +20140408: p15 FreeBSD-SA-14:05.nfsserver + FreeBSD-SA-14:06.openssl + Fix deadlock in the NFS server. [SA-14:05] + + Fix for ECDSA Cache Side-channel Attack in OpenSSL. [SA-14:06] + 20140114: p14 FreeBSD-SA-14:01.bsnmpd FreeBSD-SA-14:02.ntpd FreeBSD-SA-14:04.bind Modified: releng/8.3/crypto/openssl/crypto/bn/bn.h ============================================================================== --- releng/8.3/crypto/openssl/crypto/bn/bn.h Tue Apr 8 22:36:39 2014 (r264283) +++ releng/8.3/crypto/openssl/crypto/bn/bn.h Tue Apr 8 23:16:05 2014 (r264284) @@ -511,6 +511,8 @@ BIGNUM *BN_mod_inverse(BIGNUM *ret, BIGNUM *BN_mod_sqrt(BIGNUM *ret, const BIGNUM *a, const BIGNUM *n,BN_CTX *ctx); +void BN_consttime_swap(BN_ULONG swap, BIGNUM *a, BIGNUM *b, int nwords); + /* Deprecated versions */ #ifndef OPENSSL_NO_DEPRECATED BIGNUM *BN_generate_prime(BIGNUM *ret,int bits,int safe, @@ -740,11 +742,20 @@ int RAND_pseudo_bytes(unsigned char *buf #define bn_fix_top(a) bn_check_top(a) +#define bn_check_size(bn, bits) bn_wcheck_size(bn, ((bits+BN_BITS2-1))/BN_BITS2) +#define bn_wcheck_size(bn, words) \ + do { \ + const BIGNUM *_bnum2 = (bn); \ + assert(words <= (_bnum2)->dmax && words >= (_bnum2)->top); \ + } while(0) + #else /* !BN_DEBUG */ #define bn_pollute(a) #define bn_check_top(a) #define bn_fix_top(a) bn_correct_top(a) +#define bn_check_size(bn, bits) +#define bn_wcheck_size(bn, words) #endif Modified: releng/8.3/crypto/openssl/crypto/bn/bn_lib.c ============================================================================== --- releng/8.3/crypto/openssl/crypto/bn/bn_lib.c Tue Apr 8 22:36:39 2014 (r264283) +++ releng/8.3/crypto/openssl/crypto/bn/bn_lib.c Tue Apr 8 23:16:05 2014 (r264284) @@ -824,3 +824,55 @@ int bn_cmp_part_words(const BN_ULONG *a, } return bn_cmp_words(a,b,cl); } + +/* + * Constant-time conditional swap of a and b. + * a and b are swapped if condition is not 0. The code assumes that at most one bit of condition is set. + * nwords is the number of words to swap. The code assumes that at least nwords are allocated in both a and b, + * and that no more than nwords are used by either a or b. + * a and b cannot be the same number + */ +void BN_consttime_swap(BN_ULONG condition, BIGNUM *a, BIGNUM *b, int nwords) + { + BN_ULONG t; + int i; + + bn_wcheck_size(a, nwords); + bn_wcheck_size(b, nwords); + + assert(a != b); + assert((condition & (condition - 1)) == 0); + assert(sizeof(BN_ULONG) >= sizeof(int)); + + condition = ((condition - 1) >> (BN_BITS2 - 1)) - 1; + + t = (a->top^b->top) & condition; + a->top ^= t; + b->top ^= t; + +#define BN_CONSTTIME_SWAP(ind) \ + do { \ + t = (a->d[ind] ^ b->d[ind]) & condition; \ + a->d[ind] ^= t; \ + b->d[ind] ^= t; \ + } while (0) + + + switch (nwords) { + default: + for (i = 10; i < nwords; i++) + BN_CONSTTIME_SWAP(i); + /* Fallthrough */ + case 10: BN_CONSTTIME_SWAP(9); /* Fallthrough */ + case 9: BN_CONSTTIME_SWAP(8); /* Fallthrough */ + case 8: BN_CONSTTIME_SWAP(7); /* Fallthrough */ + case 7: BN_CONSTTIME_SWAP(6); /* Fallthrough */ + case 6: BN_CONSTTIME_SWAP(5); /* Fallthrough */ + case 5: BN_CONSTTIME_SWAP(4); /* Fallthrough */ + case 4: BN_CONSTTIME_SWAP(3); /* Fallthrough */ + case 3: BN_CONSTTIME_SWAP(2); /* Fallthrough */ + case 2: BN_CONSTTIME_SWAP(1); /* Fallthrough */ + case 1: BN_CONSTTIME_SWAP(0); + } +#undef BN_CONSTTIME_SWAP +} Modified: releng/8.3/crypto/openssl/crypto/ec/ec2_mult.c ============================================================================== --- releng/8.3/crypto/openssl/crypto/ec/ec2_mult.c Tue Apr 8 22:36:39 2014 (r264283) +++ releng/8.3/crypto/openssl/crypto/ec/ec2_mult.c Tue Apr 8 23:16:05 2014 (r264284) @@ -208,9 +208,12 @@ static int gf2m_Mxy(const EC_GROUP *grou /* Computes scalar*point and stores the result in r. * point can not equal r. - * Uses algorithm 2P of + * Uses a modified algorithm 2P of * Lopex, J. and Dahab, R. "Fast multiplication on elliptic curves over * GF(2^m) without precomputation". + * + * To protect against side-channel attack the function uses constant time + * swap avoiding conditional branches. */ static int ec_GF2m_montgomery_point_multiply(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar, const EC_POINT *point, BN_CTX *ctx) @@ -244,6 +247,11 @@ static int ec_GF2m_montgomery_point_mult x2 = &r->X; z2 = &r->Y; + bn_wexpand(x1, group->field.top); + bn_wexpand(z1, group->field.top); + bn_wexpand(x2, group->field.top); + bn_wexpand(z2, group->field.top); + if (!BN_GF2m_mod_arr(x1, &point->X, group->poly)) goto err; /* x1 = x */ if (!BN_one(z1)) goto err; /* z1 = 1 */ if (!group->meth->field_sqr(group, z2, x1, ctx)) goto err; /* z2 = x1^2 = x^2 */ @@ -266,16 +274,12 @@ static int ec_GF2m_montgomery_point_mult { for (; j >= 0; j--) { - if (scalar->d[i] & mask) - { - if (!gf2m_Madd(group, &point->X, x1, z1, x2, z2, ctx)) goto err; - if (!gf2m_Mdouble(group, x2, z2, ctx)) goto err; - } - else - { - if (!gf2m_Madd(group, &point->X, x2, z2, x1, z1, ctx)) goto err; - if (!gf2m_Mdouble(group, x1, z1, ctx)) goto err; - } + BN_consttime_swap(scalar->d[i] & mask, x1, x2, group->field.top); + BN_consttime_swap(scalar->d[i] & mask, z1, z2, group->field.top); + if (!gf2m_Madd(group, &point->X, x2, z2, x1, z1, ctx)) goto err; + if (!gf2m_Mdouble(group, x1, z1, ctx)) goto err; + BN_consttime_swap(scalar->d[i] & mask, x1, x2, group->field.top); + BN_consttime_swap(scalar->d[i] & mask, z1, z2, group->field.top); mask >>= 1; } j = BN_BITS2 - 1; Modified: releng/8.3/sys/conf/newvers.sh ============================================================================== --- releng/8.3/sys/conf/newvers.sh Tue Apr 8 22:36:39 2014 (r264283) +++ releng/8.3/sys/conf/newvers.sh Tue Apr 8 23:16:05 2014 (r264284) @@ -32,7 +32,7 @@ TYPE="FreeBSD" REVISION="8.3" -BRANCH="RELEASE-p14" +BRANCH="RELEASE-p15" if [ "X${BRANCH_OVERRIDE}" != "X" ]; then BRANCH=${BRANCH_OVERRIDE} fi Modified: releng/8.3/sys/fs/nfsserver/nfs_nfsdserv.c ============================================================================== --- releng/8.3/sys/fs/nfsserver/nfs_nfsdserv.c Tue Apr 8 22:36:39 2014 (r264283) +++ releng/8.3/sys/fs/nfsserver/nfs_nfsdserv.c Tue Apr 8 23:16:05 2014 (r264284) @@ -1446,10 +1446,23 @@ nfsrvd_rename(struct nfsrv_descript *nd, nfsvno_relpathbuf(&fromnd); goto out; } + /* + * Unlock dp in this code section, so it is unlocked before + * tdp gets locked. This avoids a potential LOR if tdp is the + * parent directory of dp. + */ if (nd->nd_flag & ND_NFSV4) { tdp = todp; tnes = *toexp; - tdirfor_ret = nfsvno_getattr(tdp, &tdirfor, nd->nd_cred, p, 0); + if (dp != tdp) { + NFSVOPUNLOCK(dp, 0); + tdirfor_ret = nfsvno_getattr(tdp, &tdirfor, nd->nd_cred, + p, 0); /* Might lock tdp. */ + } else { + tdirfor_ret = nfsvno_getattr(tdp, &tdirfor, nd->nd_cred, + p, 1); + NFSVOPUNLOCK(dp, 0); + } } else { tfh.nfsrvfh_len = 0; error = nfsrv_mtofh(nd, &tfh); @@ -1470,10 +1483,12 @@ nfsrvd_rename(struct nfsrv_descript *nd, tnes = *exp; tdirfor_ret = nfsvno_getattr(tdp, &tdirfor, nd->nd_cred, p, 1); + NFSVOPUNLOCK(dp, 0); } else { + NFSVOPUNLOCK(dp, 0); nd->nd_cred->cr_uid = nd->nd_saveduid; nfsd_fhtovp(nd, &tfh, LK_EXCLUSIVE, &tdp, &tnes, NULL, - 0, p); + 0, p); /* Locks tdp. */ if (tdp) { tdirfor_ret = nfsvno_getattr(tdp, &tdirfor, nd->nd_cred, p, 1); @@ -1488,7 +1503,7 @@ nfsrvd_rename(struct nfsrv_descript *nd, if (error) { if (tdp) vrele(tdp); - vput(dp); + vrele(dp); nfsvno_relpathbuf(&fromnd); nfsvno_relpathbuf(&tond); goto out; @@ -1503,7 +1518,7 @@ nfsrvd_rename(struct nfsrv_descript *nd, } if (tdp) vrele(tdp); - vput(dp); + vrele(dp); nfsvno_relpathbuf(&fromnd); nfsvno_relpathbuf(&tond); goto out; @@ -1512,7 +1527,7 @@ nfsrvd_rename(struct nfsrv_descript *nd, /* * Done parsing, now down to business. */ - nd->nd_repstat = nfsvno_namei(nd, &fromnd, dp, 1, exp, p, &fdirp); + nd->nd_repstat = nfsvno_namei(nd, &fromnd, dp, 0, exp, p, &fdirp); if (nd->nd_repstat) { if (nd->nd_flag & ND_NFSV3) { nfsrv_wcc(nd, fdirfor_ret, &fdirfor, fdiraft_ret, Modified: releng/8.4/UPDATING ============================================================================== --- releng/8.4/UPDATING Tue Apr 8 22:36:39 2014 (r264283) +++ releng/8.4/UPDATING Tue Apr 8 23:16:05 2014 (r264284) @@ -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. +20140408: p8 FreeBSD-SA-14:05.nfsserver + FreeBSD-SA-14:06.openssl + Fix deadlock in the NFS server. [SA-14:05] + + Fix for ECDSA Cache Side-channel Attack in OpenSSL. [SA-14:06] + 20140114: p7 FreeBSD-SA-14:01.bsnmpd FreeBSD-SA-14:02.ntpd FreeBSD-SA-14:04.bind Modified: releng/8.4/crypto/openssl/crypto/bn/bn.h ============================================================================== --- releng/8.4/crypto/openssl/crypto/bn/bn.h Tue Apr 8 22:36:39 2014 (r264283) +++ releng/8.4/crypto/openssl/crypto/bn/bn.h Tue Apr 8 23:16:05 2014 (r264284) @@ -511,6 +511,8 @@ BIGNUM *BN_mod_inverse(BIGNUM *ret, BIGNUM *BN_mod_sqrt(BIGNUM *ret, const BIGNUM *a, const BIGNUM *n,BN_CTX *ctx); +void BN_consttime_swap(BN_ULONG swap, BIGNUM *a, BIGNUM *b, int nwords); + /* Deprecated versions */ #ifndef OPENSSL_NO_DEPRECATED BIGNUM *BN_generate_prime(BIGNUM *ret,int bits,int safe, @@ -740,11 +742,20 @@ int RAND_pseudo_bytes(unsigned char *buf #define bn_fix_top(a) bn_check_top(a) +#define bn_check_size(bn, bits) bn_wcheck_size(bn, ((bits+BN_BITS2-1))/BN_BITS2) +#define bn_wcheck_size(bn, words) \ + do { \ + const BIGNUM *_bnum2 = (bn); \ + assert(words <= (_bnum2)->dmax && words >= (_bnum2)->top); \ + } while(0) + #else /* !BN_DEBUG */ #define bn_pollute(a) #define bn_check_top(a) #define bn_fix_top(a) bn_correct_top(a) +#define bn_check_size(bn, bits) +#define bn_wcheck_size(bn, words) #endif Modified: releng/8.4/crypto/openssl/crypto/bn/bn_lib.c ============================================================================== --- releng/8.4/crypto/openssl/crypto/bn/bn_lib.c Tue Apr 8 22:36:39 2014 (r264283) +++ releng/8.4/crypto/openssl/crypto/bn/bn_lib.c Tue Apr 8 23:16:05 2014 (r264284) @@ -824,3 +824,55 @@ int bn_cmp_part_words(const BN_ULONG *a, } return bn_cmp_words(a,b,cl); } + +/* + * Constant-time conditional swap of a and b. + * a and b are swapped if condition is not 0. The code assumes that at most one bit of condition is set. + * nwords is the number of words to swap. The code assumes that at least nwords are allocated in both a and b, + * and that no more than nwords are used by either a or b. + * a and b cannot be the same number + */ +void BN_consttime_swap(BN_ULONG condition, BIGNUM *a, BIGNUM *b, int nwords) + { + BN_ULONG t; + int i; + + bn_wcheck_size(a, nwords); + bn_wcheck_size(b, nwords); + + assert(a != b); + assert((condition & (condition - 1)) == 0); + assert(sizeof(BN_ULONG) >= sizeof(int)); + + condition = ((condition - 1) >> (BN_BITS2 - 1)) - 1; + + t = (a->top^b->top) & condition; + a->top ^= t; + b->top ^= t; + +#define BN_CONSTTIME_SWAP(ind) \ + do { \ + t = (a->d[ind] ^ b->d[ind]) & condition; \ + a->d[ind] ^= t; \ + b->d[ind] ^= t; \ + } while (0) + + + switch (nwords) { + default: + for (i = 10; i < nwords; i++) + BN_CONSTTIME_SWAP(i); + /* Fallthrough */ + case 10: BN_CONSTTIME_SWAP(9); /* Fallthrough */ + case 9: BN_CONSTTIME_SWAP(8); /* Fallthrough */ + case 8: BN_CONSTTIME_SWAP(7); /* Fallthrough */ + case 7: BN_CONSTTIME_SWAP(6); /* Fallthrough */ + case 6: BN_CONSTTIME_SWAP(5); /* Fallthrough */ + case 5: BN_CONSTTIME_SWAP(4); /* Fallthrough */ + case 4: BN_CONSTTIME_SWAP(3); /* Fallthrough */ + case 3: BN_CONSTTIME_SWAP(2); /* Fallthrough */ + case 2: BN_CONSTTIME_SWAP(1); /* Fallthrough */ + case 1: BN_CONSTTIME_SWAP(0); + } +#undef BN_CONSTTIME_SWAP +} Modified: releng/8.4/crypto/openssl/crypto/ec/ec2_mult.c ============================================================================== --- releng/8.4/crypto/openssl/crypto/ec/ec2_mult.c Tue Apr 8 22:36:39 2014 (r264283) +++ releng/8.4/crypto/openssl/crypto/ec/ec2_mult.c Tue Apr 8 23:16:05 2014 (r264284) @@ -208,9 +208,12 @@ static int gf2m_Mxy(const EC_GROUP *grou /* Computes scalar*point and stores the result in r. * point can not equal r. - * Uses algorithm 2P of + * Uses a modified algorithm 2P of * Lopex, J. and Dahab, R. "Fast multiplication on elliptic curves over * GF(2^m) without precomputation". + * + * To protect against side-channel attack the function uses constant time + * swap avoiding conditional branches. */ static int ec_GF2m_montgomery_point_multiply(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar, const EC_POINT *point, BN_CTX *ctx) @@ -244,6 +247,11 @@ static int ec_GF2m_montgomery_point_mult x2 = &r->X; z2 = &r->Y; + bn_wexpand(x1, group->field.top); + bn_wexpand(z1, group->field.top); + bn_wexpand(x2, group->field.top); + bn_wexpand(z2, group->field.top); + if (!BN_GF2m_mod_arr(x1, &point->X, group->poly)) goto err; /* x1 = x */ if (!BN_one(z1)) goto err; /* z1 = 1 */ if (!group->meth->field_sqr(group, z2, x1, ctx)) goto err; /* z2 = x1^2 = x^2 */ @@ -266,16 +274,12 @@ static int ec_GF2m_montgomery_point_mult { for (; j >= 0; j--) { - if (scalar->d[i] & mask) - { - if (!gf2m_Madd(group, &point->X, x1, z1, x2, z2, ctx)) goto err; - if (!gf2m_Mdouble(group, x2, z2, ctx)) goto err; - } - else - { - if (!gf2m_Madd(group, &point->X, x2, z2, x1, z1, ctx)) goto err; - if (!gf2m_Mdouble(group, x1, z1, ctx)) goto err; - } + BN_consttime_swap(scalar->d[i] & mask, x1, x2, group->field.top); + BN_consttime_swap(scalar->d[i] & mask, z1, z2, group->field.top); + if (!gf2m_Madd(group, &point->X, x2, z2, x1, z1, ctx)) goto err; + if (!gf2m_Mdouble(group, x1, z1, ctx)) goto err; + BN_consttime_swap(scalar->d[i] & mask, x1, x2, group->field.top); + BN_consttime_swap(scalar->d[i] & mask, z1, z2, group->field.top); mask >>= 1; } j = BN_BITS2 - 1; Modified: releng/8.4/sys/conf/newvers.sh ============================================================================== --- releng/8.4/sys/conf/newvers.sh Tue Apr 8 22:36:39 2014 (r264283) +++ releng/8.4/sys/conf/newvers.sh Tue Apr 8 23:16:05 2014 (r264284) @@ -32,7 +32,7 @@ TYPE="FreeBSD" REVISION="8.4" -BRANCH="RELEASE-p7" +BRANCH="RELEASE-p8" if [ "X${BRANCH_OVERRIDE}" != "X" ]; then BRANCH=${BRANCH_OVERRIDE} fi Modified: releng/8.4/sys/fs/nfsserver/nfs_nfsdserv.c ============================================================================== --- releng/8.4/sys/fs/nfsserver/nfs_nfsdserv.c Tue Apr 8 22:36:39 2014 (r264283) +++ releng/8.4/sys/fs/nfsserver/nfs_nfsdserv.c Tue Apr 8 23:16:05 2014 (r264284) @@ -1446,10 +1446,23 @@ nfsrvd_rename(struct nfsrv_descript *nd, nfsvno_relpathbuf(&fromnd); goto out; } + /* + * Unlock dp in this code section, so it is unlocked before + * tdp gets locked. This avoids a potential LOR if tdp is the + * parent directory of dp. + */ if (nd->nd_flag & ND_NFSV4) { tdp = todp; tnes = *toexp; - tdirfor_ret = nfsvno_getattr(tdp, &tdirfor, nd->nd_cred, p, 0); + if (dp != tdp) { + NFSVOPUNLOCK(dp, 0); + tdirfor_ret = nfsvno_getattr(tdp, &tdirfor, nd->nd_cred, + p, 0); /* Might lock tdp. */ + } else { + tdirfor_ret = nfsvno_getattr(tdp, &tdirfor, nd->nd_cred, + p, 1); + NFSVOPUNLOCK(dp, 0); + } } else { tfh.nfsrvfh_len = 0; error = nfsrv_mtofh(nd, &tfh); @@ -1470,10 +1483,12 @@ nfsrvd_rename(struct nfsrv_descript *nd, tnes = *exp; tdirfor_ret = nfsvno_getattr(tdp, &tdirfor, nd->nd_cred, p, 1); + NFSVOPUNLOCK(dp, 0); } else { + NFSVOPUNLOCK(dp, 0); nd->nd_cred->cr_uid = nd->nd_saveduid; nfsd_fhtovp(nd, &tfh, LK_EXCLUSIVE, &tdp, &tnes, NULL, - 0, p); + 0, p); /* Locks tdp. */ if (tdp) { tdirfor_ret = nfsvno_getattr(tdp, &tdirfor, nd->nd_cred, p, 1); @@ -1488,7 +1503,7 @@ nfsrvd_rename(struct nfsrv_descript *nd, if (error) { if (tdp) vrele(tdp); - vput(dp); + vrele(dp); nfsvno_relpathbuf(&fromnd); nfsvno_relpathbuf(&tond); goto out; @@ -1503,7 +1518,7 @@ nfsrvd_rename(struct nfsrv_descript *nd, } if (tdp) vrele(tdp); - vput(dp); + vrele(dp); nfsvno_relpathbuf(&fromnd); nfsvno_relpathbuf(&tond); goto out; @@ -1512,7 +1527,7 @@ nfsrvd_rename(struct nfsrv_descript *nd, /* * Done parsing, now down to business. */ - nd->nd_repstat = nfsvno_namei(nd, &fromnd, dp, 1, exp, p, &fdirp); + nd->nd_repstat = nfsvno_namei(nd, &fromnd, dp, 0, exp, p, &fdirp); if (nd->nd_repstat) { if (nd->nd_flag & ND_NFSV3) { nfsrv_wcc(nd, fdirfor_ret, &fdirfor, fdiraft_ret, Modified: releng/9.1/UPDATING ============================================================================== --- releng/9.1/UPDATING Tue Apr 8 22:36:39 2014 (r264283) +++ releng/9.1/UPDATING Tue Apr 8 23:16:05 2014 (r264284) @@ -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. +20140408: p11 FreeBSD-SA-14:05.nfsserver + FreeBSD-SA-14:06.openssl + Fix deadlock in the NFS server. [SA-14:05] + + Fix for ECDSA Cache Side-channel Attack in OpenSSL. [SA-14:06] + 20140114: p10 FreeBSD-SA-14:01.bsnmpd FreeBSD-SA-14:02.ntpd FreeBSD-SA-14:04.bind Modified: releng/9.1/crypto/openssl/crypto/bn/bn.h ============================================================================== --- releng/9.1/crypto/openssl/crypto/bn/bn.h Tue Apr 8 22:36:39 2014 (r264283) +++ releng/9.1/crypto/openssl/crypto/bn/bn.h Tue Apr 8 23:16:05 2014 (r264284) @@ -511,6 +511,8 @@ BIGNUM *BN_mod_inverse(BIGNUM *ret, BIGNUM *BN_mod_sqrt(BIGNUM *ret, const BIGNUM *a, const BIGNUM *n,BN_CTX *ctx); +void BN_consttime_swap(BN_ULONG swap, BIGNUM *a, BIGNUM *b, int nwords); + /* Deprecated versions */ #ifndef OPENSSL_NO_DEPRECATED BIGNUM *BN_generate_prime(BIGNUM *ret,int bits,int safe, @@ -740,11 +742,20 @@ int RAND_pseudo_bytes(unsigned char *buf #define bn_fix_top(a) bn_check_top(a) +#define bn_check_size(bn, bits) bn_wcheck_size(bn, ((bits+BN_BITS2-1))/BN_BITS2) +#define bn_wcheck_size(bn, words) \ + do { \ + const BIGNUM *_bnum2 = (bn); \ + assert(words <= (_bnum2)->dmax && words >= (_bnum2)->top); \ + } while(0) + #else /* !BN_DEBUG */ #define bn_pollute(a) #define bn_check_top(a) #define bn_fix_top(a) bn_correct_top(a) +#define bn_check_size(bn, bits) +#define bn_wcheck_size(bn, words) #endif Modified: releng/9.1/crypto/openssl/crypto/bn/bn_lib.c ============================================================================== --- releng/9.1/crypto/openssl/crypto/bn/bn_lib.c Tue Apr 8 22:36:39 2014 (r264283) +++ releng/9.1/crypto/openssl/crypto/bn/bn_lib.c Tue Apr 8 23:16:05 2014 (r264284) @@ -824,3 +824,55 @@ int bn_cmp_part_words(const BN_ULONG *a, } return bn_cmp_words(a,b,cl); } + +/* + * Constant-time conditional swap of a and b. + * a and b are swapped if condition is not 0. The code assumes that at most one bit of condition is set. + * nwords is the number of words to swap. The code assumes that at least nwords are allocated in both a and b, + * and that no more than nwords are used by either a or b. + * a and b cannot be the same number + */ +void BN_consttime_swap(BN_ULONG condition, BIGNUM *a, BIGNUM *b, int nwords) + { + BN_ULONG t; + int i; + + bn_wcheck_size(a, nwords); + bn_wcheck_size(b, nwords); + + assert(a != b); + assert((condition & (condition - 1)) == 0); + assert(sizeof(BN_ULONG) >= sizeof(int)); + + condition = ((condition - 1) >> (BN_BITS2 - 1)) - 1; + + t = (a->top^b->top) & condition; + a->top ^= t; + b->top ^= t; + +#define BN_CONSTTIME_SWAP(ind) \ + do { \ + t = (a->d[ind] ^ b->d[ind]) & condition; \ + a->d[ind] ^= t; \ + b->d[ind] ^= t; \ + } while (0) + + + switch (nwords) { + default: + for (i = 10; i < nwords; i++) + BN_CONSTTIME_SWAP(i); + /* Fallthrough */ + case 10: BN_CONSTTIME_SWAP(9); /* Fallthrough */ + case 9: BN_CONSTTIME_SWAP(8); /* Fallthrough */ + case 8: BN_CONSTTIME_SWAP(7); /* Fallthrough */ + case 7: BN_CONSTTIME_SWAP(6); /* Fallthrough */ + case 6: BN_CONSTTIME_SWAP(5); /* Fallthrough */ + case 5: BN_CONSTTIME_SWAP(4); /* Fallthrough */ + case 4: BN_CONSTTIME_SWAP(3); /* Fallthrough */ + case 3: BN_CONSTTIME_SWAP(2); /* Fallthrough */ + case 2: BN_CONSTTIME_SWAP(1); /* Fallthrough */ + case 1: BN_CONSTTIME_SWAP(0); + } +#undef BN_CONSTTIME_SWAP +} Modified: releng/9.1/crypto/openssl/crypto/ec/ec2_mult.c ============================================================================== --- releng/9.1/crypto/openssl/crypto/ec/ec2_mult.c Tue Apr 8 22:36:39 2014 (r264283) +++ releng/9.1/crypto/openssl/crypto/ec/ec2_mult.c Tue Apr 8 23:16:05 2014 (r264284) @@ -208,9 +208,12 @@ static int gf2m_Mxy(const EC_GROUP *grou /* Computes scalar*point and stores the result in r. * point can not equal r. - * Uses algorithm 2P of + * Uses a modified algorithm 2P of * Lopex, J. and Dahab, R. "Fast multiplication on elliptic curves over * GF(2^m) without precomputation". + * + * To protect against side-channel attack the function uses constant time + * swap avoiding conditional branches. */ static int ec_GF2m_montgomery_point_multiply(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar, const EC_POINT *point, BN_CTX *ctx) @@ -244,6 +247,11 @@ static int ec_GF2m_montgomery_point_mult x2 = &r->X; z2 = &r->Y; + bn_wexpand(x1, group->field.top); + bn_wexpand(z1, group->field.top); + bn_wexpand(x2, group->field.top); + bn_wexpand(z2, group->field.top); + if (!BN_GF2m_mod_arr(x1, &point->X, group->poly)) goto err; /* x1 = x */ if (!BN_one(z1)) goto err; /* z1 = 1 */ if (!group->meth->field_sqr(group, z2, x1, ctx)) goto err; /* z2 = x1^2 = x^2 */ @@ -266,16 +274,12 @@ static int ec_GF2m_montgomery_point_mult { for (; j >= 0; j--) { - if (scalar->d[i] & mask) - { - if (!gf2m_Madd(group, &point->X, x1, z1, x2, z2, ctx)) goto err; - if (!gf2m_Mdouble(group, x2, z2, ctx)) goto err; - } - else - { - if (!gf2m_Madd(group, &point->X, x2, z2, x1, z1, ctx)) goto err; - if (!gf2m_Mdouble(group, x1, z1, ctx)) goto err; - } + BN_consttime_swap(scalar->d[i] & mask, x1, x2, group->field.top); + BN_consttime_swap(scalar->d[i] & mask, z1, z2, group->field.top); + if (!gf2m_Madd(group, &point->X, x2, z2, x1, z1, ctx)) goto err; + if (!gf2m_Mdouble(group, x1, z1, ctx)) goto err; + BN_consttime_swap(scalar->d[i] & mask, x1, x2, group->field.top); + BN_consttime_swap(scalar->d[i] & mask, z1, z2, group->field.top); mask >>= 1; } j = BN_BITS2 - 1; Modified: releng/9.1/sys/conf/newvers.sh ============================================================================== --- releng/9.1/sys/conf/newvers.sh Tue Apr 8 22:36:39 2014 (r264283) +++ releng/9.1/sys/conf/newvers.sh Tue Apr 8 23:16:05 2014 (r264284) @@ -32,7 +32,7 @@ TYPE="FreeBSD" REVISION="9.1" -BRANCH="RELEASE-p10" +BRANCH="RELEASE-p11" if [ "X${BRANCH_OVERRIDE}" != "X" ]; then BRANCH=${BRANCH_OVERRIDE} fi Modified: releng/9.1/sys/fs/nfsserver/nfs_nfsdserv.c ============================================================================== --- releng/9.1/sys/fs/nfsserver/nfs_nfsdserv.c Tue Apr 8 22:36:39 2014 (r264283) +++ releng/9.1/sys/fs/nfsserver/nfs_nfsdserv.c Tue Apr 8 23:16:05 2014 (r264284) @@ -1446,10 +1446,23 @@ nfsrvd_rename(struct nfsrv_descript *nd, nfsvno_relpathbuf(&fromnd); goto out; } + /* + * Unlock dp in this code section, so it is unlocked before + * tdp gets locked. This avoids a potential LOR if tdp is the + * parent directory of dp. + */ if (nd->nd_flag & ND_NFSV4) { tdp = todp; tnes = *toexp; - tdirfor_ret = nfsvno_getattr(tdp, &tdirfor, nd->nd_cred, p, 0); + if (dp != tdp) { + NFSVOPUNLOCK(dp, 0); + tdirfor_ret = nfsvno_getattr(tdp, &tdirfor, nd->nd_cred, + p, 0); /* Might lock tdp. */ + } else { + tdirfor_ret = nfsvno_getattr(tdp, &tdirfor, nd->nd_cred, + p, 1); + NFSVOPUNLOCK(dp, 0); + } } else { tfh.nfsrvfh_len = 0; error = nfsrv_mtofh(nd, &tfh); @@ -1470,10 +1483,12 @@ nfsrvd_rename(struct nfsrv_descript *nd, tnes = *exp; tdirfor_ret = nfsvno_getattr(tdp, &tdirfor, nd->nd_cred, p, 1); + NFSVOPUNLOCK(dp, 0); } else { + NFSVOPUNLOCK(dp, 0); nd->nd_cred->cr_uid = nd->nd_saveduid; nfsd_fhtovp(nd, &tfh, LK_EXCLUSIVE, &tdp, &tnes, NULL, - 0, p); + 0, p); /* Locks tdp. */ if (tdp) { tdirfor_ret = nfsvno_getattr(tdp, &tdirfor, nd->nd_cred, p, 1); @@ -1488,7 +1503,7 @@ nfsrvd_rename(struct nfsrv_descript *nd, if (error) { if (tdp) vrele(tdp); - vput(dp); + vrele(dp); nfsvno_relpathbuf(&fromnd); nfsvno_relpathbuf(&tond); goto out; @@ -1503,7 +1518,7 @@ nfsrvd_rename(struct nfsrv_descript *nd, } if (tdp) vrele(tdp); - vput(dp); + vrele(dp); nfsvno_relpathbuf(&fromnd); nfsvno_relpathbuf(&tond); goto out; @@ -1512,7 +1527,7 @@ nfsrvd_rename(struct nfsrv_descript *nd, /* * Done parsing, now down to business. */ - nd->nd_repstat = nfsvno_namei(nd, &fromnd, dp, 1, exp, p, &fdirp); + nd->nd_repstat = nfsvno_namei(nd, &fromnd, dp, 0, exp, p, &fdirp); if (nd->nd_repstat) { if (nd->nd_flag & ND_NFSV3) { nfsrv_wcc(nd, fdirfor_ret, &fdirfor, fdiraft_ret, Modified: releng/9.2/UPDATING ============================================================================== --- releng/9.2/UPDATING Tue Apr 8 22:36:39 2014 (r264283) +++ releng/9.2/UPDATING Tue Apr 8 23:16:05 2014 (r264284) @@ -11,6 +11,12 @@ handbook: Items affecting the ports and packages system can be found in /usr/ports/UPDATING. Please read that file before running portupgrade. +20140408: p4 FreeBSD-SA-14:05.nfsserver + FreeBSD-SA-14:06.openssl + Fix deadlock in the NFS server. [SA-14:05] + + Fix for ECDSA Cache Side-channel Attack in OpenSSL. [SA-14:06] + 20140114: p3 FreeBSD-SA-14:01.bsnmpd FreeBSD-SA-14:02.ntpd FreeBSD-SA-14:04.bind Modified: releng/9.2/crypto/openssl/crypto/bn/bn.h ============================================================================== --- releng/9.2/crypto/openssl/crypto/bn/bn.h Tue Apr 8 22:36:39 2014 (r264283) +++ releng/9.2/crypto/openssl/crypto/bn/bn.h Tue Apr 8 23:16:05 2014 (r264284) @@ -511,6 +511,8 @@ BIGNUM *BN_mod_inverse(BIGNUM *ret, BIGNUM *BN_mod_sqrt(BIGNUM *ret, const BIGNUM *a, const BIGNUM *n,BN_CTX *ctx); +void BN_consttime_swap(BN_ULONG swap, BIGNUM *a, BIGNUM *b, int nwords); + /* Deprecated versions */ #ifndef OPENSSL_NO_DEPRECATED BIGNUM *BN_generate_prime(BIGNUM *ret,int bits,int safe, @@ -740,11 +742,20 @@ int RAND_pseudo_bytes(unsigned char *buf #define bn_fix_top(a) bn_check_top(a) +#define bn_check_size(bn, bits) bn_wcheck_size(bn, ((bits+BN_BITS2-1))/BN_BITS2) +#define bn_wcheck_size(bn, words) \ + do { \ + const BIGNUM *_bnum2 = (bn); \ + assert(words <= (_bnum2)->dmax && words >= (_bnum2)->top); \ + } while(0) + #else /* !BN_DEBUG */ #define bn_pollute(a) #define bn_check_top(a) #define bn_fix_top(a) bn_correct_top(a) +#define bn_check_size(bn, bits) +#define bn_wcheck_size(bn, words) #endif Modified: releng/9.2/crypto/openssl/crypto/bn/bn_lib.c ============================================================================== --- releng/9.2/crypto/openssl/crypto/bn/bn_lib.c Tue Apr 8 22:36:39 2014 (r264283) +++ releng/9.2/crypto/openssl/crypto/bn/bn_lib.c Tue Apr 8 23:16:05 2014 (r264284) @@ -824,3 +824,55 @@ int bn_cmp_part_words(const BN_ULONG *a, } return bn_cmp_words(a,b,cl); } + +/* + * Constant-time conditional swap of a and b. + * a and b are swapped if condition is not 0. The code assumes that at most one bit of condition is set. + * nwords is the number of words to swap. The code assumes that at least nwords are allocated in both a and b, + * and that no more than nwords are used by either a or b. + * a and b cannot be the same number + */ +void BN_consttime_swap(BN_ULONG condition, BIGNUM *a, BIGNUM *b, int nwords) + { + BN_ULONG t; + int i; + + bn_wcheck_size(a, nwords); + bn_wcheck_size(b, nwords); + + assert(a != b); + assert((condition & (condition - 1)) == 0); + assert(sizeof(BN_ULONG) >= sizeof(int)); + + condition = ((condition - 1) >> (BN_BITS2 - 1)) - 1; + + t = (a->top^b->top) & condition; + a->top ^= t; + b->top ^= t; + +#define BN_CONSTTIME_SWAP(ind) \ + do { \ + t = (a->d[ind] ^ b->d[ind]) & condition; \ + a->d[ind] ^= t; \ + b->d[ind] ^= t; \ + } while (0) + + + switch (nwords) { + default: + for (i = 10; i < nwords; i++) + BN_CONSTTIME_SWAP(i); + /* Fallthrough */ + case 10: BN_CONSTTIME_SWAP(9); /* Fallthrough */ + case 9: BN_CONSTTIME_SWAP(8); /* Fallthrough */ + case 8: BN_CONSTTIME_SWAP(7); /* Fallthrough */ + case 7: BN_CONSTTIME_SWAP(6); /* Fallthrough */ + case 6: BN_CONSTTIME_SWAP(5); /* Fallthrough */ + case 5: BN_CONSTTIME_SWAP(4); /* Fallthrough */ + case 4: BN_CONSTTIME_SWAP(3); /* Fallthrough */ + case 3: BN_CONSTTIME_SWAP(2); /* Fallthrough */ + case 2: BN_CONSTTIME_SWAP(1); /* Fallthrough */ + case 1: BN_CONSTTIME_SWAP(0); + } +#undef BN_CONSTTIME_SWAP +} Modified: releng/9.2/crypto/openssl/crypto/ec/ec2_mult.c ============================================================================== --- releng/9.2/crypto/openssl/crypto/ec/ec2_mult.c Tue Apr 8 22:36:39 2014 (r264283) +++ releng/9.2/crypto/openssl/crypto/ec/ec2_mult.c Tue Apr 8 23:16:05 2014 (r264284) @@ -208,9 +208,12 @@ static int gf2m_Mxy(const EC_GROUP *grou /* Computes scalar*point and stores the result in r. * point can not equal r. - * Uses algorithm 2P of + * Uses a modified algorithm 2P of * Lopex, J. and Dahab, R. "Fast multiplication on elliptic curves over * GF(2^m) without precomputation". + * + * To protect against side-channel attack the function uses constant time + * swap avoiding conditional branches. */ static int ec_GF2m_montgomery_point_multiply(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar, const EC_POINT *point, BN_CTX *ctx) @@ -244,6 +247,11 @@ static int ec_GF2m_montgomery_point_mult x2 = &r->X; z2 = &r->Y; + bn_wexpand(x1, group->field.top); + bn_wexpand(z1, group->field.top); + bn_wexpand(x2, group->field.top); + bn_wexpand(z2, group->field.top); + if (!BN_GF2m_mod_arr(x1, &point->X, group->poly)) goto err; /* x1 = x */ if (!BN_one(z1)) goto err; /* z1 = 1 */ if (!group->meth->field_sqr(group, z2, x1, ctx)) goto err; /* z2 = x1^2 = x^2 */ @@ -266,16 +274,12 @@ static int ec_GF2m_montgomery_point_mult { for (; j >= 0; j--) { - if (scalar->d[i] & mask) - { - if (!gf2m_Madd(group, &point->X, x1, z1, x2, z2, ctx)) goto err; - if (!gf2m_Mdouble(group, x2, z2, ctx)) goto err; - } - else - { - if (!gf2m_Madd(group, &point->X, x2, z2, x1, z1, ctx)) goto err; - if (!gf2m_Mdouble(group, x1, z1, ctx)) goto err; - } + BN_consttime_swap(scalar->d[i] & mask, x1, x2, group->field.top); + BN_consttime_swap(scalar->d[i] & mask, z1, z2, group->field.top); + if (!gf2m_Madd(group, &point->X, x2, z2, x1, z1, ctx)) goto err; + if (!gf2m_Mdouble(group, x1, z1, ctx)) goto err; + BN_consttime_swap(scalar->d[i] & mask, x1, x2, group->field.top); + BN_consttime_swap(scalar->d[i] & mask, z1, z2, group->field.top); mask >>= 1; } j = BN_BITS2 - 1; Modified: releng/9.2/sys/conf/newvers.sh ============================================================================== --- releng/9.2/sys/conf/newvers.sh Tue Apr 8 22:36:39 2014 (r264283) +++ releng/9.2/sys/conf/newvers.sh Tue Apr 8 23:16:05 2014 (r264284) @@ -32,7 +32,7 @@ TYPE="FreeBSD" REVISION="9.2" -BRANCH="RELEASE-p3" +BRANCH="RELEASE-p4" if [ "X${BRANCH_OVERRIDE}" != "X" ]; then BRANCH=${BRANCH_OVERRIDE} fi Modified: releng/9.2/sys/fs/nfsserver/nfs_nfsdserv.c ============================================================================== --- releng/9.2/sys/fs/nfsserver/nfs_nfsdserv.c Tue Apr 8 22:36:39 2014 (r264283) +++ releng/9.2/sys/fs/nfsserver/nfs_nfsdserv.c Tue Apr 8 23:16:05 2014 (r264284) @@ -1457,10 +1457,23 @@ nfsrvd_rename(struct nfsrv_descript *nd, nfsvno_relpathbuf(&fromnd); goto out; } + /* + * Unlock dp in this code section, so it is unlocked before + * tdp gets locked. This avoids a potential LOR if tdp is the + * parent directory of dp. + */ if (nd->nd_flag & ND_NFSV4) { tdp = todp; tnes = *toexp; - tdirfor_ret = nfsvno_getattr(tdp, &tdirfor, nd->nd_cred, p, 0); + if (dp != tdp) { + NFSVOPUNLOCK(dp, 0); + tdirfor_ret = nfsvno_getattr(tdp, &tdirfor, nd->nd_cred, + p, 0); /* Might lock tdp. */ + } else { + tdirfor_ret = nfsvno_getattr(tdp, &tdirfor, nd->nd_cred, + p, 1); + NFSVOPUNLOCK(dp, 0); + } } else { tfh.nfsrvfh_len = 0; error = nfsrv_mtofh(nd, &tfh); @@ -1481,10 +1494,12 @@ nfsrvd_rename(struct nfsrv_descript *nd, tnes = *exp; tdirfor_ret = nfsvno_getattr(tdp, &tdirfor, nd->nd_cred, p, 1); + NFSVOPUNLOCK(dp, 0); } else { + NFSVOPUNLOCK(dp, 0); nd->nd_cred->cr_uid = nd->nd_saveduid; nfsd_fhtovp(nd, &tfh, LK_EXCLUSIVE, &tdp, &tnes, NULL, - 0, p); + 0, p); /* Locks tdp. */ if (tdp) { tdirfor_ret = nfsvno_getattr(tdp, &tdirfor, nd->nd_cred, p, 1); @@ -1499,7 +1514,7 @@ nfsrvd_rename(struct nfsrv_descript *nd, if (error) { if (tdp) vrele(tdp); - vput(dp); + vrele(dp); nfsvno_relpathbuf(&fromnd); nfsvno_relpathbuf(&tond); goto out; @@ -1514,7 +1529,7 @@ nfsrvd_rename(struct nfsrv_descript *nd, } if (tdp) vrele(tdp); - vput(dp); + vrele(dp); nfsvno_relpathbuf(&fromnd); nfsvno_relpathbuf(&tond); goto out; @@ -1523,7 +1538,7 @@ nfsrvd_rename(struct nfsrv_descript *nd, /* * Done parsing, now down to business. */ - nd->nd_repstat = nfsvno_namei(nd, &fromnd, dp, 1, exp, p, &fdirp); + nd->nd_repstat = nfsvno_namei(nd, &fromnd, dp, 0, exp, p, &fdirp); if (nd->nd_repstat) { if (nd->nd_flag & ND_NFSV3) { nfsrv_wcc(nd, fdirfor_ret, &fdirfor, fdiraft_ret, From delphij at FreeBSD.org Wed Apr 30 04:04:43 2014 From: delphij at FreeBSD.org (Xin LI) Date: Wed, 30 Apr 2014 04:04:42 +0000 (UTC) Subject: svn commit: r265124 - in releng/10.0: . crypto/openssl/ssl etc/defaults sys/conf sys/netinet Message-ID: <201404300404.s3U44gdH014256@svn.freebsd.org> Author: delphij Date: Wed Apr 30 04:04:42 2014 New Revision: 265124 URL: http://svnweb.freebsd.org/changeset/base/265124 Log: Fix devfs rules not applied by default for jails. Fix OpenSSL use-after-free vulnerability. Fix TCP reassembly vulnerability. Security: FreeBSD-SA-14:07.devfs Security: CVE-2014-3001 Security: FreeBSD-SA-14:08.tcp Security: CVE-2014-3000 Security: FreeBSD-SA-14:09.openssl Security: CVE-2010-5298 Approved by: so Modified: releng/10.0/UPDATING releng/10.0/crypto/openssl/ssl/s3_pkt.c releng/10.0/etc/defaults/rc.conf releng/10.0/sys/conf/newvers.sh releng/10.0/sys/netinet/tcp_reass.c Modified: releng/10.0/UPDATING ============================================================================== --- releng/10.0/UPDATING Wed Apr 30 04:04:20 2014 (r265123) +++ releng/10.0/UPDATING Wed Apr 30 04:04:42 2014 (r265124) @@ -16,6 +16,16 @@ from older versions of FreeBSD, try WITH stable/10, and then rebuild without this option. The bootstrap process from older version of current is a bit fragile. +20140430: p2 FreeBSD-SA-14:07.devfs + FreeBSD-SA-14:08.tcp + FreeBSD-SA-14:09.openssl + + Fix devfs rules not applied by default for jails. [SA-14:07] + + Fix TCP reassembly vulnerability. [SA-14:08] + + Fix OpenSSL use-after-free vulnerability. [SA-14:09] + 20140408: p1 FreeBSD-SA-14:05.nfsserver FreeBSD-SA-14:06.openssl Fix deadlock in the NFS server. [SA-14:05] Modified: releng/10.0/crypto/openssl/ssl/s3_pkt.c ============================================================================== --- releng/10.0/crypto/openssl/ssl/s3_pkt.c Wed Apr 30 04:04:20 2014 (r265123) +++ releng/10.0/crypto/openssl/ssl/s3_pkt.c Wed Apr 30 04:04:42 2014 (r265124) @@ -1055,7 +1055,7 @@ start: { s->rstate=SSL_ST_READ_HEADER; rr->off=0; - if (s->mode & SSL_MODE_RELEASE_BUFFERS) + if (s->mode & SSL_MODE_RELEASE_BUFFERS && s->s3->rbuf.left == 0) ssl3_release_read_buffer(s); } } Modified: releng/10.0/etc/defaults/rc.conf ============================================================================== --- releng/10.0/etc/defaults/rc.conf Wed Apr 30 04:04:20 2014 (r265123) +++ releng/10.0/etc/defaults/rc.conf Wed Apr 30 04:04:42 2014 (r265124) @@ -649,7 +649,7 @@ devfs_rulesets="/etc/defaults/devfs.rule devfs_system_ruleset="" # The name (NOT number) of a ruleset to apply to /dev devfs_set_rulesets="" # A list of /mount/dev=ruleset_name settings to # apply (must be mounted already, i.e. fstab(5)) -devfs_load_rulesets="NO" # Enable to always load the default rulesets +devfs_load_rulesets="YES" # Enable to always load the default rulesets performance_cx_lowest="HIGH" # Online CPU idle state performance_cpu_freq="NONE" # Online CPU frequency economy_cx_lowest="HIGH" # Offline CPU idle state Modified: releng/10.0/sys/conf/newvers.sh ============================================================================== --- releng/10.0/sys/conf/newvers.sh Wed Apr 30 04:04:20 2014 (r265123) +++ releng/10.0/sys/conf/newvers.sh Wed Apr 30 04:04:42 2014 (r265124) @@ -32,7 +32,7 @@ TYPE="FreeBSD" REVISION="10.0" -BRANCH="RELEASE-p1" +BRANCH="RELEASE-p2" if [ "X${BRANCH_OVERRIDE}" != "X" ]; then BRANCH=${BRANCH_OVERRIDE} fi Modified: releng/10.0/sys/netinet/tcp_reass.c ============================================================================== --- releng/10.0/sys/netinet/tcp_reass.c Wed Apr 30 04:04:20 2014 (r265123) +++ releng/10.0/sys/netinet/tcp_reass.c Wed Apr 30 04:04:42 2014 (r265124) @@ -205,7 +205,7 @@ tcp_reass(struct tcpcb *tp, struct tcphd * Investigate why and re-evaluate the below limit after the behaviour * is understood. */ - if (th->th_seq != tp->rcv_nxt && + if ((th->th_seq != tp->rcv_nxt || !TCPS_HAVEESTABLISHED(tp->t_state)) && tp->t_segqlen >= (so->so_rcv.sb_hiwat / tp->t_maxseg) + 1) { V_tcp_reass_overflows++; TCPSTAT_INC(tcps_rcvmemdrop); @@ -228,7 +228,7 @@ tcp_reass(struct tcpcb *tp, struct tcphd */ te = uma_zalloc(V_tcp_reass_zone, M_NOWAIT); if (te == NULL) { - if (th->th_seq != tp->rcv_nxt) { + if (th->th_seq != tp->rcv_nxt || !TCPS_HAVEESTABLISHED(tp->t_state)) { TCPSTAT_INC(tcps_rcvmemdrop); m_freem(m); *tlenp = 0; @@ -276,7 +276,8 @@ tcp_reass(struct tcpcb *tp, struct tcphd TCPSTAT_INC(tcps_rcvduppack); TCPSTAT_ADD(tcps_rcvdupbyte, *tlenp); m_freem(m); - uma_zfree(V_tcp_reass_zone, te); + if (te != &tqs) + uma_zfree(V_tcp_reass_zone, te); tp->t_segqlen--; /* * Try to present any queued data From delphij at FreeBSD.org Wed Apr 30 04:05:50 2014 From: delphij at FreeBSD.org (Xin LI) Date: Wed, 30 Apr 2014 04:05:48 +0000 (UTC) Subject: svn commit: r265125 - in releng: 8.3 8.3/sys/conf 8.3/sys/netinet 8.4 8.4/sys/conf 8.4/sys/netinet 9.1 9.1/sys/conf 9.1/sys/netinet 9.2 9.2/sys/conf 9.2/sys/netinet Message-ID: <201404300405.s3U45mtu014533@svn.freebsd.org> Author: delphij Date: Wed Apr 30 04:05:47 2014 New Revision: 265125 URL: http://svnweb.freebsd.org/changeset/base/265125 Log: Fix TCP reassembly vulnerability. Security: FreeBSD-SA-14:08.tcp Security: CVE-2014-3000 Approved by: so Modified: releng/8.3/UPDATING releng/8.3/sys/conf/newvers.sh releng/8.3/sys/netinet/tcp_reass.c releng/8.4/UPDATING releng/8.4/sys/conf/newvers.sh releng/8.4/sys/netinet/tcp_reass.c releng/9.1/UPDATING releng/9.1/sys/conf/newvers.sh releng/9.1/sys/netinet/tcp_reass.c releng/9.2/UPDATING releng/9.2/sys/conf/newvers.sh releng/9.2/sys/netinet/tcp_reass.c Modified: releng/8.3/UPDATING ============================================================================== --- releng/8.3/UPDATING Wed Apr 30 04:04:42 2014 (r265124) +++ releng/8.3/UPDATING Wed Apr 30 04:05:47 2014 (r265125) @@ -15,6 +15,10 @@ 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. +20140430: p16 FreeBSD-SA-14:08.tcp + + Fix TCP reassembly vulnerability. [SA-14:08] + 20140408: p15 FreeBSD-SA-14:05.nfsserver FreeBSD-SA-14:06.openssl Fix deadlock in the NFS server. [SA-14:05] Modified: releng/8.3/sys/conf/newvers.sh ============================================================================== --- releng/8.3/sys/conf/newvers.sh Wed Apr 30 04:04:42 2014 (r265124) +++ releng/8.3/sys/conf/newvers.sh Wed Apr 30 04:05:47 2014 (r265125) @@ -32,7 +32,7 @@ TYPE="FreeBSD" REVISION="8.3" -BRANCH="RELEASE-p15" +BRANCH="RELEASE-p16" if [ "X${BRANCH_OVERRIDE}" != "X" ]; then BRANCH=${BRANCH_OVERRIDE} fi Modified: releng/8.3/sys/netinet/tcp_reass.c ============================================================================== --- releng/8.3/sys/netinet/tcp_reass.c Wed Apr 30 04:04:42 2014 (r265124) +++ releng/8.3/sys/netinet/tcp_reass.c Wed Apr 30 04:05:47 2014 (r265125) @@ -211,7 +211,7 @@ tcp_reass(struct tcpcb *tp, struct tcphd * Investigate why and re-evaluate the below limit after the behaviour * is understood. */ - if (th->th_seq != tp->rcv_nxt && + if ((th->th_seq != tp->rcv_nxt || !TCPS_HAVEESTABLISHED(tp->t_state)) && tp->t_segqlen >= (so->so_rcv.sb_hiwat / tp->t_maxseg) + 1) { V_tcp_reass_overflows++; TCPSTAT_INC(tcps_rcvmemdrop); @@ -234,7 +234,7 @@ tcp_reass(struct tcpcb *tp, struct tcphd */ te = uma_zalloc(V_tcp_reass_zone, M_NOWAIT); if (te == NULL) { - if (th->th_seq != tp->rcv_nxt) { + if (th->th_seq != tp->rcv_nxt || !TCPS_HAVEESTABLISHED(tp->t_state)) { TCPSTAT_INC(tcps_rcvmemdrop); m_freem(m); *tlenp = 0; @@ -282,7 +282,8 @@ tcp_reass(struct tcpcb *tp, struct tcphd TCPSTAT_INC(tcps_rcvduppack); TCPSTAT_ADD(tcps_rcvdupbyte, *tlenp); m_freem(m); - uma_zfree(V_tcp_reass_zone, te); + if (te != &tqs) + uma_zfree(V_tcp_reass_zone, te); tp->t_segqlen--; /* * Try to present any queued data Modified: releng/8.4/UPDATING ============================================================================== --- releng/8.4/UPDATING Wed Apr 30 04:04:42 2014 (r265124) +++ releng/8.4/UPDATING Wed Apr 30 04:05:47 2014 (r265125) @@ -15,6 +15,10 @@ 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. +20140430: p9 FreeBSD-SA-14:08.tcp + + Fix TCP reassembly vulnerability. [SA-14:08] + 20140408: p8 FreeBSD-SA-14:05.nfsserver FreeBSD-SA-14:06.openssl Fix deadlock in the NFS server. [SA-14:05] Modified: releng/8.4/sys/conf/newvers.sh ============================================================================== --- releng/8.4/sys/conf/newvers.sh Wed Apr 30 04:04:42 2014 (r265124) +++ releng/8.4/sys/conf/newvers.sh Wed Apr 30 04:05:47 2014 (r265125) @@ -32,7 +32,7 @@ TYPE="FreeBSD" REVISION="8.4" -BRANCH="RELEASE-p8" +BRANCH="RELEASE-p9" if [ "X${BRANCH_OVERRIDE}" != "X" ]; then BRANCH=${BRANCH_OVERRIDE} fi Modified: releng/8.4/sys/netinet/tcp_reass.c ============================================================================== --- releng/8.4/sys/netinet/tcp_reass.c Wed Apr 30 04:04:42 2014 (r265124) +++ releng/8.4/sys/netinet/tcp_reass.c Wed Apr 30 04:05:47 2014 (r265125) @@ -211,7 +211,7 @@ tcp_reass(struct tcpcb *tp, struct tcphd * Investigate why and re-evaluate the below limit after the behaviour * is understood. */ - if (th->th_seq != tp->rcv_nxt && + if ((th->th_seq != tp->rcv_nxt || !TCPS_HAVEESTABLISHED(tp->t_state)) && tp->t_segqlen >= (so->so_rcv.sb_hiwat / tp->t_maxseg) + 1) { V_tcp_reass_overflows++; TCPSTAT_INC(tcps_rcvmemdrop); @@ -234,7 +234,7 @@ tcp_reass(struct tcpcb *tp, struct tcphd */ te = uma_zalloc(V_tcp_reass_zone, M_NOWAIT); if (te == NULL) { - if (th->th_seq != tp->rcv_nxt) { + if (th->th_seq != tp->rcv_nxt || !TCPS_HAVEESTABLISHED(tp->t_state)) { TCPSTAT_INC(tcps_rcvmemdrop); m_freem(m); *tlenp = 0; @@ -282,7 +282,8 @@ tcp_reass(struct tcpcb *tp, struct tcphd TCPSTAT_INC(tcps_rcvduppack); TCPSTAT_ADD(tcps_rcvdupbyte, *tlenp); m_freem(m); - uma_zfree(V_tcp_reass_zone, te); + if (te != &tqs) + uma_zfree(V_tcp_reass_zone, te); tp->t_segqlen--; /* * Try to present any queued data Modified: releng/9.1/UPDATING ============================================================================== --- releng/9.1/UPDATING Wed Apr 30 04:04:42 2014 (r265124) +++ releng/9.1/UPDATING Wed Apr 30 04:05:47 2014 (r265125) @@ -9,6 +9,10 @@ handbook. Items affecting the ports and packages system can be found in /usr/ports/UPDATING. Please read that file before running portupgrade. +20140430: p12 FreeBSD-SA-14:08.tcp + + Fix TCP reassembly vulnerability. [SA-14:08] + 20140408: p11 FreeBSD-SA-14:05.nfsserver FreeBSD-SA-14:06.openssl Fix deadlock in the NFS server. [SA-14:05] Modified: releng/9.1/sys/conf/newvers.sh ============================================================================== --- releng/9.1/sys/conf/newvers.sh Wed Apr 30 04:04:42 2014 (r265124) +++ releng/9.1/sys/conf/newvers.sh Wed Apr 30 04:05:47 2014 (r265125) @@ -32,7 +32,7 @@ TYPE="FreeBSD" REVISION="9.1" -BRANCH="RELEASE-p11" +BRANCH="RELEASE-p12" if [ "X${BRANCH_OVERRIDE}" != "X" ]; then BRANCH=${BRANCH_OVERRIDE} fi Modified: releng/9.1/sys/netinet/tcp_reass.c ============================================================================== --- releng/9.1/sys/netinet/tcp_reass.c Wed Apr 30 04:04:42 2014 (r265124) +++ releng/9.1/sys/netinet/tcp_reass.c Wed Apr 30 04:05:47 2014 (r265125) @@ -211,7 +211,7 @@ tcp_reass(struct tcpcb *tp, struct tcphd * Investigate why and re-evaluate the below limit after the behaviour * is understood. */ - if (th->th_seq != tp->rcv_nxt && + if ((th->th_seq != tp->rcv_nxt || !TCPS_HAVEESTABLISHED(tp->t_state)) && tp->t_segqlen >= (so->so_rcv.sb_hiwat / tp->t_maxseg) + 1) { V_tcp_reass_overflows++; TCPSTAT_INC(tcps_rcvmemdrop); @@ -234,7 +234,7 @@ tcp_reass(struct tcpcb *tp, struct tcphd */ te = uma_zalloc(V_tcp_reass_zone, M_NOWAIT); if (te == NULL) { - if (th->th_seq != tp->rcv_nxt) { + if (th->th_seq != tp->rcv_nxt || !TCPS_HAVEESTABLISHED(tp->t_state)) { TCPSTAT_INC(tcps_rcvmemdrop); m_freem(m); *tlenp = 0; @@ -282,7 +282,8 @@ tcp_reass(struct tcpcb *tp, struct tcphd TCPSTAT_INC(tcps_rcvduppack); TCPSTAT_ADD(tcps_rcvdupbyte, *tlenp); m_freem(m); - uma_zfree(V_tcp_reass_zone, te); + if (te != &tqs) + uma_zfree(V_tcp_reass_zone, te); tp->t_segqlen--; /* * Try to present any queued data Modified: releng/9.2/UPDATING ============================================================================== --- releng/9.2/UPDATING Wed Apr 30 04:04:42 2014 (r265124) +++ releng/9.2/UPDATING Wed Apr 30 04:05:47 2014 (r265125) @@ -11,6 +11,10 @@ handbook: Items affecting the ports and packages system can be found in /usr/ports/UPDATING. Please read that file before running portupgrade. +20140430: p5 FreeBSD-SA-14:08.tcp + + Fix TCP reassembly vulnerability. [SA-14:08] + 20140408: p4 FreeBSD-SA-14:05.nfsserver FreeBSD-SA-14:06.openssl Fix deadlock in the NFS server. [SA-14:05] Modified: releng/9.2/sys/conf/newvers.sh ============================================================================== --- releng/9.2/sys/conf/newvers.sh Wed Apr 30 04:04:42 2014 (r265124) +++ releng/9.2/sys/conf/newvers.sh Wed Apr 30 04:05:47 2014 (r265125) @@ -32,7 +32,7 @@ TYPE="FreeBSD" REVISION="9.2" -BRANCH="RELEASE-p4" +BRANCH="RELEASE-p5" if [ "X${BRANCH_OVERRIDE}" != "X" ]; then BRANCH=${BRANCH_OVERRIDE} fi Modified: releng/9.2/sys/netinet/tcp_reass.c ============================================================================== --- releng/9.2/sys/netinet/tcp_reass.c Wed Apr 30 04:04:42 2014 (r265124) +++ releng/9.2/sys/netinet/tcp_reass.c Wed Apr 30 04:05:47 2014 (r265125) @@ -205,7 +205,7 @@ tcp_reass(struct tcpcb *tp, struct tcphd * Investigate why and re-evaluate the below limit after the behaviour * is understood. */ - if (th->th_seq != tp->rcv_nxt && + if ((th->th_seq != tp->rcv_nxt || !TCPS_HAVEESTABLISHED(tp->t_state)) && tp->t_segqlen >= (so->so_rcv.sb_hiwat / tp->t_maxseg) + 1) { V_tcp_reass_overflows++; TCPSTAT_INC(tcps_rcvmemdrop); @@ -228,7 +228,7 @@ tcp_reass(struct tcpcb *tp, struct tcphd */ te = uma_zalloc(V_tcp_reass_zone, M_NOWAIT); if (te == NULL) { - if (th->th_seq != tp->rcv_nxt) { + if (th->th_seq != tp->rcv_nxt || !TCPS_HAVEESTABLISHED(tp->t_state)) { TCPSTAT_INC(tcps_rcvmemdrop); m_freem(m); *tlenp = 0; @@ -276,7 +276,8 @@ tcp_reass(struct tcpcb *tp, struct tcphd TCPSTAT_INC(tcps_rcvduppack); TCPSTAT_ADD(tcps_rcvdupbyte, *tlenp); m_freem(m); - uma_zfree(V_tcp_reass_zone, te); + if (te != &tqs) + uma_zfree(V_tcp_reass_zone, te); tp->t_segqlen--; /* * Try to present any queued data