]> git.saurik.com Git - apple/xnu.git/blobdiff - bsd/net/net_str_id.c
xnu-7195.50.7.100.1.tar.gz
[apple/xnu.git] / bsd / net / net_str_id.c
index bc28f03c4f9de27779319cd4d64256782f607b7a..a9688c076dbac1be8b94da3e0477d7d598ab736d 100644 (file)
@@ -1,8 +1,8 @@
 /*
- * Copyright (c) 2008,2011 Apple Inc. All rights reserved.
+ * Copyright (c) 2008,2011,2019 Apple Inc. All rights reserved.
  *
  * @APPLE_OSREFERENCE_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
  * unlawful or unlicensed copies of an Apple operating system, or to
  * circumvent, violate, or enable the circumvention or violation of, any
  * terms of an Apple operating system software license agreement.
- * 
+ *
  * 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_OSREFERENCE_LICENSE_HEADER_END@
  */
 
 #include <sys/types.h>
 #include <kern/locks.h>
-#include <kern/kalloc.h>
+#include <kern/zalloc.h>
 #include <sys/errno.h>
 #include <sys/sysctl.h>
 #include <sys/malloc.h>
 
 #include "net/net_str_id.h"
 
-#define        NET_ID_STR_ENTRY_SIZE(__str) \
-       ((size_t)&(((struct net_str_id_entry*)0)->nsi_string[0]) + \
+#define NET_ID_STR_MAX_LEN 2048
+#define NET_ID_STR_ENTRY_SIZE(__str) \
+       (__builtin_offsetof(struct net_str_id_entry, nsi_string[0]) + \
        strlen(__str) + 1)
 
-#define        FIRST_NET_STR_ID                                1000
-static SLIST_HEAD(,net_str_id_entry)   net_str_id_list = {NULL};
-static lck_mtx_t                                               *net_str_id_lock = NULL;
+#define FIRST_NET_STR_ID                                1000
+static SLIST_HEAD(, net_str_id_entry)    net_str_id_list = {NULL};
+decl_lck_mtx_data(static, net_str_id_lock_data);
+static lck_mtx_t        *net_str_id_lock = &net_str_id_lock_data;
 
 static u_int32_t nsi_kind_next[NSI_MAX_KIND] = { FIRST_NET_STR_ID, FIRST_NET_STR_ID, FIRST_NET_STR_ID };
 static u_int32_t nsi_next_id = FIRST_NET_STR_ID;
@@ -57,22 +59,22 @@ extern int sysctl_if_family_ids SYSCTL_HANDLER_ARGS;
 SYSCTL_DECL(_net_link_generic_system);
 
 SYSCTL_PROC(_net_link_generic_system, OID_AUTO, if_family_ids, CTLTYPE_STRUCT | CTLFLAG_RD | CTLFLAG_LOCKED,
-       0, 0, sysctl_if_family_ids, "S, if_family_id", "Interface Family ID table");
+    0, 0, sysctl_if_family_ids, "S, if_family_id", "Interface Family ID table");
 
 __private_extern__ void
 net_str_id_init(void)
 {
-       lck_grp_attr_t  *grp_attrib = NULL;
-       lck_attr_t              *lck_attrb = NULL;
-       lck_grp_t               *lck_group = NULL;
-       
+       lck_grp_attr_t  *grp_attrib = NULL;
+       lck_attr_t              *lck_attrb = NULL;
+       lck_grp_t               *lck_group = NULL;
+
        grp_attrib = lck_grp_attr_alloc_init();
        lck_group = lck_grp_alloc_init("mbuf_tag_allocate_id", grp_attrib);
        lck_grp_attr_free(grp_attrib);
        lck_attrb = lck_attr_alloc_init();
-       
-       net_str_id_lock = lck_mtx_alloc_init(lck_group, lck_attrb);
-       
+
+       lck_mtx_init(net_str_id_lock, lck_group, lck_attrb);
+
        lck_grp_free(lck_group);
        lck_attr_free(lck_attrb);
 }
@@ -83,29 +85,33 @@ net_str_id_first_last(u_int32_t *first, u_int32_t *last, u_int32_t kind)
        *first = FIRST_NET_STR_ID;
 
        switch (kind) {
-               case NSI_MBUF_TAG:
-               case NSI_VENDOR_CODE:
-               case NSI_IF_FAM_ID:
-                       *last = nsi_kind_next[kind] - 1;
-                       break;
-               default:
-                       *last = FIRST_NET_STR_ID - 1;
-                       break;
+       case NSI_MBUF_TAG:
+       case NSI_VENDOR_CODE:
+       case NSI_IF_FAM_ID:
+               *last = nsi_kind_next[kind] - 1;
+               break;
+       default:
+               *last = FIRST_NET_STR_ID - 1;
+               break;
        }
 }
 
 __private_extern__ errno_t
-net_str_id_find_internal(const char    *string, u_int32_t *out_id,
-                                                 u_int32_t     kind, int create)
+net_str_id_find_internal(const char *string, u_int32_t *out_id,
+    u_int32_t kind, int create)
 {
-       struct net_str_id_entry                 *entry = NULL;
-       
-       
-       if (string == NULL || out_id == NULL || kind >= NSI_MAX_KIND)
+       struct net_str_id_entry                 *entry = NULL;
+
+
+       if (string == NULL || out_id == NULL || kind >= NSI_MAX_KIND) {
                return EINVAL;
+       }
+       if (strlen(string) > NET_ID_STR_MAX_LEN) {
+               return EINVAL;
+       }
 
        *out_id = 0;
-       
+
        /* Look for an existing entry */
        lck_mtx_lock(net_str_id_lock);
        SLIST_FOREACH(entry, &net_str_id_list, nsi_next) {
@@ -113,19 +119,20 @@ net_str_id_find_internal(const char       *string, u_int32_t *out_id,
                        break;
                }
        }
-       
+
        if (entry == NULL) {
                if (create == 0) {
                        lck_mtx_unlock(net_str_id_lock);
                        return ENOENT;
                }
-               
-               entry = kalloc(NET_ID_STR_ENTRY_SIZE(string));
+
+               entry = zalloc_permanent(NET_ID_STR_ENTRY_SIZE(string),
+                   ZALIGN_PTR);
                if (entry == NULL) {
                        lck_mtx_unlock(net_str_id_lock);
                        return ENOMEM;
                }
-               
+
                strlcpy(entry->nsi_string, string, strlen(string) + 1);
                entry->nsi_flags = (1 << kind);
                entry->nsi_id = nsi_next_id++;
@@ -137,19 +144,20 @@ net_str_id_find_internal(const char       *string, u_int32_t *out_id,
                        return ENOENT;
                }
                entry->nsi_flags |= (1 << kind);
-               if (entry->nsi_id >= nsi_kind_next[kind])
+               if (entry->nsi_id >= nsi_kind_next[kind]) {
                        nsi_kind_next[kind] = entry->nsi_id + 1;
+               }
        }
        lck_mtx_unlock(net_str_id_lock);
 
        *out_id = entry->nsi_id;
-       
+
        return 0;
 }
 
 
 #define ROUNDUP32(a) \
-        ((a) > 0 ? (1 + (((a) - 1) | (sizeof(uint32_t) - 1))) : sizeof(uint32_t))
+       ((a) > 0 ? (1 + (((a) - 1) | (sizeof(uint32_t) - 1))) : sizeof(uint32_t))
 
 int
 sysctl_if_family_ids SYSCTL_HANDLER_ARGS /* XXX bad syntax! */
@@ -157,25 +165,31 @@ sysctl_if_family_ids SYSCTL_HANDLER_ARGS /* XXX bad syntax! */
 #pragma unused(oidp)
 #pragma unused(arg1)
 #pragma unused(arg2)
-       errno_t error = 0;
+       errno_t error = 0;
        struct net_str_id_entry *entry = NULL;
        struct if_family_id *iffmid = NULL;
        size_t max_size = 0;
-       
+
        lck_mtx_lock(net_str_id_lock);
        SLIST_FOREACH(entry, &net_str_id_list, nsi_next) {
                size_t str_size;
                size_t iffmid_size;
-               
-               if ((entry->nsi_flags & (1 << NSI_IF_FAM_ID)) == 0)
+
+               if ((entry->nsi_flags & (1 << NSI_IF_FAM_ID)) == 0) {
                        continue;
-               
-               str_size = strlen(entry->nsi_string) + 1;
+               }
+
+               str_size = strlen(entry->nsi_string);
+               if (str_size > NET_ID_STR_MAX_LEN) {
+                       str_size = NET_ID_STR_MAX_LEN;
+               }
+               str_size += 1; // make room for end-of-string
                iffmid_size = ROUNDUP32(offsetof(struct net_str_id_entry, nsi_string) + str_size);
 
                if (iffmid_size > max_size) {
-                       if (iffmid) 
+                       if (iffmid) {
                                _FREE(iffmid, M_TEMP);
+                       }
                        iffmid = _MALLOC(iffmid_size, M_TEMP, M_WAITOK);
                        if (iffmid == NULL) {
                                lck_mtx_unlock(net_str_id_lock);
@@ -186,20 +200,20 @@ sysctl_if_family_ids SYSCTL_HANDLER_ARGS /* XXX bad syntax! */
                }
 
                bzero(iffmid, iffmid_size);
-               iffmid->iffmid_len = iffmid_size;
+               iffmid->iffmid_len = (uint32_t)iffmid_size;
                iffmid->iffmid_id = entry->nsi_id;
                strlcpy(iffmid->iffmid_str, entry->nsi_string, str_size);
-        error = SYSCTL_OUT(req, iffmid, iffmid_size);
-        if (error) {
+               error = SYSCTL_OUT(req, iffmid, iffmid_size);
+               if (error) {
                        lck_mtx_unlock(net_str_id_lock);
                        goto done;
-        }
-               
+               }
        }
        lck_mtx_unlock(net_str_id_lock);
-       
+
 done:
-       if (iffmid) 
+       if (iffmid) {
                _FREE(iffmid, M_TEMP);
+       }
        return error;
 }