1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
|
CVE-2014-9295 ntp: Multiple buffer overflows via specially-crafted packets
Upstream-Status: Backport [Debian]
Signed-off-by: Armin Kuster <akuster808@gmail.com>
2014-12-12 11:06:03+00:00, stenn@psp-fb1.ntp.org +12 -3
[Sec 2667] buffer overflow in crypto_recv()
2014-12-12 11:13:40+00:00, stenn@psp-fb1.ntp.org +16 -1
[Sec 2668] buffer overflow in ctl_putdata()
2014-12-12 11:19:37+00:00, stenn@psp-fb1.ntp.org +14 -0
[Sec 2669] buffer overflow in configure()
Index: git/ntpd/ntp_crypto.c
===================================================================
--- git.orig/ntpd/ntp_crypto.c 2014-12-20 18:45:44.208851199 +0100
+++ git/ntpd/ntp_crypto.c 2014-12-20 18:45:56.425100776 +0100
@@ -789,15 +789,24 @@
* errors.
*/
if (vallen == (u_int)EVP_PKEY_size(host_pkey)) {
+ u_int32 *cookiebuf = malloc(
+ RSA_size(host_pkey->pkey.rsa));
+ if (!cookiebuf) {
+ rval = XEVNT_CKY;
+ break;
+ }
+
if (RSA_private_decrypt(vallen,
(u_char *)ep->pkt,
- (u_char *)&temp32,
+ (u_char *)cookiebuf,
host_pkey->pkey.rsa,
- RSA_PKCS1_OAEP_PADDING) <= 0) {
+ RSA_PKCS1_OAEP_PADDING) != 4) {
rval = XEVNT_CKY;
+ free(cookiebuf);
break;
} else {
- cookie = ntohl(temp32);
+ cookie = ntohl(*cookiebuf);
+ free(cookiebuf);
}
} else {
rval = XEVNT_CKY;
Index: git/ntpd/ntp_control.c
===================================================================
--- git.orig/ntpd/ntp_control.c 2014-12-20 18:45:44.208851199 +0100
+++ git/ntpd/ntp_control.c 2014-12-20 18:45:56.429100859 +0100
@@ -486,6 +486,10 @@
static char *reqpt;
static char *reqend;
+#ifndef MIN
+#define MIN(a, b) (((a) <= (b)) ? (a) : (b))
+#endif
+
/*
* init_control - initialize request data
*/
@@ -995,6 +999,7 @@
)
{
int overhead;
+ unsigned int currentlen;
overhead = 0;
if (!bin) {
@@ -1018,12 +1023,22 @@
/*
* Save room for trailing junk
*/
- if (dlen + overhead + datapt > dataend) {
+ while (dlen + overhead + datapt > dataend) {
/*
* Not enough room in this one, flush it out.
*/
+ currentlen = MIN(dlen, dataend - datapt);
+
+ memcpy(datapt, dp, currentlen);
+
+ datapt += currentlen;
+ dp += currentlen;
+ dlen -= currentlen;
+ datalinelen += currentlen;
+
ctl_flushpkt(CTL_MORE);
}
+
memmove((char *)datapt, dp, (unsigned)dlen);
datapt += dlen;
datalinelen += dlen;
@@ -2492,6 +2507,20 @@
/* Initialize the remote config buffer */
data_count = reqend - reqpt;
+
+ if (data_count > sizeof(remote_config.buffer) - 2) {
+ snprintf(remote_config.err_msg,
+ sizeof(remote_config.err_msg),
+ "runtime configuration failed: request too long");
+ ctl_putdata(remote_config.err_msg,
+ strlen(remote_config.err_msg), 0);
+ ctl_flushpkt(0);
+ msyslog(LOG_NOTICE,
+ "runtime config from %s rejected: request too long",
+ stoa(&rbufp->recv_srcadr));
+ return;
+ }
+
memcpy(remote_config.buffer, reqpt, data_count);
if (data_count > 0
&& '\n' != remote_config.buffer[data_count - 1])
|