X-Git-Url: https://git.saurik.com/apple/xnu.git/blobdiff_plain/fe8ab488e9161c46dd9885d58fc52996dc0249ff..e8c3f78193f1895ea514044358b93b1add9322f3:/osfmk/ipc/ipc_entry.c diff --git a/osfmk/ipc/ipc_entry.c b/osfmk/ipc/ipc_entry.c index aabb15ada..facaf2af0 100644 --- a/osfmk/ipc/ipc_entry.c +++ b/osfmk/ipc/ipc_entry.c @@ -79,6 +79,7 @@ #include <ipc/ipc_table.h> #include <ipc/ipc_port.h> #include <string.h> +#include <sys/kdebug.h> /* * Routine: ipc_entry_lookup @@ -103,8 +104,9 @@ ipc_entry_lookup( if (index < space->is_table_size) { entry = &space->is_table[index]; if (IE_BITS_GEN(entry->ie_bits) != MACH_PORT_GEN(name) || - IE_BITS_TYPE(entry->ie_bits) == MACH_PORT_TYPE_NONE) + IE_BITS_TYPE(entry->ie_bits) == MACH_PORT_TYPE_NONE) { entry = IE_NULL; + } } else { entry = IE_NULL; @@ -189,10 +191,14 @@ ipc_entry_claim( assert(table->ie_next < space->is_table_size); /* - * Initialize the new entry. We need only - * increment the generation number and clear ie_request. + * Initialize the new entry: increment gencount and reset + * rollover point if it rolled over, and clear ie_request. */ - gen = IE_BITS_NEW_GEN(entry->ie_bits); + gen = ipc_entry_new_gen(entry->ie_bits); + if (__improbable(ipc_entry_gen_rolled(entry->ie_bits, gen))) { + ipc_entry_bits_t roll = ipc_space_get_rollpoint(space); + gen = ipc_entry_new_rollpoint(roll); + } entry->ie_bits = gen; entry->ie_request = IE_REQ_NONE; @@ -302,6 +308,9 @@ ipc_entry_alloc_name( mach_port_index_t index = MACH_PORT_INDEX(name); mach_port_gen_t gen = MACH_PORT_GEN(name); + if (index > ipc_table_max_entries()) + return KERN_NO_SPACE; + assert(MACH_PORT_VALID(name)); @@ -431,7 +440,7 @@ ipc_entry_dealloc( if ((index < size) && (entry == &table[index])) { assert(IE_BITS_GEN(entry->ie_bits) == MACH_PORT_GEN(name)); - entry->ie_bits &= IE_BITS_GEN_MASK; + entry->ie_bits &= (IE_BITS_GEN_MASK | IE_BITS_ROLL_MASK); entry->ie_next = table->ie_next; table->ie_next = index; space->is_table_free++; @@ -481,6 +490,14 @@ ipc_entry_modified( space->is_low_mod = index; if (index > space->is_high_mod) space->is_high_mod = index; + + KERNEL_DEBUG_CONSTANT( + MACHDBG_CODE(DBG_MACH_IPC,MACH_IPC_PORT_ENTRY_MODIFY) | DBG_FUNC_NONE, + space->is_task ? task_pid(space->is_task) : 0, + name, + entry->ie_bits, + 0, + 0); } #define IPC_ENTRY_GROW_STATS 1 @@ -608,14 +625,7 @@ ipc_entry_grow_table( return KERN_RESOURCE_SHORTAGE; } - /* initialize new entries (free chain in backwards order) */ - for (i = osize; i < size; i++) { - table[i].ie_object = IO_NULL; - table[i].ie_bits = IE_BITS_GEN_MASK; - table[i].ie_index = 0; - table[i].ie_next = i + 1; - } - table[size-1].ie_next = 0; + ipc_space_rand_freelist(space, table, osize, size); /* clear out old entries in new table */ memset((void *)table, 0, osize * sizeof(*table)); @@ -749,3 +759,29 @@ ipc_entry_grow_table( return KERN_SUCCESS; } + + +/* + * Routine: ipc_entry_name_mask + * Purpose: + * Ensure a mach port name has the default ipc entry + * generation bits set. This can be used to ensure that + * a name passed in by user space matches names generated + * by the kernel. + * Conditions: + * None. + * Returns: + * 'name' input with default generation bits masked or added + * as appropriate. + */ +mach_port_name_t +ipc_entry_name_mask(mach_port_name_t name) +{ +#ifndef NO_PORT_GEN + static mach_port_name_t null_name = MACH_PORT_MAKE(0, IE_BITS_GEN_MASK + IE_BITS_GEN_ONE); + return name | null_name; +#else + static mach_port_name_t null_name = MACH_PORT_MAKE(0, ~(IE_BITS_GEN_MASK + IE_BITS_GEN_ONE)); + return name & ~null_name; +#endif +}