static void sig_handler(int signal, siginfo_t *info, void *data) { uint32_t crc; test_msg("signo=%d si_code=%x\n", signal, info->si_code); if (test_go()) { pr_perror("The signal is received before unlocking"); return; } switch (signal) { case SIGCHLD: if ((info->si_code & CLD_EXITED) && (info->si_pid == child) && (info->si_status == 5)) numsig++; else { fail("Wrong siginfo"); exit(1); } return; } if (TESTSIG == signal || THREADSIG == signal) { siginfo_t *src; if (signal == TESTSIG) { src = &share_infos[share_nr]; share_nr++; } else if (getpid() == syscall(SYS_gettid)) { src = &self_infos[self_nr]; self_nr++; } else { src = &thread_infos[thread_nr]; thread_nr++; } crc = ~0; if (datachk((uint8_t *) &info->_sifields, sizeof(siginfo_t) - offsetof(siginfo_t, _sifields), &crc)) { fail("CRC mismatch\n"); return; } if (memcmp(info, src, sizeof(siginfo_t))) { fail("Source and received info are differ\n"); return; } numsig++; return; } pr_perror("Unexpected signal"); exit(1); }
static int check_shm_id(int id, size_t size) { uint8_t *mem; uint32_t crc = INIT_CRC; mem = shmat(id, NULL, 0); if (mem == (void *)-1) { pr_perror("Can't attach shm: %d", -errno); return -1; } crc = INIT_CRC; if (datachk(mem, size, &crc)) { fail("shmem data are corrupted"); return -1; } if (shmdt(mem) < 0) { pr_perror("Can't detach shm: %d", -errno); return -1; } return 0; }
int main(int argc, char ** argv) { void *m; uint32_t crc; int i; test_init(argc, argv); m = mmap(NULL, MEM_SIZE, PROT_WRITE | PROT_READ, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); if (m == MAP_FAILED) { fail(); return 1; } crc = ~0; datagen(m, MEM_SIZE, &crc); for (i = 0; i < MEM_SIZE / (1<<20); i++) if (mprotect(m + (lrand48() * PAGE_SIZE % MEM_SIZE), PAGE_SIZE, PROT_NONE)) { err("mprotect"); return 1; } test_daemon(); test_waitsig(); if (mprotect(m, MEM_SIZE, PROT_READ)) err("mprotect"); crc = ~0; if (datachk(m, MEM_SIZE, &crc)) fail("Mem corrupted"); else pass(); return 0; }
int main(int argc, char ** argv) { int fd; struct stat st; uint32_t crc; bool chk_hole = true; test_init(argc, argv); fd = open(filename, O_RDWR | O_CREAT | O_TRUNC, 0644); if (fd < 0) { pr_perror("can't open %s", filename); exit(1); } if (unlink(filename) < 0) { pr_perror("can't unlink %s", filename); goto failed; } crc = ~0; datagen(buf4k, BUFSIZE, &crc); if (pwrite(fd, buf4k, BUFSIZE, DATA1_OFF) != BUFSIZE) { pr_perror("can't write data1"); goto failed; } crc = ~0; datagen(buf4k, BUFSIZE, &crc); if (pwrite(fd, buf4k, BUFSIZE, DATA2_OFF) != BUFSIZE) { pr_perror("can't write data2"); goto failed; } if (ftruncate(fd, FILE_SIZE)) { pr_perror("Can't fixup file size"); goto failed; } if (lseek(fd, DATA1_OFF, SEEK_HOLE) != DATA1_OFF + BUFSIZE) { test_msg("Won't check for hole\n"); chk_hole = false; } test_daemon(); test_waitsig(); if (fstat(fd, &st) < 0) { fail("can't stat after"); goto failed; } if (st.st_size != FILE_SIZE) { fail("file size changed to %ld", (long)st.st_size); goto failed; } test_msg("Blocks %u OK\n", FILE_BLOCKS); /* Data 1 */ if (pread(fd, buf4k, BUFSIZE, DATA1_OFF) != BUFSIZE) { fail("pread1 fail"); goto failed; } crc = ~0; if (datachk(buf4k, BUFSIZE, &crc)) { fail("datachk1 fail"); goto failed; } test_msg("Data @%u OK\n", DATA1_BLK); /* Data 2 */ if (pread(fd, buf4k, BUFSIZE, DATA2_OFF) != BUFSIZE) { fail("pread2 fail"); goto failed; } crc = ~0; if (datachk(buf4k, BUFSIZE, &crc)) { fail("datachk2 fail"); goto failed; } test_msg("Data @%u OK\n", DATA2_BLK); /* Hole */ if (chk_hole) { #ifdef HEAD_HOLE if (lseek(fd, 0, SEEK_HOLE) != 0) { fail("hh not found"); goto failed; } test_msg("Head hole OK\n"); #endif if (lseek(fd, DATA1_OFF, SEEK_HOLE) != DATA1_OFF + BUFSIZE) { fail("mh not found"); goto failed; } test_msg("Mid hole OK\n"); #ifdef TAIL_HOLE if (lseek(fd, DATA2_OFF, SEEK_HOLE) != DATA2_OFF + BUFSIZE) { fail("tail hole not found"); goto failed; } test_msg("Tail hole OK\n"); #endif } close(fd); pass(); return 0; failed: close(fd); return 1; }
int main(int argc, char **argv) { unsigned char buf[BUF_SIZE]; int fd, fd_s; int status; pid_t pid; int res; uint32_t crc; struct sigaction sa = { .sa_handler = sig_hand, /* don't set SA_RESTART */ }; test_init(argc, argv); if ((fd_s = tcp_init_server(ZDTM_FAMILY, &port)) < 0) { err("initializing server failed"); return 1; } test_daemon(); test_waitsig(); sigemptyset(&sa.sa_mask); if (sigaction(SIGCHLD, &sa, NULL)) fprintf(stderr, "Can't set SIGTERM handler: %m\n"); pid = test_fork(); if (pid < 0) { err("fork failed. Return %d %m", pid); return 1; } if (pid == 0) { /* * Chiled is client of TCP connection */ close(fd_s); fd = tcp_init_client(ZDTM_FAMILY, "localhost", port); if (fd < 0) return 1; res = read(fd, buf, BUF_SIZE); close(fd); if (res != BUF_SIZE) { err("read less then have to: %d instead of %d", res, BUF_SIZE); return -1; } if (datachk(buf, BUF_SIZE, &crc)) return -2; return 0; } /* * parent is server of TCP connection */ fd = tcp_accept_server(fd_s); close(fd_s); if (fd < 0) { err("can't accept client connection %m"); goto error; } datagen(buf, BUF_SIZE, &crc); if (write(fd, buf, BUF_SIZE) < BUF_SIZE) { err("can't write"); goto error; } close(fd); if (wait(&status) < 0) { err("wait failed %m"); goto error; } if (WIFEXITED(status) && WEXITSTATUS(status) != 0) { err("chiled failed. Return %d", WEXITSTATUS(status)); return 1; } pass(); return 0; error: kill(pid, SIGKILL); wait(&status); return -1; }
int main(int argc, char **argv) { unsigned char buf[BUF_SIZE]; int fd, fd_s; pid_t extpid; uint32_t crc; int pfd[2]; int val; socklen_t optlen; if (pipe(pfd)) { err("pipe() failed"); return 1; } extpid = fork(); if (extpid < 0) { err("fork() failed"); return 1; } else if (extpid == 0) { test_ext_init(argc, argv); close(pfd[1]); if (read(pfd[0], &port, sizeof(port)) != sizeof(port)) { err("Can't read port\n"); return 1; } fd = tcp_init_client(ZDTM_FAMILY, "localhost", port); if (fd < 0) return 1; #ifdef STREAM while (1) { if (read_data(fd, buf, BUF_SIZE)) { err("read less then have to"); return 1; } if (datachk(buf, BUF_SIZE, &crc)) return 2; datagen(buf, BUF_SIZE, &crc); if (write_data(fd, buf, BUF_SIZE)) { err("can't write"); return 1; } } #else if (read_data(fd, buf, BUF_SIZE)) { err("read less then have to"); return 1; } if (datachk(buf, BUF_SIZE, &crc)) return 2; datagen(buf, BUF_SIZE, &crc); if (write_data(fd, buf, BUF_SIZE)) { err("can't write"); return 1; } #endif return 0; } test_init(argc, argv); if ((fd_s = tcp_init_server(ZDTM_FAMILY, &port)) < 0) { err("initializing server failed"); return 1; } close(pfd[0]); if (write(pfd[1], &port, sizeof(port)) != sizeof(port)) { err("Can't send port"); return 1; } close(pfd[1]); /* * parent is server of TCP connection */ fd = tcp_accept_server(fd_s); if (fd < 0) { err("can't accept client connection %m"); return 1; } val = 1; if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val))) { err("setsockopt"); return 1; } test_daemon(); #ifdef STREAM while (test_go()) { datagen(buf, BUF_SIZE, &crc); if (write_data(fd, buf, BUF_SIZE)) { err("can't write"); return 1; } if (read_data(fd, buf, BUF_SIZE)) { err("read less then have to"); return 1; } if (datachk(buf, BUF_SIZE, &crc)) return 2; } kill(extpid, SIGKILL); #else test_waitsig(); datagen(buf, BUF_SIZE, &crc); if (write_data(fd, buf, BUF_SIZE)) { err("can't write"); return 1; } if (read_data(fd, buf, BUF_SIZE)) { err("read less then have to"); return 1; } if (datachk(buf, BUF_SIZE, &crc)) return 2; #endif optlen = sizeof(val); if (getsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &val, &optlen)) { err("getsockopt"); return 1; } if (val != 1) { fail("SO_REUSEADDR are not set for %d\n", fd); return 1; } pass(); return 0; }
int main(int argc, char ** argv) { int fd; size_t fsize=1000; mode_t mode; uid_t uid; gid_t gid; uint8_t buf[fsize]; struct stat fst; uint32_t crc; #ifdef UNLINK_FSTAT04 char filename[PATH_MAX]; #endif test_init(argc, argv); #ifdef UNLINK_FSTAT04 snprintf(filename, sizeof(filename), "%s/test\\file'\n\"un%%linkfstat00", dirname); mkdir(dirname, 0700); #endif fd = open(filename, O_RDWR | O_CREAT | O_TRUNC, 0644); if (fd < 0) { pr_perror("can't open %s", filename); exit(1); } #ifdef UNLINK_FSTAT04 if (chmod(dirname, 0500)) { pr_perror("chmod"); exit(1); } #endif if (fstat(fd, &fst) < 0) { pr_perror("can't get file info %s before", filename); goto failed; } if (unlink(filename) < 0) { pr_perror("can't unlink %s", filename); goto failed; } /* Change file size */ if (fst.st_size != 0) { pr_perror("%s file size eq %d", fst.st_size); goto failed; } crc = ~0; datagen(buf, sizeof(buf), &crc); if (write(fd, buf, sizeof(buf)) != sizeof(buf)) { pr_perror("can't write %s", filename); goto failed; } /* Change file mode */ if ((fst.st_mode & S_IXOTH) == 0) mode = (fst.st_mode | S_IXOTH); else mode = (fst.st_mode ^ S_IXOTH); if (fchmod(fd, mode) < 0) { pr_perror("can't chmod %s", filename); goto failed; } if (getuid()) { uid = getuid(); gid = getgid(); } else { /* Change uid, gid */ if (fchown(fd, (uid = fst.st_uid + 1), (gid = fst.st_gid + 1)) < 0) { pr_perror("can't chown %s", filename); goto failed; } } if (lseek(fd, 0, SEEK_SET) != 0) { pr_perror("can't reposition to 0"); goto failed; } test_daemon(); test_waitsig(); if (fstat(fd, &fst) < 0) { pr_perror("can't get %s file info after", filename); goto failed; } /* Check file size */ if (fst.st_size != fsize) { fail("(via fstat): file size changed to %d", fst.st_size); goto failed; } fst.st_size = lseek(fd, 0, SEEK_END); if (fst.st_size != fsize) { fail("(via lseek): file size changed to %d", fst.st_size); goto failed; } /* Check mode */ if (fst.st_mode != mode) { fail("mode is changed to %o(%o)", fst.st_mode, mode); goto failed; } /* Check uid, gid */ if (fst.st_uid != uid || fst.st_gid != gid) { fail("u(g)id changed: uid=%d(%d), gid=%d(%d)", fst.st_uid, uid, fst.st_gid, gid); goto failed; } if (lseek(fd, 0, SEEK_SET) != 0) { pr_perror("can't reposition to 0"); goto failed; } if (read(fd, buf, sizeof(buf)) != sizeof(buf)) { fail("can't read %s: %m\n", filename); goto failed; } crc = ~0; if (datachk(buf, sizeof(buf), &crc)) { fail("CRC mismatch\n"); goto failed; } close(fd); pass(); return 0; failed: unlink(filename); close(fd); return 1; }
static int check_map(struct map *map) { int prot = PROT_WRITE | PROT_READ | PROT_EXEC; if (signal(SIGSEGV, segfault) == SIG_ERR) { fail("setting SIGSEGV handler failed: %m\n"); return -1; } if (!sigsetjmp(segv_ret, 1)) { uint32_t crc = ~0; if (datachk(map->ptr, ONE_MAP_SIZE, &crc)) /* perform read access */ if (!(map->flag & MAP_ANONYMOUS) || (map->prot & PROT_WRITE)) { /* anon maps could only be filled when r/w */ fail("CRC mismatch\n"); return -1; } /* prot |= PROT_READ// need barrier before this line, because compiler change order commands. I finded one method: look at next lines*/ } else prot &= PROT_WRITE | !PROT_READ | PROT_EXEC; if (signal(SIGSEGV, segfault) == SIG_ERR) { fail("setting SIGSEGV handler failed: %m\n"); return -1; } if (!sigsetjmp(segv_ret, 1)) { * (int *) (map->ptr) = 1234; /* perform write access */ } else prot &= !PROT_WRITE | PROT_READ | PROT_EXEC; if (signal(SIGSEGV, segfault) == SIG_ERR) { fail("restoring SIGSEGV handler failed: %m\n"); return -1; } if (!sigsetjmp(segv_ret, 1)) { if (map->prot & PROT_WRITE) { memcpy(map->ptr,test_func, getpagesize()); } else { if (!(map->flag & MAP_ANONYMOUS)) { lseek(map->fd,0,SEEK_SET); if (write(map->fd,test_func,check_map - test_func)<check_map - test_func) { err("failed to write %s: %m\n", map->filename); return -1; } } } if (!(map->flag & MAP_ANONYMOUS) || map->prot & PROT_WRITE) /* Function body has been copied into the mapping */ ((int (*)())map->ptr)(); /* perform exec access */ else /* No way to copy function body into mapping, * clear exec bit from effective protection */ prot &= PROT_WRITE | PROT_READ | !PROT_EXEC; } else prot &= PROT_WRITE | PROT_READ | !PROT_EXEC; if (signal(SIGSEGV, SIG_DFL) == SIG_ERR) { fail("restoring SIGSEGV handler failed: %m\n"); return -1; } return prot; }
int main(int argc, char ** argv) { int sock, acc_sock, ret; pid_t pid; uint32_t crc; uint8_t buf[1000]; test_init(argc, argv); sock = setup_srv_sock(); if (sock < 0) exit(1); pid = test_fork(); if (pid < 0) { pr_perror("can't fork"); exit(1); } if (pid == 0) { /* child writes to the unlinked socket and returns */ close(sock); sock = setup_clnt_sock(); if (sock < 0) _exit(1); test_waitsig(); crc = ~0; datagen(buf, sizeof(buf), &crc); if (write(sock, buf, sizeof(buf)) != sizeof(buf)) { pr_perror("can't write to socket"); exit(errno); } close(sock); exit(0); } acc_sock = accept(sock, NULL, NULL); if (acc_sock < 0) { pr_perror("can't accept() the connection on \"%s\"", filename); goto out_kill; } close(sock); sock = acc_sock; if (unlink(filename)) { pr_perror("can't unlink %s", filename); goto out_kill; } test_daemon(); test_waitsig(); if (kill(pid, SIGTERM)) { fail("terminating the child failed: %m\n"); goto out; } if (wait(&ret) != pid) { fail("wait() returned wrong pid %d: %m\n", pid); goto out; } if (WIFEXITED(ret)) { ret = WEXITSTATUS(ret); if (ret) { fail("child exited with nonzero code %d (%s)\n", ret, strerror(ret)); goto out; } } if (WIFSIGNALED(ret)) { fail("child exited on unexpected signal %d\n", WTERMSIG(ret)); goto out; } if (read(sock, buf, sizeof(buf)) != sizeof(buf)) { fail("can't read %s: %m\n", filename); goto out; } crc = ~0; if (datachk(buf, sizeof(buf), &crc)) { fail("CRC mismatch\n"); goto out; } if (close(sock)) { fail("close failed: %m\n"); goto out; } if (unlink(filename) != -1 || errno != ENOENT) { fail("file %s should have been deleted before migration: unlink: %m\n", filename); goto out; } pass(); out_kill: kill(pid, SIGTERM); out: close(sock); return 0; }
int main(int argc, char ** argv) { void *m, *m2; char path[PATH_MAX]; uint32_t crc; pid_t pid = -1; int status, fd; test_init(argc, argv); m = mmap(NULL, MEM_SIZE, PROT_WRITE | PROT_READ, MAP_SHARED | MAP_ANONYMOUS, -1, 0); if (m == MAP_FAILED) goto err; pid = test_fork(); if (pid < 0) { goto err; } else if (pid == 0) { crc = ~0; datagen(m + MEM_OFFSET, PAGE_SIZE, &crc); crc = ~0; datagen(m + MEM_OFFSET2, PAGE_SIZE, &crc); test_waitsig(); crc = ~0; status = datachk(m + MEM_OFFSET, PAGE_SIZE, &crc); if (status) return 1; crc = ~0; status = datachk(m + MEM_OFFSET2, PAGE_SIZE, &crc); if (status) return 1; crc = ~0; status = datachk(m + PAGE_SIZE, PAGE_SIZE, &crc); if (status) return 1; return 0; } snprintf(path, PATH_MAX, "/proc/self/map_files/%lx-%lx", (unsigned long) m, (unsigned long) m + MEM_SIZE); fd = open(path, O_RDWR); if (fd == -1) { err("Can't open file %s: %m", path); goto err; } m2 = mmap(NULL, PAGE_SIZE, PROT_WRITE | PROT_READ, MAP_SHARED, fd, MEM_OFFSET3); if (m2 == MAP_FAILED) { err("Can't map file %s", path); goto err; } close(fd); munmap(m, PAGE_SIZE); munmap(m + PAGE_SIZE * 10, PAGE_SIZE); munmap(m + MEM_OFFSET2, PAGE_SIZE); crc = ~0; datagen(m + PAGE_SIZE, PAGE_SIZE, &crc); crc = ~0; datagen(m2, PAGE_SIZE, &crc); test_daemon(); test_waitsig(); kill(pid, SIGTERM); wait(&status); if (WIFEXITED(status)) { if (WEXITSTATUS(status)) goto err; } else goto err; crc = ~0; if (datachk(m + MEM_OFFSET, PAGE_SIZE, &crc)) goto err; crc = ~0; if (datachk(m2, PAGE_SIZE, &crc)) goto err; pass(); return 0; err: if (waitpid(-1, NULL, WNOHANG) == 0) { kill(pid, SIGTERM); wait(NULL); } return 1; }
static int test_fn(int argc, char **argv) { key_t key; int sem, shm, pid1, pid2; int fail_count = 0; uint8_t *mem; uint32_t crc; int ret; key = ftok(argv[0], 822155650); if (key == -1) { pr_perror("Can't make key"); goto out; } sem = semget(key, 1, 0777 | IPC_CREAT | IPC_EXCL); if (sem == -1) { pr_perror("Can't get sem"); goto out; } if (semctl(sem, 0, SETVAL, 1) == -1) { pr_perror("Can't init sem"); fail_count++; goto out_sem; } shm = shmget(key, shmem_size, 0777 | IPC_CREAT | IPC_EXCL); if (shm == -1) { pr_perror("Can't get shm"); fail_count++; goto out_sem; } mem = shmat(shm, NULL, 0); if (mem == (void *)-1) { pr_perror("Can't attach shm"); fail_count++; goto out_shm; } poison_area((int *)mem); pid1 = test_fork(); if (pid1 == -1) { pr_perror("Can't fork 1st time"); goto out_shdt; } else if (pid1 == 0) exit(child(key)); pid2 = test_fork(); if (pid2 == -1) { pr_perror("Can't fork 2nd time"); fail_count++; goto out_child; } else if (pid2 == 0) exit(child(key)); test_daemon(); while (test_go()) { ret = semop(sem, &lock, 1); if (ret) { if (errno == EINTR) continue; fail_count++; fail("Error in semop lock"); break; } if (mem[0] != POISON) { crc = INIT_CRC; if (datachk(mem, shmem_size, &crc)) { fail_count++; fail("Semaphore protection is broken or " "shmem pages are messed"); semop(sem, &unlock, 1); break; } poison_area((int *)mem); } while ((ret = semop(sem, &unlock, 1)) && (errno == EINTR)); if (ret) { fail_count++; fail("Error in semop unlock"); break; } } test_waitsig(); kill(pid2, SIGTERM); waitpid(pid2, &ret, 0); if (!WIFEXITED(ret)) { fail_count++; pr_perror("Child 2 was killed"); } else if (WEXITSTATUS(ret)) { fail_count++; pr_perror("Child 2 couldn't inititalise"); } out_child: kill(pid1, SIGTERM); waitpid(pid1, &ret, 0); if (!WIFEXITED(ret)) { fail_count++; pr_perror("Child 1 was killed"); } else if (WEXITSTATUS(ret)) { fail_count++; pr_perror("Child 1 couldn't inititalise"); } out_shdt: shmdt(mem); out_shm: shmctl(shm, IPC_RMID, NULL); out_sem: semctl(sem, 1, IPC_RMID); if (fail_count == 0) pass(); out: return 0; }
int main(int argc, char ** argv) { int sock, acc_sock, ret; char path[256]; pid_t pid; uint32_t crc; uint8_t buf[1000]; test_init(argc, argv); if (snprintf(path, sizeof(path), "%s/foo", dirname) >= sizeof(path)) { err("directory name \"%s\"is too long", dirname); exit(1); } if (mkdir(dirname, 0700)) { err("can't make directory %s: %m\n", dirname); exit(1); } sock = setup_srv_sock(path); if (sock < 0) goto out; pid = fork(); if (pid < 0) { err("can't fork: %m\n"); goto out; } if (pid == 0) { /* child writes to the overmounted socket and returns */ close(sock); sock = setup_clnt_sock(path); if (sock < 0) _exit(1); test_waitsig(); crc = ~0; datagen(buf, sizeof(buf), &crc); if (write(sock, buf, sizeof(buf)) != sizeof(buf)) _exit(errno); close(sock); _exit(0); } acc_sock = accept(sock, NULL, NULL); if (acc_sock < 0) { err("can't accept() the connection on \"%s\": %m", path); goto out_kill; } close(sock); sock = acc_sock; if (mount("rien", dirname, "tmpfs", 0, 0) < 0) { err("can't mount tmpfs over %s: %m", dirname); goto out_kill; } test_daemon(); test_waitsig(); if (kill(pid, SIGTERM)) { fail("terminating the child failed: %m\n"); goto out; } if (wait(&ret) != pid) { fail("wait() returned wrong pid %d: %m\n", pid); goto out; } if (WIFEXITED(ret)) { ret = WEXITSTATUS(ret); if (ret) { fail("child exited with nonzero code %d (%s)\n", ret, strerror(ret)); goto out; } } if (WIFSIGNALED(ret)) { fail("child exited on unexpected signal %d\n", WTERMSIG(ret)); goto out; } if (read(sock, buf, sizeof(buf)) != sizeof(buf)) { fail("can't read %s: %m\n", path); goto out; } crc = ~0; if (datachk(buf, sizeof(buf), &crc)) { fail("CRC mismatch\n"); goto out; } if (umount(dirname) < 0) { fail("can't umount %s: %m", dirname); goto out; } if (close(sock) < 0) { fail("can't close %s: %m", path); goto out; } if (unlink(path) < 0) { fail("can't unlink %s: %m", path); goto out; } pass(); out_kill: kill(pid, SIGKILL); out: close(sock); unlink(path); rmdir(dirname); return 0; }
int main(int argc, char **argv) { key_t key; int shm; int fail_count = 0; int ret = -1; void *mem; uint32_t crc = INIT_CRC; test_init(argc, argv); key = ftok(argv[0], 822155666); if (key == -1) { pr_perror("Can't make key"); goto out; } shm = prepare_shm(key, shmem_size); if (shm == -1) { pr_perror("Can't prepare shm (1)"); goto out; } mem = shmat(shm, NULL, 0); if (mem == (void *)-1) { pr_perror("Can't shmat"); goto out; } test_daemon(); test_waitsig(); ret = check_shm_id(shm, shmem_size); if (ret < 0) { fail("ID check (1) failed\n"); fail_count++; goto out_shm; } ret = check_shm_key(key, shmem_size); if (ret < 0) { fail("KEY check failed\n"); fail_count++; goto out_shm; } if (datachk(mem, shmem_size, &crc)) { fail("shmem data is corrupted"); return -1; } if (shmdt(mem) < 0) { pr_perror("Can't detach shm"); return -1; } ret = shmctl(shm, IPC_RMID, NULL); if (ret < 0) { fail("Failed (1) to destroy segment: %d\n", -errno); fail_count++; goto out_shm; } /* * Code below checks that it's still possible to create new IPC SHM * segments */ shm = prepare_shm(key, shmem_size); if (shm == -1) { fail("Can't prepare shm (2)"); fail_count++; goto out; } ret = check_shm_id(shm, shmem_size); if (ret < 0) { fail("ID check (2) failed\n"); fail_count++; goto out_shm; } out_shm: ret = shmctl(shm, IPC_RMID, NULL); if (ret < 0) { fail("Failed (2) to destroy segment: %d\n", -errno); fail_count++; } if (fail_count == 0) pass(); out: return ret; }