mirror of
https://github.com/EchoStretch/kstuff-lite.git
synced 2026-10-22 11:42:38 -05:00
Fix fake key publication race
This commit is contained in:
1 parent
2c706656cf
commit
1e459b1cae
1 file changed
+13
-7
@@ -5,7 +5,8 @@
|
||||
extern struct
|
||||
{
|
||||
uint64_t bitmask;
|
||||
char pad[24];
|
||||
uint64_t ready_mask;
|
||||
char pad[16];
|
||||
char key_data[63][32];
|
||||
} shared_area;
|
||||
|
||||
@@ -21,7 +22,9 @@ int register_fake_key(const char key_data[32])
|
||||
}
|
||||
while(!__atomic_compare_exchange_n(&shared_area.bitmask, &mask, mask1, 1, __ATOMIC_RELEASE, __ATOMIC_ACQUIRE));
|
||||
int key_idx = 63 - __builtin_clzll(mask ^ mask1);
|
||||
uint64_t bit = 1ull << key_idx;
|
||||
memcpy(shared_area.key_data[key_idx], key_data, 32);
|
||||
__atomic_fetch_or(&shared_area.ready_mask, bit, __ATOMIC_RELEASE);
|
||||
return key_idx;
|
||||
}
|
||||
|
||||
@@ -29,15 +32,17 @@ int unregister_fake_key(int key_id)
|
||||
{
|
||||
if(key_id < 0 || key_id >= 63)
|
||||
return 0;
|
||||
uint64_t bit = 1ull << key_id;
|
||||
uint64_t mask, mask1;
|
||||
mask = __atomic_load_n(&shared_area.bitmask, __ATOMIC_ACQUIRE);
|
||||
mask = __atomic_load_n(&shared_area.ready_mask, __ATOMIC_ACQUIRE);
|
||||
do
|
||||
{
|
||||
if(!(mask & (1ull << key_id)))
|
||||
if(!(mask & bit))
|
||||
return 0;
|
||||
mask1 = mask & ~(1ull << key_id);
|
||||
mask1 = mask & ~bit;
|
||||
}
|
||||
while(!__atomic_compare_exchange_n(&shared_area.bitmask, &mask, mask1, 1, __ATOMIC_RELEASE, __ATOMIC_ACQUIRE));
|
||||
while(!__atomic_compare_exchange_n(&shared_area.ready_mask, &mask, mask1, 1, __ATOMIC_ACQ_REL, __ATOMIC_ACQUIRE));
|
||||
__atomic_fetch_and(&shared_area.bitmask, ~bit, __ATOMIC_RELEASE);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -45,8 +50,9 @@ int get_fake_key(int key_id, char key_data[32])
|
||||
{
|
||||
if(key_id < 0 || key_id >= 63)
|
||||
return 0;
|
||||
uint64_t mask = __atomic_load_n(&shared_area.bitmask, __ATOMIC_ACQUIRE);
|
||||
if(!(mask & (1ull << key_id)))
|
||||
uint64_t bit = 1ull << key_id;
|
||||
uint64_t mask = __atomic_load_n(&shared_area.ready_mask, __ATOMIC_ACQUIRE);
|
||||
if(!(mask & bit))
|
||||
return 0;
|
||||
memcpy(key_data, shared_area.key_data[key_id], 32);
|
||||
return 1;
|
||||
|
||||
Reference in new issue
Block a user