Some sockopt optlen fixes
Subsystems (3)
Marcelo Ricardo Leitner
maintainercover Some sockopt optlen fixes
Hangbin Liu reported that some SCTP sockopt are allowing the user to get the kernel to allocate really large buffers by not having a ceiling on optlen.
This patchset address this issue (in patch 2), replace an GFP_ATOMIC that isn't needed and avoid calculating the option size multiple times in some setsockopt.
Marcelo Ricardo Leitner (3):
sctp: GFP_ATOMIC is not needed in sctp_setsockopt_events
sctp: add a ceiling to optlen in some sockopts
sctp: make use of pre-calculated len
net/sctp/socket.c | 28 +++++++++++++++++++++------- 1 file changed, 21 insertions(+), 7 deletions(-)
Signature · 1 line
2.14.3
Marcelo Ricardo Leitner
maintainerPATCH 1/3 sctp: GFP_ATOMIC is not needed in sctp_setsockopt_events
So replace it with GFP_USER and also add __GFP_NOWARN.
--- net/sctp/socket.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
net/sctp/socket.c +1 -1
@@ -2277,7 +2277,7 @@ static int sctp_setsockopt_events(struct sock *sk, char __user *optval,if (asoc &&sctp_outq_is_empty (&asoc->outqueue)) { event =sctp_ulpevent_make_sender_dry_event (asoc, -GFP_ATOMIC ); +GFP_USER | __GFP_NOWARN);if (!event)return -ENOMEM ;
Signature · 1 line
2.14.3
Marcelo Ricardo Leitner
maintainerPATCH 2/3 sctp: add a ceiling to optlen in some sockopts
In reply to Marcelo Ricardo LeitnerHangbin Liu reported that some sockopt calls could cause the kernel to log a warning on memory allocation failure if the user supplied a large optlen value. That is because some of them called memdup_user() without a ceiling on optlen, allowing it to try to allocate really large buffers.
This patch adds a ceiling by limiting optlen to the maximum allowed that would still make sense for these sockopt.
--- net/sctp/socket.c | 10 ++++++++++ 1 file changed, 10 insertions(+)
net/sctp/socket.c +10 -0
@@ -3498,6 +3498,8 @@ static int sctp_setsockopt_hmac_ident(struct sock *sk,if (optlen <sizeof (struct sctp_hmacalgo ))return -EINVAL ; + optlen = min_t(unsigned int, optlen, sizeof(struct sctp_hmacalgo) + +SCTP_AUTH_NUM_HMACS *sizeof (u16)); hmacs =memdup_user (optval, optlen);if (IS_ERR (hmacs))
@@ -3536,6 +3538,11 @@ static int sctp_setsockopt_auth_key(struct sock *sk,if (optlen <=sizeof (struct sctp_authkey ))return -EINVAL ; +/* authkey->sca_keylength is u16, so optlen can't be bigger than +* this. +*/ + optlen = min_t(unsigned int, optlen, USHRT_MAX + +sizeof (struct sctp_authkey )); authkey =memdup_user (optval, optlen);if (IS_ERR (authkey))
@@ -3893,6 +3900,9 @@ static int sctp_setsockopt_reset_streams(struct sock *sk,if (optlen <sizeof (*params))return -EINVAL ; +/* srs_number_streams is u16, so optlen can't be bigger than this. */ + optlen = min_t(unsigned int, optlen, USHRT_MAX + +sizeof (__u16) *sizeof (*params)); params =memdup_user (optval, optlen);if (IS_ERR (params))
Signature · 1 line
2.14.3
Marcelo Ricardo Leitner
maintainerPATCH 3/3 sctp: make use of pre-calculated len
In reply to Marcelo Ricardo LeitnerSome sockopt handling functions were calculating the length of the buffer to be written to userspace and then calculating it again when actually writing the buffer, which could lead to some write not using an up-to-date length.
This patch updates such places to just make use of the len variable.
Also, replace some sizeof(type) to sizeof(var).
--- net/sctp/socket.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-)
net/sctp/socket.c +10 -6
@@ -5025,7 +5025,7 @@ static int sctp_getsockopt_autoclose(struct sock *sk, int len, char __user *optv len =sizeof (int );if (put_user (len, optlen))return -EFAULT ; -if (copy_to_user (optval, &sctp_sk (sk)->autoclose,sizeof (int ))) +if (copy_to_user (optval, &sctp_sk (sk)->autoclose, len))return -EFAULT ;return 0 ; }
@@ -5655,6 +5655,9 @@ static int sctp_getsockopt_local_addrs(struct sock *sk, int len, err = -EFAULT ; goto out; } +/* XXX: We should have accounted for sizeof(struct sctp_getaddrs) too, +* but we can't change it anymore. +*/ if (put_user (bytes_copied, optlen)) err = -EFAULT ; out:
@@ -6091,7 +6094,7 @@ static int sctp_getsockopt_maxseg(struct sock *sk, int len, params.assoc_id =0 ; }else if (len >=sizeof (struct sctp_assoc_value )) { len =sizeof (struct sctp_assoc_value ); -if (copy_from_user (¶ms, optval,sizeof (params))) +if (copy_from_user (¶ms, optval, len))return -EFAULT ; }else return -EINVAL ;
@@ -6261,7 +6264,9 @@ static int sctp_getsockopt_active_key(struct sock *sk, int len,if (len <sizeof (struct sctp_authkeyid ))return -EINVAL ; -if (copy_from_user (&val, optval,sizeof (struct sctp_authkeyid ))) + + len =sizeof (struct sctp_authkeyid ); +if (copy_from_user (&val, optval, len))return -EFAULT ; asoc =sctp_id2assoc (sk, val.scact_assoc_id);
@@ -6273,7 +6278,6 @@ static int sctp_getsockopt_active_key(struct sock *sk, int len,else val.scact_keynumber = ep->active_key_id; - len =sizeof (struct sctp_authkeyid );if (put_user (len, optlen))return -EFAULT ;if (copy_to_user (optval, &val, len))
@@ -6299,7 +6303,7 @@ static int sctp_getsockopt_peer_auth_chunks(struct sock *sk, int len,if (len <sizeof (struct sctp_authchunks ))return -EINVAL ; -if (copy_from_user (&val, optval,sizeof (struct sctp_authchunks ))) +if (copy_from_user (&val, optval,sizeof (val)))return -EFAULT ; to = p->gauth_chunks;
@@ -6344,7 +6348,7 @@ static int sctp_getsockopt_local_auth_chunks(struct sock *sk, int len,if (len <sizeof (struct sctp_authchunks ))return -EINVAL ; -if (copy_from_user (&val, optval,sizeof (struct sctp_authchunks ))) +if (copy_from_user (&val, optval,sizeof (val)))return -EFAULT ; to = p->gauth_chunks;
Signature · 1 line
2.14.3
Quoted 8 lines · Marcelo Ricardo Leitner
Hangbin Liu reported that some SCTP sockopt are allowing the user to get the kernel to allocate really large buffers by not having a ceiling on optlen.
This patchset address this issue (in patch 2), replace an
GFP_ATOMICthat isn't needed and avoid calculating the option size multiple times in some setsockopt.
Quoted 12 lines
Marcelo Ricardo Leitner (3):
sctp:GFP_ATOMICis not needed insctp_setsockopt_events
sctp: add a ceiling to optlen in some sockopts
sctp: make use of pre-calculated lennet/sctp/socket.c | 28 +++++++++++++++++++++------- 1 file changed, 21 insertions(+), 7 deletions(-)Signature · 1 line
2.14.3
Series
David Miller
maintainerFrom: Marcelo Ricardo Leitner <[email protected]>
Date: Mon, 8 Jan 2018 19:02:26 -0200
Quoted 7 lines
Hangbin Liu reported that some SCTP sockopt are allowing the user to get the kernel to allocate really large buffers by not having a ceiling on optlen.
This patchset address this issue (in patch 2), replace an
GFP_ATOMICthat isn't needed and avoid calculating the option size multiple times in some setsockopt.
Series applied, thank you.