Programação defensiva e memória
Format strings, memória e ROP, canários, taint, cópia segura, TOCTOU e mitigações.
Contratos e formato
- Valida no servidor tipo, tamanho, intervalo e significado. Cliente pode enviar pedidos sem formulário. Prefere permitidos a padrões proibidos; validação não separa dados de instruções.
- SQL usa parâmetros para valores; HTML exige codificação do contexto.
printf(entrada)deixa dados controlar a interpretação. Usaprintf("%s", entrada)para texto. Formato controlado pode levar a implementação a ler posições da pilha nesta máquina e expor segredos; analisa formato e canários em conjunto, sem promessa portátil.%slê string por ponteiro;%drecebeint;%nsem modificador recebeint *e guarda a contagem já impressa.printf("abc%n!", &n)guarda 3.
Limites e tipos
- Buffer de bytes guarda string até mais nulo. Comportamento fora dos limites é indefinido; não deduz vítima pela ordem das declarações.
- Para
nomeválido terminado em nulo, rejeita se não cabe:
if (n >= 8) return 0;
memcpy(buf, nome, n + 1);
- Conta bytes, não letras Unicode. Bloco binário exige comprimento explícito.
strncpypode não terminar e pode colidir identificadores.
| Erro | Regra |
|---|---|
| Heap overflow | Escrita além da alocação; adjacência não garantida. |
| Use-after-free | Uso após libertar é inválido; copiar ponteiro não prolonga vida. |
| Double free | Libertar duas vezes é inválido; anular um ponteiro não anula aliases. |
| Integer overflow | Rejeita quantidade > SIZE_MAX / sizeof(item) antes de multiplicar. |
| Leitura fora dos limites | Com índice com sinal exige 0 <= indice && indice < len. |
Valida comprimento contra bytes disponíveis antes de converter; 65540 em campo de 16 bits fica 4.
Pilha, ROP e canários
- Modelo x86 de 32 bits com frame pointer: pilha cresce para endereços menores; cópia avança para maiores. Com buffer de 12 bytes em
ebp-16e retorno emebp+4, o índice 20 atinge o retorno. Little-endian põe0x11223344como44 33 22 11. Depende da disposição dada.
ROP encadeia trechos existentes por ret; reutilizar funções completas é o caso simples.
Assume argumentos na pilha, sem canário e funções que não retiram argumentos. Não extrapola para x86-64.
- Canário deteta escritas que o atravessam. Terminador só trava primitivas de texto; cópia binária transporta nulos. Aleatório exige imprevisibilidade e sigilo; fuga nesta máquina pode revelá-lo.
- NX impede executar páginas de dados, não reutilização de código. ASLR dificulta endereços; fugas reduzem-no. CFI restringe desvios cobertos.
- Taint segue fontes externas até sinks; cópia propaga marca. Sanitização só vale para a condição do sink. Estática aproxima e pode falhar; dinâmica só vê caminhos executados.
TOCTOU
Verificar nome e abrir depois permite trocar o objeto. Abre com restrições, verifica pelo descritor e usa esse descritor. Repetir verificação pelo nome cria outro intervalo. Saldo exige atomicidade ou transação; mutex local não coordena outros processos.