Add padding to cmdmon requests to prevent amplification attack

To prevent an attacker using chronyd in an amplification attack, change
the protocol to include padding in request packets so that the largest
possible reply is not larger than the request. Request packets that
don't include this padding are ignored as invalid.

This is an incompatible change in the protocol. Clients from chrony
1.27, 1.28 and 1.29 will receive NULL reply with STT_BADPKTVERSION and
print "Protocol version mismatch". Clients from 1.26 and older will not
receive a reply as it would be larger than the request if it was padded
to be compatible with their protocol.
This commit is contained in:
Miroslav Lichvar
2014-01-24 13:55:15 +01:00
parent 3e23430926
commit dba458d50c
5 changed files with 197 additions and 17 deletions

View File

@@ -1260,6 +1260,7 @@ submit_request(CMD_Request *request, CMD_Reply *reply, int *reply_auth_ok)
int read_length;
int expected_length;
int command_length;
int padding_length;
int auth_length;
struct timeval tv;
int timeout;
@@ -1281,6 +1282,13 @@ submit_request(CMD_Request *request, CMD_Reply *reply, int *reply_auth_ok)
n_attempts = 0;
do {
command_length = PKL_CommandLength(request);
padding_length = PKL_CommandPaddingLength(request);
assert(command_length > 0 && command_length > padding_length);
/* Zero the padding to avoid sending uninitialized data. This needs to be
done before generating auth data as it includes the padding. */
memset(((char *)request) + command_length - padding_length, 0, padding_length);
/* Decide whether to authenticate */
if (password) {
@@ -1294,9 +1302,6 @@ submit_request(CMD_Request *request, CMD_Reply *reply, int *reply_auth_ok)
auth_length = 0;
}
command_length = PKL_CommandLength(request);
assert(command_length > 0);
/* add empty MD5 auth so older servers will not drop the request
due to bad length */
if (!auth_length) {
@@ -1400,7 +1405,7 @@ submit_request(CMD_Request *request, CMD_Reply *reply, int *reply_auth_ok)
}
bad_header = ((reply->version != PROTO_VERSION_NUMBER &&
!(reply->version >= PROTO_VERSION_MISMATCH_COMPAT &&
!(reply->version >= PROTO_VERSION_MISMATCH_COMPAT_CLIENT &&
ntohs(reply->status) == STT_BADPKTVERSION)) ||
(reply->pkt_type != PKT_TYPE_CMD_REPLY) ||
(reply->res1 != 0) ||