sctp: Fix kernel panic while process protocol violation parameter
Since call to function sctp_sf_abort_violation() need paramter 'arg' with 'struct sctp_chunk' type, it will read the chunk type and chunk length from the chunk_hdr member of chunk. But call to sctp_sf_violation_paramlen() always with 'struct sctp_paramhdr' type's parameter, it will be passed to sctp_sf_abort_violation(). This may cause kernel panic. sctp_sf_violation_paramlen() |-- sctp_sf_abort_violation() |-- sctp_make_abort_violation() This patch fixed this problem. This patch also fix two place which called sctp_sf_violation_paramlen() with wrong paramter type. Signed-off-by: Wei Yongjun <yjwei@cn.fujitsu.com> Signed-off-by: Vlad Yasevich <vladislav.yasevich@hp.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
committed by
David S. Miller
parent
8b122efd13
commit
ba0166708e
@@ -1012,6 +1012,29 @@ end:
|
||||
return retval;
|
||||
}
|
||||
|
||||
struct sctp_chunk *sctp_make_violation_paramlen(
|
||||
const struct sctp_association *asoc,
|
||||
const struct sctp_chunk *chunk,
|
||||
struct sctp_paramhdr *param)
|
||||
{
|
||||
struct sctp_chunk *retval;
|
||||
static const char error[] = "The following parameter had invalid length:";
|
||||
size_t payload_len = sizeof(error) + sizeof(sctp_errhdr_t) +
|
||||
sizeof(sctp_paramhdr_t);
|
||||
|
||||
retval = sctp_make_abort(asoc, chunk, payload_len);
|
||||
if (!retval)
|
||||
goto nodata;
|
||||
|
||||
sctp_init_cause(retval, SCTP_ERROR_PROTO_VIOLATION,
|
||||
sizeof(error) + sizeof(sctp_paramhdr_t));
|
||||
sctp_addto_chunk(retval, sizeof(error), error);
|
||||
sctp_addto_param(retval, sizeof(sctp_paramhdr_t), param);
|
||||
|
||||
nodata:
|
||||
return retval;
|
||||
}
|
||||
|
||||
/* Make a HEARTBEAT chunk. */
|
||||
struct sctp_chunk *sctp_make_heartbeat(const struct sctp_association *asoc,
|
||||
const struct sctp_transport *transport,
|
||||
@@ -1782,11 +1805,6 @@ static int sctp_process_inv_paramlength(const struct sctp_association *asoc,
|
||||
const struct sctp_chunk *chunk,
|
||||
struct sctp_chunk **errp)
|
||||
{
|
||||
static const char error[] = "The following parameter had invalid length:";
|
||||
size_t payload_len = WORD_ROUND(sizeof(error)) +
|
||||
sizeof(sctp_paramhdr_t);
|
||||
|
||||
|
||||
/* This is a fatal error. Any accumulated non-fatal errors are
|
||||
* not reported.
|
||||
*/
|
||||
@@ -1794,14 +1812,7 @@ static int sctp_process_inv_paramlength(const struct sctp_association *asoc,
|
||||
sctp_chunk_free(*errp);
|
||||
|
||||
/* Create an error chunk and fill it in with our payload. */
|
||||
*errp = sctp_make_op_error_space(asoc, chunk, payload_len);
|
||||
|
||||
if (*errp) {
|
||||
sctp_init_cause(*errp, SCTP_ERROR_PROTO_VIOLATION,
|
||||
sizeof(error) + sizeof(sctp_paramhdr_t));
|
||||
sctp_addto_chunk(*errp, sizeof(error), error);
|
||||
sctp_addto_param(*errp, sizeof(sctp_paramhdr_t), param);
|
||||
}
|
||||
*errp = sctp_make_violation_paramlen(asoc, chunk, param);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
Reference in New Issue
Block a user