aboutsummaryrefslogtreecommitdiffstats
path: root/net/tipc/ref.c
diff options
context:
space:
mode:
authorAllan Stephens <allan.stephens@windriver.com>2008-05-12 18:42:28 -0400
committerDavid S. Miller <davem@davemloft.net>2008-05-12 18:42:28 -0400
commit7ef43ebaa538e0cc9063cbf84593a05091bcace2 (patch)
treed2bac748f6620cc2f217672105918b2116f6c958 /net/tipc/ref.c
parent4e3e6dcb43c3669a8817cb3d0f920f91661afd98 (diff)
tipc: Fix race condition when creating socket or native port
This patch eliminates the (very remote) chance of a crash resulting from a partially initialized socket or native port unexpectedly receiving a message. Now, during the creation of a socket or native port, the underlying generic port's lock is not released until all initialization required to handle incoming messages has been done. Signed-off-by: Allan Stephens <allan.stephens@windriver.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/tipc/ref.c')
-rw-r--r--net/tipc/ref.c12
1 files changed, 8 insertions, 4 deletions
diff --git a/net/tipc/ref.c b/net/tipc/ref.c
index 89cbab24d08f..a101de86824d 100644
--- a/net/tipc/ref.c
+++ b/net/tipc/ref.c
@@ -142,9 +142,13 @@ void tipc_ref_table_stop(void)
142/** 142/**
143 * tipc_ref_acquire - create reference to an object 143 * tipc_ref_acquire - create reference to an object
144 * 144 *
145 * Return a unique reference value which can be translated back to the pointer 145 * Register an object pointer in reference table and lock the object.
146 * 'object' at a later time. Also, pass back a pointer to the lock protecting 146 * Returns a unique reference value that is used from then on to retrieve the
147 * the object, but without locking it. 147 * object pointer, or to determine that the object has been deregistered.
148 *
149 * Note: The object is returned in the locked state so that the caller can
150 * register a partially initialized object, without running the risk that
151 * the object will be accessed before initialization is complete.
148 */ 152 */
149 153
150u32 tipc_ref_acquire(void *object, spinlock_t **lock) 154u32 tipc_ref_acquire(void *object, spinlock_t **lock)
@@ -178,13 +182,13 @@ u32 tipc_ref_acquire(void *object, spinlock_t **lock)
178 ref = (next_plus_upper & ~index_mask) + index; 182 ref = (next_plus_upper & ~index_mask) + index;
179 entry->ref = ref; 183 entry->ref = ref;
180 entry->object = object; 184 entry->object = object;
181 spin_unlock_bh(&entry->lock);
182 *lock = &entry->lock; 185 *lock = &entry->lock;
183 } 186 }
184 else if (tipc_ref_table.init_point < tipc_ref_table.capacity) { 187 else if (tipc_ref_table.init_point < tipc_ref_table.capacity) {
185 index = tipc_ref_table.init_point++; 188 index = tipc_ref_table.init_point++;
186 entry = &(tipc_ref_table.entries[index]); 189 entry = &(tipc_ref_table.entries[index]);
187 spin_lock_init(&entry->lock); 190 spin_lock_init(&entry->lock);
191 spin_lock_bh(&entry->lock);
188 ref = tipc_ref_table.start_mask + index; 192 ref = tipc_ref_table.start_mask + index;
189 entry->ref = ref; 193 entry->ref = ref;
190 entry->object = object; 194 entry->object = object;