DragonFlyBSD Kernel Audit
DF-0046 / fix_test.c
← back to finding ↓ download raw
/* Supplementary test: verify SEMVMX is enforced on positive-op AND SETVAL. */
#include <sys/sem.h>
#include <sys/ipc.h>
#include <err.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>

#define SEMVMX 32767

int main(void) {
    int id = semget(IPC_PRIVATE, 1, 0600 | IPC_CREAT);
    if (id < 0) err(1, "semget");

    /* (1) positive-op: 0 -> 32767 (== SEMVMX, allowed), then +1 -> ERANGE */
    struct sembuf up1 = { 0, SEMVMX, 0 };
    struct sembuf up2 = { 0, 1, 0 };
    int r1 = semop(id, &up1, 1);
    int r2 = semop(id, &up2, 1);
    printf("[pos-op] +SEMVMX rc=%d; +1 rc=%d errno=%d (%s)\n",
        r1, r2, errno, r2 < 0 ? strerror(errno) : "OK");
    if (r2 < 0 && errno == ERANGE)
        printf("    -> FIX OK: positive-op enforces SEMVMX (ERANGE)\n");
    else
        printf("    -> BUG: no ERANGE\n");

    /* (2) SETVAL: set to SEMVMX (allowed), then SEMVMX+1 (ERANGE expected) */
    union semun { int val; } arg;
    arg.val = SEMVMX;
    int s1 = semctl(id, 0, SETVAL, arg);
    arg.val = SEMVMX + 1;
    int s2 = semctl(id, 0, SETVAL, arg);
    printf("[SETVAL] =SEMVMX rc=%d; =SEMVMX+1 rc=%d errno=%d (%s)\n",
        s1, s2, errno, s2 < 0 ? strerror(errno) : "OK");
    if (s2 < 0 && errno == ERANGE)
        printf("    -> FIX OK: SETVAL enforces SEMVMX (ERANGE)\n");
    else
        printf("    -> BUG: no ERANGE\n");

    /* (3) confirm normal small ops still work */
    struct sembuf down = { 0, -1, IPC_NOWAIT };
    int r3 = semop(id, &down, 1);
    printf("[smoke] -1 rc=%d semval=%d (should be SEMVMX-1=%d)\n",
        r3, semctl(id, 0, GETVAL), SEMVMX-1);

    semctl(id, 0, IPC_RMID);
    return 0;
}