Files
ESP32_Serial_Swiss_Army_Knife/tests/sdk_security_overrides/dhcp.c
T
Commander1024 c010e1a1d5 Apply Phase 9D security mitigations
- Add fail-closed wolfSSL small-math policy and vectors
- Backport DHCP, EMS, and X.509 allocation fixes
- Extend source override validation and operational documentation
2026-09-15 23:06:23 +02:00

79 lines
3.0 KiB
C

/* SPDX-License-Identifier: GPL-3.0-only */
#include <assert.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <sys/mman.h>
#include <unistd.h>
typedef uint8_t u8_t;
typedef uint16_t u16_t;
typedef int16_t s16_t;
typedef struct { uint32_t addr; } ip4_addr_t;
typedef struct { uint32_t client_address; bool renew; } dhcps_t;
struct dhcps_state { u8_t state; };
enum { DHCPS_STATE_IDLE, DHCPS_STATE_ACK, DHCPS_STATE_NAK, DHCPS_STATE_OFFER,
DHCPS_STATE_DECLINE, DHCPS_STATE_RELEASE };
/* SDK_DEFINES */
/* SDK_FUNCTIONS */
static unsigned cases;
static u8_t check(dhcps_t *ctx, const u8_t *data, size_t len)
{
size_t page = (size_t)sysconf(_SC_PAGESIZE);
u8_t *map = mmap(NULL, page * 2, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
assert(map != MAP_FAILED && len <= page);
assert(mprotect(map + page, page, PROT_NONE) == 0);
u8_t *input = map + page - len;
memcpy(input, data, len);
u8_t result = parse_options(ctx, input, (s16_t)len);
/* Upstream's pointer expressions stay within this larger backing object. */
u8_t padded[4096 + 258] = {0};
memcpy(padded, data, len);
assert(result == upstream_parse_options(ctx, padded, (s16_t)len));
assert(memcmp(input, data, len) == 0);
assert(munmap(map, page * 2) == 0);
cases++;
return result;
}
int main(void)
{
dhcps_t ctx = {.client_address = 0x04030201};
u8_t data[300] = {0};
assert(check(&ctx, data, 0) == DHCPS_STATE_IDLE);
for (unsigned code = 0; code < 256; code++) {
data[0] = code;
check(&ctx, data, 1);
for (unsigned length = 0; length < 256; length++) {
data[1] = length;
check(&ctx, data, 2);
check(&ctx, data, 2 + length);
if (length) check(&ctx, data, 1 + length);
}
}
memset(data, 0, sizeof(data));
assert(check(&ctx, data, sizeof(data)) == DHCPS_STATE_IDLE);
u8_t discover[] = {0, 0, 53, 1, 1, 255};
assert(check(&ctx, discover, sizeof(discover)) == DHCPS_STATE_OFFER);
u8_t request[] = {53, 1, 3, 50, 4, 0, 0, 0, 0, 255};
memcpy(request + 5, &ctx.client_address, 4);
assert(check(&ctx, request, sizeof(request)) == DHCPS_STATE_ACK);
request[5] ^= 1;
assert(check(&ctx, request, sizeof(request)) == DHCPS_STATE_NAK);
assert(check(&ctx, request, 3) == DHCPS_STATE_NAK);
ctx.renew = true;
assert(check(&ctx, request, 3) == DHCPS_STATE_ACK);
request[2] = 7;
assert(check(&ctx, request, 3) == DHCPS_STATE_RELEASE);
request[2] = 4;
assert(check(&ctx, request, 3) == DHCPS_STATE_DECLINE);
u8_t short_type[] = {53, 0, 255};
assert(check(&ctx, short_type, sizeof(short_type)) == DHCPS_STATE_IDLE);
for (unsigned len = 0; len < 4; len++) {
u8_t short_ip[] = {50, len, 1, 2, 3};
assert(check(&ctx, short_ip, len + 2) == DHCPS_STATE_IDLE);
}
u8_t end[] = {255, 53, 1, 1};
assert(check(&ctx, end, sizeof(end)) == DHCPS_STATE_IDLE);
printf("DHCP extracted parser: %u guard-page / upstream-equivalence cases PASS\n", cases);
}