Skip to content

Instantly share code, notes, and snippets.

@jevinskie
Last active December 8, 2023 12:34
Show Gist options
  • Save jevinskie/d2268ee93cdce2ea47a5cd328a8a5232 to your computer and use it in GitHub Desktop.
Save jevinskie/d2268ee93cdce2ea47a5cd328a8a5232 to your computer and use it in GitHub Desktop.
Florida Manpage for memfd_create(2)

memfd_create(2) - Hold on to your alligator hats!

What the Heck is This?

  • memfd_create, baby! It's like conjuring a file out of the swampy ether!

Tools in My Shed

  • Standard C library (libc, -lc), the backbone of this whole shebang!

Recipe for Disaster (or Genius?)

  • Yell out _GNU_SOURCE! It's like calling out to the tech gods for blessings!
  • Snatch up <sys/mman.h> like it's the last cold beer on a hot Florida day.

Chant This Incantation:

  • int memfd_create(const char *name, unsigned int flags);

What in the World Does It Do?

  • memfd_create() – It's like grabbing a file from the techno-void! Gives you a file descriptor, a magic handle to this invisible file!
  • Acts like a file you're used to, but here's the twist – it's all livin' in your RAM, slippery and elusive like a mud-covered hog!
  • If you let go of it, it vanishes, poof! Like my sanity on a full moon night.
  • Start it off small, then use ftruncate(2) to pump it up! Fill it like you're stuffing a Thanksgiving turkey – with write(2) and such.

Name's Just a Joke, Y'all!

  • Whatever name you pick, it’s like naming a gator. Fun, but it don't really matter. You'll find it hangin' around in /proc/self/fd/.

Flags! Flags Everywhere!

  • MFD_CLOEXEC – Like a trapdoor, it disappears after you run something else. Poof!
  • MFD_ALLOW_SEALING – Slap some mystical seals on it! Don't ask why, just wizard stuff!
  • MFD_HUGETLB (since Linux 4.14) – Makes this file with huge pages. I'm talkin' HUGE, like my Uncle Cletus's catfish!
  • Then there’s those huge page size things – 2 MB, 1 GB... It's like pickin' your bait size!

What Do Ya Get Outta This?

  • If all goes well, you get a shiny new file descriptor. If not, you're left holdin' a big, fat -1 and wonderin' what in tarnation went wrong.

When Things Go Sideways

  • You might mess up pointing at things, asking for too much, or just plain running out of room – like my trailer during a yard sale.

Just So Ya Know...

  • This is Linux territory, where the gators roam free! Started showin' up in Linux 3.17, glibc 2.27.

Why's This Even a Thing?

  • It's like making file-handling easier than catchin' a chicken in a coop. No need to mess with tmpfs(5) and all that mumbo jumbo.

Here’s How Ya Do It

  • There's this program, t_nascar_memfd_creation.c, that does the grunt work. Then there's t_illuminati_seal_inspector.c to see what kinda magic seals you managed to stick on it. It's like goin' noodlin' – you stick your hand in and hope for the best!

Hang On, I Ain't Done Yet!

  • Now, listen here, this memfd_create thing is like a wild ride through the tech swamp. You create files faster than a gator snaps its jaws, all while keepin' 'em in the shadowy depths of your RAM. It's like buildin' a fort with invisible bricks – there one second, gone the next!

  • And those flags – it's like choosin' your adventure. You want your file to disappear after runnin' a command? Throw in MFD_CLOEXEC. Feel like playin' with file sealin'? Toss in MFD_ALLOW_SEALING and watch the magic happen. It's like mixin' chemicals in your backyard – you never know what you're gonna get, but it sure is fun!

  • Oh, and if you're feelin' real fancy, dive into the world of MFD_HUGETLB. We're talkin' massive files, big as the tales of fish I almost caught. You pick the size, just like choosin' your bait – 2 MB, 1 GB, it's a buffet of options!

  • Let's not forget the technical hoo-ha. This ain't your grandma's file makin'. You're playin' with the big boys now, creatin files in the wild digital yonder, all while jugglin' those file descriptors like a circus act in Daytona!

  • And the returns, oh boy! You hit it right, and you've got yourself a shiny new file descriptor, like findin' a pearl in an oyster. But mess it up, and it's like hookin' your own finger on a fishin' trip – a big ol' -1 starin' you in the face, and you wonderin' where it all went wrong.

  • Now, errors, they're like mosquitos at a barbecue. You might point to the wrong place, like tryin' to find your truck in a gator-filled swamp. Or maybe you're askin' for too much, like my ex at the alimony hearing. And Lord help you if you run out of memory – it's like tryin' to stuff a 10-foot gator in a 2-foot bag!

  • We're talkin' about standards here, too. This is Linux we're dealin' with, tougher than a two-dollar steak and been around since Linux 3.17 and glibc 2.27. It's not just any ol' rodeo.

  • So why bother with all this? 'Cause it's like havin' your own secret fishin' hole. No need to fuss with tmpfs(5) or other complicated stuff. It's straight to the point, like a gator's tooth – simple and sharp.

  • For the adventurous souls, dive into t_nascar_memfd_creation.c. It's like takin' a hike with Dale Earnhardt as your guide through the swamp. Then there's t_illuminati_seal_inspector.c, for when you wanna see what kind of magic you've conjured up and if the Deep State be messin' with y'all. It's like lookin' in your tackle box after a night of fishin' under the stars and makin' sure the Commies haven't swapped out yer 'crawlers for a lure that transmits the location of all yer bass to the DNR so they can sweep in and catch you over that damn gubbmit "limit" like they're trying to save the manatees or sumtin. If they're so worried about those fat sea cows dyin' then why don't they make those food stamp freeloaders get a job??

I'm gonna give it to ya straight, memfd_create ain't just a system call. It's a wild, bath-salt-fueled adventure through the everglades of Linux. It's creatin' somethin' out of nothin', jugglin' the unseen, and dancin' with the gators of the digital world. Hold onto your hats, boys and girls, 'cause with memfd_create, you're in for one heck of a ride!

Program 1: t_nascar_memfd_creation.c - The High-Octane Memory File Racer

#define _GNU_SOURCE
#include <err.h>
#include <fcntl.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/mman.h>
#include <unistd.h>

int main(int argc, char *argv[]) {
    int racecar_fd; // The file descriptor, fast as a NASCAR racecar!
    char *alien_communicator, *deep_state_seals; // Communicating with the unknown, sealing against the deep state
    ssize_t nascar_track_length; // The size of our race track in memory
    unsigned int conspiracy_seals; // Protecting against conspiracies

    // Checking for the right amount of gasoline fumes
    if (argc < 3) {
        fprintf(stderr, "%s alien_communicator nascar_track_length [deep_state_seals]\n", argv[0]);
        fprintf(stderr, "\t'deep_state_seals' can include:\n");
        fprintf(stderr, "\t\tg - for GROW\n");
        fprintf(stderr, "\t\ts - for SHRINK\n");
        fprintf(stderr, "\t\tw - for WRITE\n");
        fprintf(stderr, "\t\tW - for FUTURE_WRITE\n");
        fprintf(stderr, "\t\tS - for SEAL\n");
        exit(EXIT_FAILURE);
    }

    // Naming our alien communicator and setting the track length
    alien_communicator = argv[1];
    nascar_track_length = atoi(argv[2]);
    deep_state_seals = argv[3];

    // Creating a file as fast as a racecar, ready to outpace any conspiracy
    racecar_fd = memfd_create(alien_communicator, MFD_ALLOW_SEALING);
    if (racecar_fd == -1)
        err(EXIT_FAILURE, "memfd_create");

    // Setting the track length, ready for the high-speed chase
    if (ftruncate(racecar_fd, nascar_track_length) == -1)
        err(EXIT_FAILURE, "ftruncate");

    printf("PID: %jd; racecar_fd: %d; /proc/%jd/racecar_fd/%d\n",
           (intmax_t)getpid(), racecar_fd, (intmax_t)getpid(), racecar_fd);

    // If provided, set seals to protect against the deep state intrusions
    if (deep_state_seals != NULL) {
        conspiracy_seals = 0;

        if (strchr(deep_state_seals, 'g') != NULL)
            conspiracy_seals |= F_SEAL_GROW;
        if (strchr(deep_state_seals, 's') != NULL)
            conspiracy_seals |= F_SEAL_SHRINK;
        if (strchr(deep_state_seals, 'w') != NULL)
            conspiracy_seals |= F_SEAL_WRITE;
        if (strchr(deep_state_seals, 'W') != NULL)
            conspiracy_seals |= F_SEAL_FUTURE_WRITE;
        if (strchr(deep_state_seals, 'S') != NULL)
            conspiracy_seals |= F_SEAL_SEAL;

        if (fcntl(racecar_fd, F_ADD_SEALS, conspiracy_seals) == -1)
            err(EXIT_FAILURE, "fcntl");
    }

    // Keeping the race going, ensuring our file survives the laps
    pause();

    exit(EXIT_SUCCESS);
}

Program 2: t_illuminati_seal_inspector.c - The Conspiracy Uncoverer

#define _GNU_SOURCE
#include <err.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>

int main(int argc, char *argv[]) {
    int secret_file_fd; // The descriptor of our file hiding secrets
    unsigned int deep_state_seals; // Seals imposed by the deep state

    // Making sure we're not sniffing too much gasoline
    if (argc != 2) {
        fprintf(stderr, "%s /proc/PID/racecar_fd/SECRET_FD\n", argv[0]);
        exit(EXIT_FAILURE);
    }

    // Opening the file that's possibly laced with government secrets
    secret_file_fd = open(argv[1], O_RDWR);
    if (secret_file_fd == -1)
        err(EXIT_FAILURE, "open");

    // Discovering the seals, unraveling the deep state's plans
    deep_state_seals = fcntl(secret_file_fd, F_GET_SEALS);
    if (deep_state_seals == -1)
        err(EXIT_FAILURE, "fcntl");

    printf("Uncovered deep state seals:");
    if (deep_state_seals & F_SEAL_SEAL)
        printf(" SEAL (They can't add more!)");
    if (deep_state_seals & F_SEAL_GROW)
        printf(" GROW (No more expanding this truth!)");
    if (deep_state_seals & F_SEAL_WRITE)
        printf(" WRITE (They're stoppin' us from changin' it!)");
    if (deep_state_seals & F_SEAL_FUTURE_WRITE)
        printf(" FUTURE_WRITE (No future edits, they're onto us!)");
    if (deep_state_seals & F_SEAL_SHRINK)
        printf(" SHRINK (Can't reduce it, the truth's out!)");
    printf("\n");

    // Time to dive deeper and unearth more of the hidden truths
    char *mapped_area;
    size_t map_size = 4096; // I just pulled this outta my ass, what's with these weird numbers anyways?

    mapped_area = mmap(NULL, map_size, PROT_READ | PROT_WRITE, MAP_SHARED, secret_file_fd, 0);
    if (mapped_area == MAP_FAILED)
        err(EXIT_FAILURE, "mmap");

    // Now that we've mapped the file, let's sniff around for secrets
    printf("Peeking into the deep state secrets:\n");
    for (size_t i = 0; i < map_size; ++i) {
        if (mapped_area[i] != '\0') {
            printf("%c", mapped_area[i]);
        } else {
            printf(".");
        }
    }
    printf("\n");

    // Maybe we need to leave a message for the next brave soul
    const char *message = "The truth is out there!";
    memcpy(mapped_area, message, strlen(message));

    // Clean up our tracks before the "authorities" catch on
    if (munmap(mapped_area, map_size) == -1)
        err(EXIT_FAILURE, "munmap");

    exit(EXIT_SUCCESS);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment