void sc_do_umount(const char *target, int flags) { char buf[10000] = { 0 }; const char *umount_cmd = NULL; if (sc_is_debug_enabled()) { #ifdef SNAP_CONFINE_DEBUG_BUILD umount_cmd = sc_umount_cmd(buf, sizeof(buf), target, flags); #else umount_cmd = use_debug_build; #endif debug("performing operation: %s", umount_cmd); } if (sc_faulty("umount", NULL) || umount2(target, flags) < 0) { // Save errno as ensure can clobber it. int saved_errno = errno; // Drop privileges so that we can compute our nice error message // without risking an attack on one of the string functions there. sc_privs_drop(); // Compute the equivalent umount command. umount_cmd = sc_umount_cmd(buf, sizeof(buf), target, flags); // Restore errno and die. errno = saved_errno; die("cannot perform operation: %s", umount_cmd); } }
void sc_do_mount(const char *source, const char *target, const char *fs_type, unsigned long mountflags, const void *data) { char buf[10000] = { 0 }; const char *mount_cmd = NULL; if (sc_is_debug_enabled()) { #ifdef SNAP_CONFINE_DEBUG_BUILD mount_cmd = sc_mount_cmd(buf, sizeof(buf), source, target, fs_type, mountflags, data); #else mount_cmd = use_debug_build; #endif debug("performing operation: %s", mount_cmd); } if (sc_faulty("mount", NULL) || mount(source, target, fs_type, mountflags, data) < 0) { // Save errno as ensure can clobber it. int saved_errno = errno; // Drop privileges so that we can compute our nice error message // without risking an attack on one of the string functions there. sc_privs_drop(); // Compute the equivalent mount command. mount_cmd = sc_mount_cmd(buf, sizeof(buf), source, target, fs_type, mountflags, data); // Restore errno and die. errno = saved_errno; die("cannot perform operation: %s", mount_cmd); } }
void debug(const char *msg, ...) { if (sc_is_debug_enabled()) { va_list va; va_start(va, msg); fprintf(stderr, "DEBUG: "); vfprintf(stderr, msg, va); fprintf(stderr, "\n"); va_end(va); } }
int main(int argc, char **argv) { if (sc_is_debug_enabled()) { for (int i = 0; i < argc; i++) { printf("-%s-\n", argv[i]); } } // signal gdb to stop here printf("\n\n"); printf("Welcome to `snap run --gdb`.\n"); printf("You are right before your application is execed():\n"); printf("- set any options you may need\n"); printf("- use 'cont' to start\n"); printf("\n\n"); raise(SIGTRAP); const char *executable = argv[1]; execv(executable, (char *const *)&argv[1]); perror("execv failed"); // very different exit code to make an execve failure easy to distinguish return 101; }
static bool sc_do_mount_ex(const char *source, const char *target, const char *fs_type, unsigned long mountflags, const void *data, bool optional) { char buf[10000] = { 0 }; const char *mount_cmd = NULL; if (sc_is_debug_enabled()) { #ifdef SNAP_CONFINE_DEBUG_BUILD mount_cmd = sc_mount_cmd(buf, sizeof(buf), source, target, fs_type, mountflags, data); #else mount_cmd = use_debug_build; #endif debug("performing operation: %s", mount_cmd); } if (sc_faulty("mount", NULL) || mount(source, target, fs_type, mountflags, data) < 0) { int saved_errno = errno; if (optional && saved_errno == ENOENT) { // The special-cased value that is allowed to fail. return false; } // Drop privileges so that we can compute our nice error message // without risking an attack on one of the string functions there. sc_privs_drop(); // Compute the equivalent mount command. mount_cmd = sc_mount_cmd(buf, sizeof(buf), source, target, fs_type, mountflags, data); // Restore errno and die. errno = saved_errno; die("cannot perform operation: %s", mount_cmd); } return true; }