Fix fake key publication race

This commit is contained in:
Roman Tarasov committed 2026-03-31 01:44:00 +03:00
1 parent 2c706656cf
commit 1e459b1cae
1 file changed
+13 -7
+13 -7
View File
@@ -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;