- Add fail-closed wolfSSL small-math policy and vectors - Backport DHCP, EMS, and X.509 allocation fixes - Extend source override validation and operational documentation
79 lines
3.0 KiB
C
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);
|
|
}
|