// // Cforall Version 1.0.0 Copyright (C) 2016 University of Waterloo // // The contents of this file are covered under the licence agreement in the // file "LICENCE" distributed with Cforall. // // dumpable.cfa -- Check if everything looks correctly set to dump core // // Author : Thierry Delisle // Created On : Wed Jan 05 13:53:22 2022 // Last Modified By : // Last Modified On : // Update Count : // #include #include #include #include extern "C" { #include #include #include #include #include #include #include } void check_ulimit() { struct rlimit rlp; getrlimit(RLIMIT_CORE, &rlp); if(rlp.rlim_cur < 536870912) { serr | "Soft core limit is less than ~500Mb: " | rlp.rlim_cur; } if(rlp.rlim_max < 536870912) { serr | "Hard core limit is less than ~500Mb: " | rlp.rlim_max; } } void check_permission() { { char myExe[PATH_MAX]; ssize_t n = readlink("/proc/self/exe", myExe, sizeof(myExe)); if (n < 0) { perror("readlink(/proc/self/exe) error"); return 1; } myExe[n] = '\0'; if(int r = access(myExe, F_OK); r != 0) serr | "Expected current executable does not exist!" | r | errno; if(int r = access(myExe, R_OK); r != 0) serr | "No read access for current executable" | r | errno; } { char myCwd[PATH_MAX]; if (getcwd(myCwd, sizeof(myCwd)) == 0p) { perror("getcwd() error"); return; } if(access(myCwd, F_OK) != 0) serr | "Expected current working directory does not exist!"; if(access(myCwd, R_OK) != 0) serr | "No read access for current working directory"; if(access(myCwd, W_OK) != 0) serr | "No write access for current working directory"; } } void check_free_space() { struct statvfs buf; if(statvfs(".", &buf) != 0) { perror("statvfs() error"); return; } uint64_t avail = buf.f_bavail; avail *= buf.f_bsize; if(avail < 536870912_l64u) { serr | "Available diskspace is less than ~500Mb: " | avail; } if(buf.f_favail < 10) { serr | "Available inodes is less than 10: " | buf.f_favail; } if(buf.f_flag & ST_RDONLY) { serr | "Filesystem is read only"; } } void check_noconflict() { char * name = "./core"; if(access("./core", F_OK) == 0) serr | "A file of the core name ('" | name | "') already exists"; } void check_dumpflag() { int r = prctl(PR_GET_DUMPABLE, 0, 0, 0, 0); if(r < 0) { perror("prctl(PR_GET_DUMPABLE) error"); return; } if(r != 1) serr | "dumpable attribute not set to 1 \"(SUID_DUMP_USER, process is dumpable)\", was" | r; } void check_core_pattern() { int ret; int cp = open("/proc/sys/kernel/core_pattern", 0, O_RDONLY); if(cp < 0) { perror("open(/proc/sys/kernel/core_pattern, O_RDONLY) error"); return; } try { const char * expected = "core\n"; const int sz = sizeof("core\n"); char buf[512]; ret = read(cp, buf, 512); if(ret < 0) { perror("first core pattern read error"); return; } ret = strncmp(expected, buf, sz - 1); if(ret != 0) { serr | "/proc/sys/kernel/core_pattern does not contain 'core', was:" | nl | nl | buf | nl | "Test script expect cores files to be dumped with name 'core' in current working directory." | nl | "Apport is not supported, it should be deactivated in /etc/default/apport for the test suite to work with core dumps."; return; } } finally { ret = close(cp); if(ret < 0) perror("close(/proc/sys/kernel/core_pattern) error"); } } int main() { check_ulimit(); check_permission(); check_free_space(); check_noconflict(); check_dumpflag(); check_core_pattern(); sout | "Done"; }