sctp: set frag_point in sctp_setsockopt_maxseg correctly
authorXin Long <[email protected]>
Fri, 17 Nov 2017 06:11:11 +0000 (14:11 +0800)
committerDavid S. Miller <[email protected]>
Sat, 18 Nov 2017 01:32:41 +0000 (10:32 +0900)
commitecca8f88da5c4260cc2bccfefd2a24976704c366
tree763c7eece0fe70691f21ce60d1f6b3ef8e6759b5
parentd35ef8f846c72d84bfccf239c248c84f79c3a7e8
sctp: set frag_point in sctp_setsockopt_maxseg correctly

Now in sctp_setsockopt_maxseg user_frag or frag_point can be set with
val >= 8 and val <= SCTP_MAX_CHUNK_LEN. But both checks are incorrect.

val >= 8 means frag_point can even be less than SCTP_DEFAULT_MINSEGMENT.
Then in sctp_datamsg_from_user(), when it's value is greater than cookie
echo len and trying to bundle with cookie echo chunk, the first_len will
overflow.

The worse case is when it's value is equal as cookie echo len, first_len
becomes 0, it will go into a dead loop for fragment later on. In Hangbin
syzkaller testing env, oom was even triggered due to consecutive memory
allocation in that loop.

Besides, SCTP_MAX_CHUNK_LEN is the max size of the whole chunk, it should
deduct the data header for frag_point or user_frag check.

This patch does a proper check with SCTP_DEFAULT_MINSEGMENT subtracting
the sctphdr and datahdr, SCTP_MAX_CHUNK_LEN subtracting datahdr when
setting frag_point via sockopt. It also improves sctp_setsockopt_maxseg
codes.

Suggested-by: Marcelo Ricardo Leitner <[email protected]>
Reported-by: Hangbin Liu <[email protected]>
Signed-off-by: Xin Long <[email protected]>
Acked-by: Marcelo Ricardo Leitner <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
include/net/sctp/sctp.h
net/sctp/socket.c