cscg24-heap

CSCG 2024 Challenge 'Intro(ish) to heap 1 - Heap Leak'
git clone https://git.sinitax.com/sinitax/cscg24-heap
Log | Files | Refs | sfeed.txt

main.c (2408B)


      1// gcc -O0 -g main.c -o main
      2#include <stdio.h>
      3#include <stdlib.h>
      4#include <unistd.h>
      5#include <string.h>
      6
      7#define MAX_TASKS 25
      8#define TASK_NAME 0x90
      9
     10typedef struct Task
     11{
     12    char name[TASK_NAME];
     13} task_t;
     14
     15task_t *tasks[MAX_TASKS];
     16
     17long read_long()
     18{
     19    char buf[1024];
     20    char *end;
     21    long ret;
     22
     23    if (!fgets(buf, sizeof(buf), stdin))
     24    {
     25        puts("error reading stdin");
     26        exit(1);
     27    }
     28    ret = strtol(buf, &end, 10);
     29    if(end == buf){
     30        puts("not a number");
     31        exit(1);
     32    }
     33    return ret;
     34}
     35
     36void add_task()
     37{
     38    char *last_n;
     39
     40    for (int i = 0; i < MAX_TASKS; i++)
     41    {
     42        if (tasks[i])
     43        {
     44            continue;
     45        }
     46        tasks[i] = malloc(sizeof(task_t));
     47        printf("name? ");
     48        read(0, tasks[i]->name, TASK_NAME);
     49        last_n = strrchr(tasks[i]->name, '\n');
     50        if (last_n)
     51        {
     52            *last_n = 0;
     53        }
     54        return;
     55    }
     56    puts("too many tasks :(");
     57}
     58
     59void delete_task()
     60{
     61    long id;
     62
     63    printf("id? ");
     64    id = read_long();
     65    if (id >= MAX_TASKS)
     66    {
     67        puts("invalid id");
     68        return;
     69    }
     70    if (!tasks[id])
     71    {
     72        puts("task does not exist");
     73        return;
     74    }
     75    free(tasks[id]);
     76}
     77
     78void list_tasks()
     79{
     80    for (int i = 0; i < MAX_TASKS; i++)
     81    {
     82        if (!tasks[i])
     83        {
     84            continue;
     85        }
     86        printf("[%02d] %s\n", i, tasks[i]->name);
     87    }
     88}
     89
     90void execute()
     91{
     92    long address;
     93
     94    printf("address? ");
     95    address = read_long();
     96    printf("jumping to %p\n", (void *)address);
     97    ((void (*)(char *))address)("cat /flag");
     98}
     99
    100int menu()
    101{
    102    long choice;
    103    puts("---menu---");
    104    puts("[0] exit");
    105    puts("[1] add task");
    106    puts("[2] delete task");
    107    puts("[3] list tasks");
    108    puts("[4] execute");
    109
    110    printf("choice? ");
    111    choice = read_long();
    112    return choice;
    113}
    114
    115int main(int argc, char **argv)
    116{
    117    setvbuf(stdin, 0, _IONBF, 0);
    118    setvbuf(stdout, 0, _IONBF, 0);
    119    setvbuf(stderr, 0, _IONBF, 0);
    120    while (1)
    121    {
    122        switch (menu())
    123        {
    124        case 0:
    125            return 0;
    126        case 1:
    127            add_task();
    128            break;
    129        case 2:
    130            delete_task();
    131            break;
    132        case 3:
    133            list_tasks();
    134            break;
    135        case 4:
    136            execute();
    137            break;
    138        default:
    139            puts("choose wisely");
    140        }
    141    }
    142}