#include <sys/wait.h>
#include <libgen.h>
#include <signal.h>
+#include <stdlib.h>
#define ENSC_WRAPPERS_FCNTL 1
#define ENSC_WRAPPERS_UNISTD 1
unsigned long xflag;
unsigned long mask;
char * data;
+ char * data_parsed;
};
struct Options {
};
#ifndef MS_REC
-# define MS_REC 0x4000
+#define MS_REC 0x4000
+#endif
+#ifndef MS_UNBINDABLE
+#define MS_UNBINDABLE (1<<17)
+#endif
+#ifndef MS_PRIVATE
+#define MS_PRIVATE (1<<18)
+#endif
+#ifndef MS_SLAVE
+#define MS_SLAVE (1<<19)
+#endif
+#ifndef MS_SHARED
+#define MS_SHARED (1<<20)
#endif
static struct FstabOption {
unsigned long const xflag;
bool const is_dflt;
} const FSTAB_OPTIONS[] = {
- { "defaults", 0, (MS_RDONLY|MS_NOSUID|MS_NODEV|MS_NOEXEC|
+ { "defaults", MS_NODEV, (MS_RDONLY|MS_NOSUID|MS_NODEV|MS_NOEXEC|
MS_SYNCHRONOUS), 0, false },
{ "rbind", MS_BIND|MS_REC, MS_BIND|MS_REC, 0, false },
{ "bind", MS_BIND, MS_BIND, 0, false },
{ "noauto", 0, 0, XFLAG_NOAUTO, false },
{ "user", 0, 0, 0, false },
{ "nouser", 0, 0, 0, false },
+ { "rec", MS_REC, MS_REC, 0, false },
+ { "unbindable", MS_UNBINDABLE, MS_UNBINDABLE, 0, false },
+ { "private", MS_PRIVATE, MS_PRIVATE, 0, false },
+ { "slave", MS_SLAVE, MS_SLAVE, 0, false },
+ { "shared", MS_SHARED, MS_SHARED, 0, false },
};
int wrapper_exit_code = 1;
goto err0;
}
- if (flock(fd, LOCK_EX)==-1) {
- perror("secure-mount: flock()");
+ if (lockf(fd, F_LOCK, 0)==-1) {
+ perror("secure-mount: lockf()");
goto err1;
}
if (!mnt) return false;
else if ((mnt->flag & (MS_BIND|MS_MOVE))) return true;
+ else if ((mnt->flag & (MS_SHARED|MS_SLAVE|MS_PRIVATE|
+ MS_UNBINDABLE))) return true;
else if (mnt->type==0) return false;
for (i=FS+0; *i!=0; ++i)
if (canHandleInternal(mnt)) {
if (mount(mnt->src, ".",
mnt->type ? mnt->type : "",
- mnt->flag, mnt->data)==-1) {
+ mnt->flag, mnt->data_parsed)==-1) {
perror("secure-mount: mount()");
return false;
}
+ if ((mnt->flag & MS_BIND) &&
+ (mnt->flag & ~(MS_BIND|MS_REC))) {
+ /* This is needed to put us in the new mountpoint */
+ if (!secureChdir(mnt->dst, opt))
+ return false;
+ if (mount(mnt->src, ".",
+ mnt->type ? mnt->type : "",
+ (mnt->flag | MS_REMOUNT), NULL) == -1 &&
+ errno != EBUSY) { /* Returned on older kernels */
+ perror("secure-mount: mount()");
+ return false;
+ }
+ }
}
else if (!callExternalMount(mnt))
return false;
transformOptionList(struct MountInfo *info, size_t UNUSED *col)
{
char const * ptr = info->data;
+ char * data = malloc(strlen(info->data));
+ char * dst = data;
do {
char const * pos = strchr(ptr, ',');
info->mask |= opt->mask;
info->xflag |= opt->xflag;
}
+ else {
+ if (dst != data)
+ *(dst++) = ',';
+ strncpy(dst, ptr, pos-ptr);
+ dst += pos - ptr;
+ *dst = '\0';
+ }
if (*pos!='\0')
ptr = pos+1;
} while (*ptr!='\0');
+ info->data_parsed = data;
return true;
}
default :
WRITE_MSG(2, "Try '");
WRITE_STR(2, argv[0]);
- WRITE_MSG(2, " --help\" for more information.\n");
+ WRITE_MSG(2, " --help' for more information.\n");
return EXIT_FAILURE;
break;
}