Untitled
unknown
plain_text
10 months ago
1.9 kB
16
Indexable
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#ifdef _WIN32
#include <io.h>
#define READ _read
#else
#include <unistd.h>
#define READ read
#endif
#define MAX_SIZE 128
int main(void) {
char buf[64];
char in[MAX_SIZE];
size_t safe_bytes = 0; /* final, validated copy length */
size_t inlen = 0;
/* ---- Read input safely and terminate ---- */
printf("Enter buffer contents:\n");
ssize_t got = READ(0, in, MAX_SIZE - 1);
if (got < 0) {
perror("read");
return 1;
}
in[got] = '\0';
/* ---- Ask user how many bytes (may be unsafe/tainted) ---- */
printf("Bytes to copy:\n");
unsigned long tmp = 0;
if (scanf("%lu", &tmp) != 1) {
fprintf(stderr, "Invalid number; defaulting to 0\n");
tmp = 0;
}
/* ---- Compute a SAFE, non-tainted length ----
We only trust the user value if it’s within BOTH bounds:
(1) available input length, (2) destination capacity - 1 (for NUL).
Otherwise we fall back to the strict safe cap. */
inlen = strnlen(in, MAX_SIZE);
if (tmp <= inlen && tmp <= sizeof(buf) - 1) {
safe_bytes = (size_t)tmp;
} else {
/* fallback: safest possible bounded copy */
safe_bytes = inlen;
if (safe_bytes > sizeof(buf) - 1) {
safe_bytes = sizeof(buf) - 1;
}
}
/* ---- Copy with bounds checking and NUL-termination ---- */
#ifdef _WIN32
/* MSVC’s checked runtime helps Fortify see the guard explicitly */
if (memcpy_s(buf, sizeof buf, in, safe_bytes) != 0) {
fprintf(stderr, "memcpy_s failed\n");
return 1;
}
#else
memcpy(buf, in, safe_bytes);
#endif
buf[safe_bytes] = '\0';
/* Optional: show result */
printf("Copied (%zu bytes): \"%s\"\n", safe_bytes, buf);
return 0;
}
Editor is loading...
Leave a Comment