1
Description: Fix cve-2011-4868: error in DDNS handling with IPv6
2
Bug-Debian: http://bugs.debian.org/655746
3
Index: isc-dhcp/includes/dhcpd.h
4
===================================================================
5
--- isc-dhcp.orig/includes/dhcpd.h 2012-04-27 13:33:50.000000000 -0400
6
+++ isc-dhcp/includes/dhcpd.h 2012-04-28 15:46:28.000000000 -0400
8
#define DDNS_CLIENT_DID_UPDATE 0x10
9
#define DDNS_EXECUTE_NEXT 0x20
10
#define DDNS_ABORT 0x40
11
+#define DDNS_ACTIVE_LEASE 0x100
14
* The following two groups are separate and we could reuse
17
struct dns_zone *zone;
23
ddns_action_t cur_func;
26
int ddns_updates(struct packet *, struct lease *, struct lease *,
27
struct iasubopt *, struct iasubopt *, struct option_state *);
28
-int ddns_removals(struct lease *, struct iasubopt *, struct dhcp_ddns_cb *);
29
+int ddns_removals(struct lease *, struct iasubopt *, struct dhcp_ddns_cb *, isc_boolean_t);
31
void trace_ddns_init(void);
33
Index: isc-dhcp/server/ddns.c
34
===================================================================
35
--- isc-dhcp.orig/server/ddns.c 2012-04-27 13:33:50.000000000 -0400
36
+++ isc-dhcp/server/ddns.c 2012-04-28 15:51:44.000000000 -0400
38
if (ddns_cb == NULL) {
41
- /* assume that we shall update both the A and ptr records */
42
- ddns_cb->flags = DDNS_UPDATE_ADDR | DDNS_UPDATE_PTR;
44
+ * Assume that we shall update both the A and ptr records and,
45
+ * as this is an update, set the active flag
47
+ ddns_cb->flags = DDNS_UPDATE_ADDR | DDNS_UPDATE_PTR |
51
scope = &(lease->scope);
54
/* If desired do the removals */
56
- (void) ddns_removals(lease, lease6, NULL);
57
+ (void) ddns_removals(lease, lease6, NULL, ISC_TRUE);
62
* the ddns messages. Currently we don't.
65
- rcode1 = ddns_removals(lease, lease6, ddns_cb);
66
+ rcode1 = ddns_removals(lease, lease6, ddns_cb, ISC_TRUE);
69
ddns_fwd_srv_connector(lease, lease6, scope, ddns_cb,
72
struct data_string lease_dhcid;
75
+ * If we are processing an expired or released v6 lease
76
+ * we don't actually have a scope to update
78
+ if ((ddns_cb->address.len == 16) &&
79
+ ((ddns_cb->flags & DDNS_ACTIVE_LEASE) == 0)) {
80
+ return (ISC_R_SUCCESS);
83
if (inscope != NULL) {
85
} else if (ddns_cb->address.len == 4) {
86
@@ -1052,6 +1065,15 @@
87
file, line, ddns_cb, ddns_address );
91
+ * If we are processing an expired or released v6 lease
92
+ * we don't actually have a scope to update
94
+ if ((ddns_cb->address.len == 16) &&
95
+ ((ddns_cb->flags & DDNS_ACTIVE_LEASE) == 0)) {
96
+ return (ISC_R_SUCCESS);
100
safe_lease_update(lease, NULL, ddns_cb, ddns_cb_set,
102
@@ -1104,7 +1126,7 @@
104
(find_ipv6_pool(&pool, D6O_IA_NA, &addr) !=
106
- inet_ntop(AF_INET6, &lease6->addr, addrbuf,
107
+ inet_ntop(AF_INET6, &addr, addrbuf,
108
MAX_ADDRESS_STRING_LEN);
109
log_error("%s(%d): Pool for lease %s not found.",
110
file, line, addrbuf);
111
@@ -1124,7 +1146,7 @@
112
find_lease6->ddns_cb = ddns_cb_set;
113
iasubopt_dereference(&find_lease6, MDL);
115
- inet_ntop(AF_INET6, &lease6->addr, addrbuf,
116
+ inet_ntop(AF_INET6, &addr, addrbuf,
117
MAX_ADDRESS_STRING_LEN);
118
log_error("%s(%d): Lease %s not found within pool.",
119
file, line, addrbuf);
120
@@ -1566,12 +1588,18 @@
121
* 0 - badness occurred and we weren't able to do what was wanted
122
* 1 - we were able to do stuff but it's in progress
123
* in both cases any additional block has been passed on to it's handler
125
+ * active == ISC_TRUE if the lease is still active, and FALSE if the lease
126
+ * is inactive. This is used to indicate if the lease is inactive or going
127
+ * to inactive in IPv6 so we can avoid trying to update the lease with
128
+ * cb pointers and text information.
132
ddns_removals(struct lease *lease,
133
struct iasubopt *lease6,
134
- dhcp_ddns_cb_t *add_ddns_cb)
135
+ dhcp_ddns_cb_t *add_ddns_cb,
136
+ isc_boolean_t active)
138
isc_result_t rcode, execute_add = ISC_R_FAILURE;
139
struct binding_scope **scope = NULL;
140
@@ -1610,6 +1638,16 @@
145
+ * Set the flag bit if the lease is active, that is it isn't
146
+ * expired or released. This is used in the IPv6 paths to
147
+ * determine if we need to update the lease when the response
148
+ * from the DNS code is processed.
150
+ if (active == ISC_TRUE) {
151
+ ddns_cb->flags |= DDNS_ACTIVE_LEASE;
154
/* No scope implies that DDNS has not been performed for this lease. */
157
Index: isc-dhcp/server/failover.c
158
===================================================================
159
--- isc-dhcp.orig/server/failover.c 2012-04-27 13:33:50.000000000 -0400
160
+++ isc-dhcp/server/failover.c 2012-04-28 15:44:55.000000000 -0400
161
@@ -5218,7 +5218,7 @@
163
if (msg->binding_status == FTS_ACTIVE &&
164
(chaddr_changed || ident_changed)) {
165
- ddns_removals(lease, NULL, NULL);
166
+ ddns_removals(lease, NULL, NULL, ISC_FALSE);
168
if (lease->scope != NULL)
169
binding_scope_dereference(&lease->scope, MDL);
170
Index: isc-dhcp/server/mdb6.c
171
===================================================================
172
--- isc-dhcp.orig/server/mdb6.c 2012-04-27 13:33:50.000000000 -0400
173
+++ isc-dhcp/server/mdb6.c 2012-04-28 15:44:55.000000000 -0400
174
@@ -1058,7 +1058,7 @@
175
#if defined (NSUPDATE)
176
/* Process events upon expiration. */
177
if (pool->pool_type != D6O_IA_PD) {
178
- ddns_removals(NULL, lease, NULL);
179
+ ddns_removals(NULL, lease, NULL, ISC_FALSE);
183
@@ -1466,6 +1466,11 @@
184
* Note that if there are no leases in the pool,
185
* expire_lease6() will return ISC_R_SUCCESS with
188
+ * expire_lease6() will call move_lease_to_inactive() which
189
+ * calls ddns_removals() do we want that on the standard
190
+ * expiration timer or a special 'depref' timer? Original
191
+ * query from DH, moved here by SAR.
194
if (expire_lease6(&lease, pool, cur_time) != ISC_R_SUCCESS) {
195
@@ -1475,18 +1480,6 @@
199
- /* Look to see if there were ddns updates, and if
202
- * DH: Do we want to do this on a special 'depref'
203
- * timer rather than expiration timer?
205
-#if defined (NSUPDATE)
206
- if (pool->pool_type != D6O_IA_PD) {
207
- ddns_removals(NULL, lease, NULL);
213
iasubopt_dereference(&lease, MDL);
214
Index: isc-dhcp/server/mdb.c
215
===================================================================
216
--- isc-dhcp.orig/server/mdb.c 2012-04-27 13:33:50.000000000 -0400
217
+++ isc-dhcp/server/mdb.c 2012-04-28 15:44:55.000000000 -0400
218
@@ -1445,7 +1445,7 @@
219
lease -> binding_state == FTS_ACTIVE &&
220
lease -> next_binding_state != FTS_RELEASED))) {
221
#if defined (NSUPDATE)
222
- ddns_removals(lease, NULL, NULL);
223
+ ddns_removals(lease, NULL, NULL, ISC_FALSE);
225
if (lease -> on_expiry) {
226
execute_statements ((struct binding_value **)0,
227
@@ -1511,7 +1511,7 @@
228
* release message. This is not true of expiry, where the
229
* peer may have extended the lease.
231
- ddns_removals(lease, NULL, NULL);
232
+ ddns_removals(lease, NULL, NULL, ISC_FALSE);
234
if (lease -> on_release) {
235
execute_statements ((struct binding_value **)0,
236
@@ -1680,7 +1680,7 @@
237
/* If there are statements to execute when the lease is
238
released, execute them. */
239
#if defined (NSUPDATE)
240
- ddns_removals(lease, NULL, NULL);
241
+ ddns_removals(lease, NULL, NULL, ISC_FALSE);
243
if (lease -> on_release) {
244
execute_statements ((struct binding_value **)0,
245
@@ -1754,7 +1754,7 @@
247
struct lease *lt = (struct lease *)0;
248
#if defined (NSUPDATE)
249
- ddns_removals(lease, NULL, NULL);
250
+ ddns_removals(lease, NULL, NULL, ISC_FALSE);
253
if (!lease_copy (<, lease, MDL))
254
@@ -1786,7 +1786,7 @@
256
struct lease *lt = (struct lease *)0;
257
#if defined (NSUPDATE)
258
- ddns_removals(lease, NULL, NULL);
259
+ ddns_removals(lease, NULL, NULL, ISC_FALSE);
262
if (!lease_copy (<, lease, MDL))