Merge git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux
This commit is contained in:
@@ -45,6 +45,7 @@
|
||||
|
||||
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
|
||||
|
||||
#include <crypto/hash.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/ip.h>
|
||||
@@ -52,7 +53,6 @@
|
||||
#include <linux/net.h>
|
||||
#include <linux/inet.h>
|
||||
#include <linux/scatterlist.h>
|
||||
#include <linux/crypto.h>
|
||||
#include <linux/slab.h>
|
||||
#include <net/sock.h>
|
||||
|
||||
@@ -62,11 +62,13 @@
|
||||
#include <net/sctp/sm.h>
|
||||
|
||||
static struct sctp_chunk *sctp_make_control(const struct sctp_association *asoc,
|
||||
__u8 type, __u8 flags, int paylen);
|
||||
__u8 type, __u8 flags, int paylen,
|
||||
gfp_t gfp);
|
||||
static struct sctp_chunk *sctp_make_data(const struct sctp_association *asoc,
|
||||
__u8 flags, int paylen);
|
||||
__u8 flags, int paylen, gfp_t gfp);
|
||||
static struct sctp_chunk *_sctp_make_chunk(const struct sctp_association *asoc,
|
||||
__u8 type, __u8 flags, int paylen);
|
||||
__u8 type, __u8 flags, int paylen,
|
||||
gfp_t gfp);
|
||||
static sctp_cookie_param_t *sctp_pack_cookie(const struct sctp_endpoint *ep,
|
||||
const struct sctp_association *asoc,
|
||||
const struct sctp_chunk *init_chunk,
|
||||
@@ -318,7 +320,7 @@ struct sctp_chunk *sctp_make_init(const struct sctp_association *asoc,
|
||||
* PLEASE DO NOT FIXME [This version does not support Host Name.]
|
||||
*/
|
||||
|
||||
retval = sctp_make_control(asoc, SCTP_CID_INIT, 0, chunksize);
|
||||
retval = sctp_make_control(asoc, SCTP_CID_INIT, 0, chunksize, gfp);
|
||||
if (!retval)
|
||||
goto nodata;
|
||||
|
||||
@@ -465,7 +467,7 @@ struct sctp_chunk *sctp_make_init_ack(const struct sctp_association *asoc,
|
||||
num_ext);
|
||||
|
||||
/* Now allocate and fill out the chunk. */
|
||||
retval = sctp_make_control(asoc, SCTP_CID_INIT_ACK, 0, chunksize);
|
||||
retval = sctp_make_control(asoc, SCTP_CID_INIT_ACK, 0, chunksize, gfp);
|
||||
if (!retval)
|
||||
goto nomem_chunk;
|
||||
|
||||
@@ -570,7 +572,8 @@ struct sctp_chunk *sctp_make_cookie_echo(const struct sctp_association *asoc,
|
||||
cookie_len = asoc->peer.cookie_len;
|
||||
|
||||
/* Build a cookie echo chunk. */
|
||||
retval = sctp_make_control(asoc, SCTP_CID_COOKIE_ECHO, 0, cookie_len);
|
||||
retval = sctp_make_control(asoc, SCTP_CID_COOKIE_ECHO, 0,
|
||||
cookie_len, GFP_ATOMIC);
|
||||
if (!retval)
|
||||
goto nodata;
|
||||
retval->subh.cookie_hdr =
|
||||
@@ -615,7 +618,7 @@ struct sctp_chunk *sctp_make_cookie_ack(const struct sctp_association *asoc,
|
||||
{
|
||||
struct sctp_chunk *retval;
|
||||
|
||||
retval = sctp_make_control(asoc, SCTP_CID_COOKIE_ACK, 0, 0);
|
||||
retval = sctp_make_control(asoc, SCTP_CID_COOKIE_ACK, 0, 0, GFP_ATOMIC);
|
||||
|
||||
/* RFC 2960 6.4 Multi-homed SCTP Endpoints
|
||||
*
|
||||
@@ -664,7 +667,7 @@ struct sctp_chunk *sctp_make_cwr(const struct sctp_association *asoc,
|
||||
|
||||
cwr.lowest_tsn = htonl(lowest_tsn);
|
||||
retval = sctp_make_control(asoc, SCTP_CID_ECN_CWR, 0,
|
||||
sizeof(sctp_cwrhdr_t));
|
||||
sizeof(sctp_cwrhdr_t), GFP_ATOMIC);
|
||||
|
||||
if (!retval)
|
||||
goto nodata;
|
||||
@@ -698,7 +701,7 @@ struct sctp_chunk *sctp_make_ecne(const struct sctp_association *asoc,
|
||||
|
||||
ecne.lowest_tsn = htonl(lowest_tsn);
|
||||
retval = sctp_make_control(asoc, SCTP_CID_ECN_ECNE, 0,
|
||||
sizeof(sctp_ecnehdr_t));
|
||||
sizeof(sctp_ecnehdr_t), GFP_ATOMIC);
|
||||
if (!retval)
|
||||
goto nodata;
|
||||
retval->subh.ecne_hdr =
|
||||
@@ -713,7 +716,8 @@ nodata:
|
||||
*/
|
||||
struct sctp_chunk *sctp_make_datafrag_empty(struct sctp_association *asoc,
|
||||
const struct sctp_sndrcvinfo *sinfo,
|
||||
int data_len, __u8 flags, __u16 ssn)
|
||||
int data_len, __u8 flags, __u16 ssn,
|
||||
gfp_t gfp)
|
||||
{
|
||||
struct sctp_chunk *retval;
|
||||
struct sctp_datahdr dp;
|
||||
@@ -734,7 +738,7 @@ struct sctp_chunk *sctp_make_datafrag_empty(struct sctp_association *asoc,
|
||||
dp.ssn = htons(ssn);
|
||||
|
||||
chunk_len = sizeof(dp) + data_len;
|
||||
retval = sctp_make_data(asoc, flags, chunk_len);
|
||||
retval = sctp_make_data(asoc, flags, chunk_len, gfp);
|
||||
if (!retval)
|
||||
goto nodata;
|
||||
|
||||
@@ -781,7 +785,7 @@ struct sctp_chunk *sctp_make_sack(const struct sctp_association *asoc)
|
||||
+ sizeof(__u32) * num_dup_tsns;
|
||||
|
||||
/* Create the chunk. */
|
||||
retval = sctp_make_control(asoc, SCTP_CID_SACK, 0, len);
|
||||
retval = sctp_make_control(asoc, SCTP_CID_SACK, 0, len, GFP_ATOMIC);
|
||||
if (!retval)
|
||||
goto nodata;
|
||||
|
||||
@@ -861,7 +865,7 @@ struct sctp_chunk *sctp_make_shutdown(const struct sctp_association *asoc,
|
||||
shut.cum_tsn_ack = htonl(ctsn);
|
||||
|
||||
retval = sctp_make_control(asoc, SCTP_CID_SHUTDOWN, 0,
|
||||
sizeof(sctp_shutdownhdr_t));
|
||||
sizeof(sctp_shutdownhdr_t), GFP_ATOMIC);
|
||||
if (!retval)
|
||||
goto nodata;
|
||||
|
||||
@@ -879,7 +883,8 @@ struct sctp_chunk *sctp_make_shutdown_ack(const struct sctp_association *asoc,
|
||||
{
|
||||
struct sctp_chunk *retval;
|
||||
|
||||
retval = sctp_make_control(asoc, SCTP_CID_SHUTDOWN_ACK, 0, 0);
|
||||
retval = sctp_make_control(asoc, SCTP_CID_SHUTDOWN_ACK, 0, 0,
|
||||
GFP_ATOMIC);
|
||||
|
||||
/* RFC 2960 6.4 Multi-homed SCTP Endpoints
|
||||
*
|
||||
@@ -908,7 +913,8 @@ struct sctp_chunk *sctp_make_shutdown_complete(
|
||||
*/
|
||||
flags |= asoc ? 0 : SCTP_CHUNK_FLAG_T;
|
||||
|
||||
retval = sctp_make_control(asoc, SCTP_CID_SHUTDOWN_COMPLETE, flags, 0);
|
||||
retval = sctp_make_control(asoc, SCTP_CID_SHUTDOWN_COMPLETE, flags,
|
||||
0, GFP_ATOMIC);
|
||||
|
||||
/* RFC 2960 6.4 Multi-homed SCTP Endpoints
|
||||
*
|
||||
@@ -947,7 +953,8 @@ struct sctp_chunk *sctp_make_abort(const struct sctp_association *asoc,
|
||||
flags = SCTP_CHUNK_FLAG_T;
|
||||
}
|
||||
|
||||
retval = sctp_make_control(asoc, SCTP_CID_ABORT, flags, hint);
|
||||
retval = sctp_make_control(asoc, SCTP_CID_ABORT, flags, hint,
|
||||
GFP_ATOMIC);
|
||||
|
||||
/* RFC 2960 6.4 Multi-homed SCTP Endpoints
|
||||
*
|
||||
@@ -1139,7 +1146,8 @@ struct sctp_chunk *sctp_make_heartbeat(const struct sctp_association *asoc,
|
||||
struct sctp_chunk *retval;
|
||||
sctp_sender_hb_info_t hbinfo;
|
||||
|
||||
retval = sctp_make_control(asoc, SCTP_CID_HEARTBEAT, 0, sizeof(hbinfo));
|
||||
retval = sctp_make_control(asoc, SCTP_CID_HEARTBEAT, 0,
|
||||
sizeof(hbinfo), GFP_ATOMIC);
|
||||
|
||||
if (!retval)
|
||||
goto nodata;
|
||||
@@ -1167,7 +1175,8 @@ struct sctp_chunk *sctp_make_heartbeat_ack(const struct sctp_association *asoc,
|
||||
{
|
||||
struct sctp_chunk *retval;
|
||||
|
||||
retval = sctp_make_control(asoc, SCTP_CID_HEARTBEAT_ACK, 0, paylen);
|
||||
retval = sctp_make_control(asoc, SCTP_CID_HEARTBEAT_ACK, 0, paylen,
|
||||
GFP_ATOMIC);
|
||||
if (!retval)
|
||||
goto nodata;
|
||||
|
||||
@@ -1200,7 +1209,7 @@ static struct sctp_chunk *sctp_make_op_error_space(
|
||||
struct sctp_chunk *retval;
|
||||
|
||||
retval = sctp_make_control(asoc, SCTP_CID_ERROR, 0,
|
||||
sizeof(sctp_errhdr_t) + size);
|
||||
sizeof(sctp_errhdr_t) + size, GFP_ATOMIC);
|
||||
if (!retval)
|
||||
goto nodata;
|
||||
|
||||
@@ -1271,7 +1280,8 @@ struct sctp_chunk *sctp_make_auth(const struct sctp_association *asoc)
|
||||
return NULL;
|
||||
|
||||
retval = sctp_make_control(asoc, SCTP_CID_AUTH, 0,
|
||||
hmac_desc->hmac_len + sizeof(sctp_authhdr_t));
|
||||
hmac_desc->hmac_len + sizeof(sctp_authhdr_t),
|
||||
GFP_ATOMIC);
|
||||
if (!retval)
|
||||
return NULL;
|
||||
|
||||
@@ -1309,11 +1319,11 @@ struct sctp_chunk *sctp_make_auth(const struct sctp_association *asoc)
|
||||
*/
|
||||
struct sctp_chunk *sctp_chunkify(struct sk_buff *skb,
|
||||
const struct sctp_association *asoc,
|
||||
struct sock *sk)
|
||||
struct sock *sk, gfp_t gfp)
|
||||
{
|
||||
struct sctp_chunk *retval;
|
||||
|
||||
retval = kmem_cache_zalloc(sctp_chunk_cachep, GFP_ATOMIC);
|
||||
retval = kmem_cache_zalloc(sctp_chunk_cachep, gfp);
|
||||
|
||||
if (!retval)
|
||||
goto nodata;
|
||||
@@ -1361,7 +1371,8 @@ const union sctp_addr *sctp_source(const struct sctp_chunk *chunk)
|
||||
* arguments, reserving enough space for a 'paylen' byte payload.
|
||||
*/
|
||||
static struct sctp_chunk *_sctp_make_chunk(const struct sctp_association *asoc,
|
||||
__u8 type, __u8 flags, int paylen)
|
||||
__u8 type, __u8 flags, int paylen,
|
||||
gfp_t gfp)
|
||||
{
|
||||
struct sctp_chunk *retval;
|
||||
sctp_chunkhdr_t *chunk_hdr;
|
||||
@@ -1369,8 +1380,7 @@ static struct sctp_chunk *_sctp_make_chunk(const struct sctp_association *asoc,
|
||||
struct sock *sk;
|
||||
|
||||
/* No need to allocate LL here, as this is only a chunk. */
|
||||
skb = alloc_skb(WORD_ROUND(sizeof(sctp_chunkhdr_t) + paylen),
|
||||
GFP_ATOMIC);
|
||||
skb = alloc_skb(WORD_ROUND(sizeof(sctp_chunkhdr_t) + paylen), gfp);
|
||||
if (!skb)
|
||||
goto nodata;
|
||||
|
||||
@@ -1381,7 +1391,7 @@ static struct sctp_chunk *_sctp_make_chunk(const struct sctp_association *asoc,
|
||||
chunk_hdr->length = htons(sizeof(sctp_chunkhdr_t));
|
||||
|
||||
sk = asoc ? asoc->base.sk : NULL;
|
||||
retval = sctp_chunkify(skb, asoc, sk);
|
||||
retval = sctp_chunkify(skb, asoc, sk, gfp);
|
||||
if (!retval) {
|
||||
kfree_skb(skb);
|
||||
goto nodata;
|
||||
@@ -1400,16 +1410,18 @@ nodata:
|
||||
}
|
||||
|
||||
static struct sctp_chunk *sctp_make_data(const struct sctp_association *asoc,
|
||||
__u8 flags, int paylen)
|
||||
__u8 flags, int paylen, gfp_t gfp)
|
||||
{
|
||||
return _sctp_make_chunk(asoc, SCTP_CID_DATA, flags, paylen);
|
||||
return _sctp_make_chunk(asoc, SCTP_CID_DATA, flags, paylen, gfp);
|
||||
}
|
||||
|
||||
static struct sctp_chunk *sctp_make_control(const struct sctp_association *asoc,
|
||||
__u8 type, __u8 flags, int paylen)
|
||||
__u8 type, __u8 flags, int paylen,
|
||||
gfp_t gfp)
|
||||
{
|
||||
struct sctp_chunk *chunk = _sctp_make_chunk(asoc, type, flags, paylen);
|
||||
struct sctp_chunk *chunk;
|
||||
|
||||
chunk = _sctp_make_chunk(asoc, type, flags, paylen, gfp);
|
||||
if (chunk)
|
||||
sctp_control_set_owner_w(chunk);
|
||||
|
||||
@@ -1606,7 +1618,6 @@ static sctp_cookie_param_t *sctp_pack_cookie(const struct sctp_endpoint *ep,
|
||||
{
|
||||
sctp_cookie_param_t *retval;
|
||||
struct sctp_signed_cookie *cookie;
|
||||
struct scatterlist sg;
|
||||
int headersize, bodysize;
|
||||
|
||||
/* Header size is static data prior to the actual cookie, including
|
||||
@@ -1663,16 +1674,19 @@ static sctp_cookie_param_t *sctp_pack_cookie(const struct sctp_endpoint *ep,
|
||||
ntohs(init_chunk->chunk_hdr->length), raw_addrs, addrs_len);
|
||||
|
||||
if (sctp_sk(ep->base.sk)->hmac) {
|
||||
struct hash_desc desc;
|
||||
SHASH_DESC_ON_STACK(desc, sctp_sk(ep->base.sk)->hmac);
|
||||
int err;
|
||||
|
||||
/* Sign the message. */
|
||||
sg_init_one(&sg, &cookie->c, bodysize);
|
||||
desc.tfm = sctp_sk(ep->base.sk)->hmac;
|
||||
desc.flags = 0;
|
||||
desc->tfm = sctp_sk(ep->base.sk)->hmac;
|
||||
desc->flags = 0;
|
||||
|
||||
if (crypto_hash_setkey(desc.tfm, ep->secret_key,
|
||||
sizeof(ep->secret_key)) ||
|
||||
crypto_hash_digest(&desc, &sg, bodysize, cookie->signature))
|
||||
err = crypto_shash_setkey(desc->tfm, ep->secret_key,
|
||||
sizeof(ep->secret_key)) ?:
|
||||
crypto_shash_digest(desc, (u8 *)&cookie->c, bodysize,
|
||||
cookie->signature);
|
||||
shash_desc_zero(desc);
|
||||
if (err)
|
||||
goto free_cookie;
|
||||
}
|
||||
|
||||
@@ -1697,12 +1711,10 @@ struct sctp_association *sctp_unpack_cookie(
|
||||
struct sctp_cookie *bear_cookie;
|
||||
int headersize, bodysize, fixed_size;
|
||||
__u8 *digest = ep->digest;
|
||||
struct scatterlist sg;
|
||||
unsigned int len;
|
||||
sctp_scope_t scope;
|
||||
struct sk_buff *skb = chunk->skb;
|
||||
ktime_t kt;
|
||||
struct hash_desc desc;
|
||||
|
||||
/* Header size is static data prior to the actual cookie, including
|
||||
* any padding.
|
||||
@@ -1733,16 +1745,23 @@ struct sctp_association *sctp_unpack_cookie(
|
||||
goto no_hmac;
|
||||
|
||||
/* Check the signature. */
|
||||
sg_init_one(&sg, bear_cookie, bodysize);
|
||||
desc.tfm = sctp_sk(ep->base.sk)->hmac;
|
||||
desc.flags = 0;
|
||||
{
|
||||
SHASH_DESC_ON_STACK(desc, sctp_sk(ep->base.sk)->hmac);
|
||||
int err;
|
||||
|
||||
memset(digest, 0x00, SCTP_SIGNATURE_SIZE);
|
||||
if (crypto_hash_setkey(desc.tfm, ep->secret_key,
|
||||
sizeof(ep->secret_key)) ||
|
||||
crypto_hash_digest(&desc, &sg, bodysize, digest)) {
|
||||
*error = -SCTP_IERROR_NOMEM;
|
||||
goto fail;
|
||||
desc->tfm = sctp_sk(ep->base.sk)->hmac;
|
||||
desc->flags = 0;
|
||||
|
||||
err = crypto_shash_setkey(desc->tfm, ep->secret_key,
|
||||
sizeof(ep->secret_key)) ?:
|
||||
crypto_shash_digest(desc, (u8 *)bear_cookie, bodysize,
|
||||
digest);
|
||||
shash_desc_zero(desc);
|
||||
|
||||
if (err) {
|
||||
*error = -SCTP_IERROR_NOMEM;
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
|
||||
if (memcmp(digest, cookie->signature, SCTP_SIGNATURE_SIZE)) {
|
||||
@@ -2757,7 +2776,8 @@ static struct sctp_chunk *sctp_make_asconf(struct sctp_association *asoc,
|
||||
length += addrlen;
|
||||
|
||||
/* Create the chunk. */
|
||||
retval = sctp_make_control(asoc, SCTP_CID_ASCONF, 0, length);
|
||||
retval = sctp_make_control(asoc, SCTP_CID_ASCONF, 0, length,
|
||||
GFP_ATOMIC);
|
||||
if (!retval)
|
||||
return NULL;
|
||||
|
||||
@@ -2941,7 +2961,8 @@ static struct sctp_chunk *sctp_make_asconf_ack(const struct sctp_association *as
|
||||
int length = sizeof(asconf) + vparam_len;
|
||||
|
||||
/* Create the chunk. */
|
||||
retval = sctp_make_control(asoc, SCTP_CID_ASCONF_ACK, 0, length);
|
||||
retval = sctp_make_control(asoc, SCTP_CID_ASCONF_ACK, 0, length,
|
||||
GFP_ATOMIC);
|
||||
if (!retval)
|
||||
return NULL;
|
||||
|
||||
@@ -3501,7 +3522,7 @@ struct sctp_chunk *sctp_make_fwdtsn(const struct sctp_association *asoc,
|
||||
|
||||
hint = (nstreams + 1) * sizeof(__u32);
|
||||
|
||||
retval = sctp_make_control(asoc, SCTP_CID_FWD_TSN, 0, hint);
|
||||
retval = sctp_make_control(asoc, SCTP_CID_FWD_TSN, 0, hint, GFP_ATOMIC);
|
||||
|
||||
if (!retval)
|
||||
return NULL;
|
||||
|
Reference in New Issue
Block a user