* Copyright (c) 2004, 2006, 2008-2013, 2015 Apple Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
- *
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
* compliance with the License. Please obtain a copy of the License at
* http://www.opensource.apple.com/apsl/ and read it before using this
* file.
- *
+ *
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
* Please see the License for the specific language governing rights and
* limitations under the License.
- *
+ *
* @APPLE_LICENSE_HEADER_END@
*/
dns_configuration_copy()
{
uint8_t *buf = NULL;
+ size_t bufLen;
dns_config_t *config = NULL;
static const char *proc_name = NULL;
xpc_object_t reqdict;
static const char *service_name = DNSINFO_SERVICE_NAME;
dispatch_once(&once, ^{
+#if DEBUG
const char *name;
// get [XPC] service name
name = getenv(service_name);
- if ((name != NULL) && (issetugid() == 0)) {
+ if (name != NULL) {
service_name = strdup(name);
}
+#endif // DEBUG
// get process name
proc_name = getprogname();
if ((dataRef != NULL) &&
((dataLen >= sizeof(_dns_config_buf_t)) && (dataLen <= DNS_CONFIG_BUF_MAX))) {
_dns_config_buf_t *config = (_dns_config_buf_t *)(void *)dataRef;
- uint32_t n_padding = ntohl(config->n_padding);
-
- if (n_padding <= (DNS_CONFIG_BUF_MAX - dataLen)) {
- size_t len;
-
- len = dataLen + n_padding;
- buf = malloc(len);
- bcopy((void *)dataRef, buf, dataLen);
- bzero(&buf[dataLen], n_padding);
- }
+ size_t configLen;
+ uint32_t n_attribute = ntohl(config->n_attribute);
+ uint32_t n_padding = ntohl(config->n_padding);
+
+ /*
+ * Check that the size of the configuration header plus the size of the
+ * attribute data matches the size of the configuration buffer.
+ *
+ * If the sizes are different, something that should NEVER happen, CRASH!
+ */
+ configLen = sizeof(_dns_config_buf_t) + n_attribute;
+ assert(configLen == dataLen);
+
+ /*
+ * Check that the size of the requested padding would not result in our
+ * allocating a configuration + padding buffer larger than our maximum size.
+ *
+ * If the requested padding size is too large, something that should NEVER
+ * happen, CRASH!
+ */
+ assert(n_padding <= (DNS_CONFIG_BUF_MAX - dataLen));
+
+ /*
+ * Check that the actual size of the configuration data and any requested
+ * padding will be less than the maximum possible size of the in-memory
+ * configuration buffer.
+ *
+ * If the length needed is too large, something that should NEVER happen, CRASH!
+ */
+ bufLen = dataLen + n_padding;
+ assert(bufLen <= DNS_CONFIG_BUF_MAX);
+
+ // allocate a buffer large enough to hold both the configuration
+ // data and the padding.
+ buf = malloc(bufLen);
+ bcopy((void *)dataRef, buf, dataLen);
+ bzero(&buf[dataLen], n_padding);
}
xpc_release(reply);
resolver->n_nameserver = ntohl(resolver->n_nameserver);
if (!__dns_configuration_expand_add_list(padding,
- n_padding,
- resolver->n_nameserver,
- sizeof(DNS_PTR(struct sockaddr *, x)),
- (void **)&resolver->nameserver)) {
+ n_padding,
+ resolver->n_nameserver,
+ sizeof(DNS_PTR(struct sockaddr *, x)),
+ (void **)&resolver->nameserver)) {
goto error;
}
resolver->n_search = ntohl(resolver->n_search);
if (!__dns_configuration_expand_add_list(padding,
- n_padding,
- resolver->n_search,
- sizeof(DNS_PTR(char *, x)),
- (void **)&resolver->search)) {
+ n_padding,
+ resolver->n_search,
+ sizeof(DNS_PTR(char *, x)),
+ (void **)&resolver->search)) {
goto error;
}
resolver->n_sortaddr = ntohl(resolver->n_sortaddr);
if (!__dns_configuration_expand_add_list(padding,
- n_padding,
- resolver->n_sortaddr,
- sizeof(DNS_PTR(dns_sortaddr_t *, x)),
- (void **)&resolver->sortaddr)) {
+ n_padding,
+ resolver->n_sortaddr,
+ sizeof(DNS_PTR(dns_sortaddr_t *, x)),
+ (void **)&resolver->sortaddr)) {
goto error;
}
int32_t n_service_specific_resolver = 0;
void *padding;
- // establish padding
+ n_attribute = ntohl(buf->n_attribute); // pre-validated (or known OK) at entry
+ n_padding = ntohl(buf->n_padding); // pre-validated (or known OK) at entry
- padding = &buf->attribute[ntohl(buf->n_attribute)];
- n_padding = ntohl(buf->n_padding);
+ // establish the start of padding to be after the last attribute
+
+ padding = &buf->attribute[n_attribute];
// initialize resolver lists
config->n_resolver = ntohl(config->n_resolver);
if (!__dns_configuration_expand_add_list(&padding,
- &n_padding,
- config->n_resolver,
- sizeof(DNS_PTR(dns_resolver_t *, x)),
- (void **)&config->resolver)) {
+ &n_padding,
+ config->n_resolver,
+ sizeof(DNS_PTR(dns_resolver_t *, x)),
+ (void **)&config->resolver)) {
goto error;
}
config->n_scoped_resolver = ntohl(config->n_scoped_resolver);
if (!__dns_configuration_expand_add_list(&padding,
- &n_padding,
- config->n_scoped_resolver,
- sizeof(DNS_PTR(dns_resolver_t *, x)),
- (void **)&config->scoped_resolver)) {
+ &n_padding,
+ config->n_scoped_resolver,
+ sizeof(DNS_PTR(dns_resolver_t *, x)),
+ (void **)&config->scoped_resolver)) {
goto error;
}
config->n_service_specific_resolver = ntohl(config->n_service_specific_resolver);
if (!__dns_configuration_expand_add_list(&padding,
- &n_padding,
- config->n_service_specific_resolver,
- sizeof(DNS_PTR(dns_resolver_t *, x)),
- (void **)&config->service_specific_resolver)) {
+ &n_padding,
+ config->n_service_specific_resolver,
+ sizeof(DNS_PTR(dns_resolver_t *, x)),
+ (void **)&config->service_specific_resolver)) {
goto error;
}
// process configuration buffer "attribute" data
- n_attribute = ntohl(buf->n_attribute);
- attribute = (dns_attribute_t *)(void *)&buf->attribute[0];
+ attribute = (dns_attribute_t *)(void *)&buf->attribute[0];
while (n_attribute >= sizeof(dns_attribute_t)) {
uint32_t attribute_length = ntohl(attribute->length);