Skip to content

Instantly share code, notes, and snippets.

@ayende

ayende/linux.c Secret

Created January 9, 2025 12:01
Show Gist options
  • Select an option

  • Save ayende/5fdb898301b4240436f08d711374c667 to your computer and use it in GitHub Desktop.

Select an option

Save ayende/5fdb898301b4240436f08d711374c667 to your computer and use it in GitHub Desktop.
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <linux/falloc.h>
#include <errno.h>
#include <string.h>
#include <sys/random.h>
#define MB (1024 * 1024)
void write_all(int fd, const void *buf, size_t count)
{
size_t bytes_written = 0;
const char *ptr = (const char *)buf;
while (bytes_written < count)
{
ssize_t result = write(fd, ptr + bytes_written, count - bytes_written);
if (result < 0)
{
if (errno == EINTR)
continue;
fprintf(stderr, "Write error: errno = %d (%s)\n", errno, strerror(errno));
exit(EXIT_FAILURE);
}
if (result == 0)
{
fprintf(stderr, "Zero len write is bad: errno = %d (%s)\n", errno, strerror(errno));
exit(EXIT_FAILURE);
}
bytes_written += result;
}
}
int main()
{
int fd;
char buffer[MB];
unlink("/mnt/ramdisk/fullfile");
unlink("/mnt/ramdisk/anotherfile");
getrandom(buffer, MB, 0);
ssize_t bytes_written;
fd = open("/mnt/ramdisk/fullfile", O_RDWR | O_CREAT | O_TRUNC, 0644);
if (fd == -1)
{
fprintf(stderr, "open full file: errno = %d (%s)\n", errno, strerror(errno));
exit(EXIT_FAILURE);
}
for (int i = 0; i < 32; i++)
{
write_all(fd, buffer, MB);
}
close(fd);
fd = open("/mnt/ramdisk/fullfile", O_RDWR);
if (fd == -1)
{
fprintf(stderr, "reopen full file: errno = %d (%s)\n", errno, strerror(errno));
exit(EXIT_FAILURE);
}
if (fallocate(fd, FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE, 12 * MB, 8 * MB) == -1)
{
fprintf(stderr, "fallocate failure: errno = %d (%s)\n", errno, strerror(errno));
exit(EXIT_FAILURE);
}
close(fd);
fd = open("/mnt/ramdisk/anotherfile", O_RDWR | O_CREAT | O_TRUNC, 0644);
if (fd == -1)
{
fprintf(stderr, "open another file: errno = %d (%s)\n", errno, strerror(errno));
exit(EXIT_FAILURE);
}
for (int i = 0; i < 4; i++)
{
write_all(fd, buffer, MB);
}
close(fd);
// Write 8 MB to the hole in the first file
fd = open("/mnt/ramdisk/fullfile", O_RDWR);
char *mapped_memory = mmap(NULL, 32 * MB, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
if (mapped_memory == MAP_FAILED)
{
fprintf(stderr, "fail mmap: errno = %d (%s)\n", errno, strerror(errno));
exit(EXIT_FAILURE);
}
for (size_t i = (12 * MB); i < (20 * MB); i++)
{
mapped_memory[i] = 1;
}
munmap(mapped_memory, 32 * MB);
close(fd);
printf("Operations completed successfully.\n");
return 0;
}
#include <stdio.h>
#include <windows.h>
#define MB (1024 * 1024)
int main() {
HANDLE hFile, hFile2;
DWORD bytesWritten;
LARGE_INTEGER fileSize, moveAmount;
char* buffer = malloc(MB);
int i;
DeleteFileA("R:\\original_file.bin");
DeleteFileA("R:\\another_file.bin");
hFile = CreateFileA("R:/original_file.bin", GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile == INVALID_HANDLE_VALUE) {
printf("Error creating file: %d\n", GetLastError());
exit(__LINE__);
}
for (int i = 0; i < 20; i++) {
if (!WriteFile(hFile, buffer, MB, &bytesWritten, NULL)) {
fprintf(stderr, "WriteFile failed on iteration %d: %x\n", i, GetLastError());
exit(__LINE__);
}
if (bytesWritten != MB) {
fprintf(stderr, "Failed to write full buffer on iteration %d\n", i);
exit(__LINE__);
}
}
if (!FlushFileBuffers(hFile)) {
fprintf(stderr, "Could not flush file buffers: %x\n", GetLastError());
exit(__LINE__);
}
FILE_ZERO_DATA_INFORMATION zeroDataInfo;
zeroDataInfo.FileOffset.QuadPart = 6 * MB;
zeroDataInfo.BeyondFinalZero.QuadPart = 18 * MB;
if (!DeviceIoControl(hFile, FSCTL_SET_SPARSE, NULL, 0, NULL, 0, NULL, NULL) ||
!DeviceIoControl(hFile, FSCTL_SET_ZERO_DATA, &zeroDataInfo, sizeof(zeroDataInfo), NULL, 0, NULL, NULL)) {
printf("Error setting zero data: %d\n", GetLastError());
exit(__LINE__);
}
if (!FlushFileBuffers(hFile)) {
fprintf(stderr, "Could not flush file buffers: %x\n", GetLastError());
exit(__LINE__);
}
// Create another file of size 4 MB
hFile2 = CreateFileA("R:/another_file.bin", GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile2 == INVALID_HANDLE_VALUE) {
printf("Error creating second file: %d\n", GetLastError());
exit(__LINE__);
}
for (int i = 0; i < 12; i++) {
if (!WriteFile(hFile2, buffer, MB, &bytesWritten, NULL)) {
fprintf(stderr, "WriteFile 2 failed on iteration %d: %x\n", i, GetLastError());
exit(__LINE__);
}
if (bytesWritten != MB) {
fprintf(stderr, "Failed to write full buffer 2 on iteration %d\n", i);
exit(__LINE__);
}
}
HANDLE hMapFile = CreateFileMapping(hFile, NULL, PAGE_READWRITE, 0, 0, NULL);
if (hMapFile == NULL) {
fprintf(stderr, "Could not create file mapping object: %x\n", GetLastError());
exit(__LINE__);
}
char* lpMapAddress = MapViewOfFile(hMapFile, FILE_MAP_WRITE, 0, 0, 0);
if (lpMapAddress == NULL) {
fprintf(stderr, "Could not map view of file: %x\n", GetLastError());
exit(__LINE__);
}
for (i = 6 * MB; i < 18 * MB; i++) {
((char*)lpMapAddress)[i]++;
}
if (!FlushViewOfFile(lpMapAddress, 0)) {
fprintf(stderr, "Could not flush view of file: %x\n", GetLastError());
exit(__LINE__);
}
if (!FlushFileBuffers(hFile)) {
fprintf(stderr, "Could not flush file buffers: %x\n", GetLastError());
exit(__LINE__);
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment