typedef enum { rfsYES, rfsNO, rfsONLY } RootFsOption;
struct MountInfo {
- char const * src;
- char const * dst;
- char const * type;
+ char * src;
+ char * dst;
+ char * name;
+ char * type;
unsigned long flag;
unsigned long xflag;
unsigned long mask;
bool mount_all;
RootFsOption rootfs;
+ char cur_dir_path[PATH_MAX];
int cur_dir_fd;
int cur_rootdir_fd;
};
#define OPTION_ROOTFS 1031
#define XFLAG_NOAUTO 0x01
+#define XFLAG_FILE 0x02
+#define XFLAG_NOMTAB 0x04
static struct option const
CMDLINE_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 {
{ "private", MS_PRIVATE, MS_PRIVATE, 0, false },
{ "slave", MS_SLAVE, MS_SLAVE, 0, false },
{ "shared", MS_SHARED, MS_SHARED, 0, false },
+ { "nomtab", 0, 0, XFLAG_NOMTAB, false },
};
int wrapper_exit_code = 1;
if (writeStrX(fd, mnt->src)==-1 ||
writeStrX(fd, " ")==-1 ||
writeStrX(fd, mnt->dst)==-1 ||
+ writeStrX(fd, mnt->xflag & XFLAG_FILE ? "/" : "")==-1 ||
+ writeStrX(fd, mnt->xflag & XFLAG_FILE ? mnt->name : "")==-1 ||
writeStrX(fd, " ")==-1 ||
writeStrX(fd, getType(mnt))==-1 ||
writeStrX(fd, " ")==-1 ||
}
argv[idx++] = mnt->src;
- argv[idx++] = ".";
+ argv[idx++] = mnt->name;
argv[idx] = 0;
pid = fork();
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)
}
static bool
-mountSingle(struct MountInfo const *mnt, struct Options const *opt)
+mountSingle(struct MountInfo const *mnt, struct Options *opt)
{
assert(mnt->dst!=0);
return false;
if (canHandleInternal(mnt)) {
- if (mount(mnt->src, ".",
+ if (mount(mnt->src, mnt->name,
mnt->type ? mnt->type : "",
mnt->flag, mnt->data_parsed)==-1) {
perror("secure-mount: mount()");
return false;
}
- if ((mnt->flag & MS_BIND) &&
- (mnt->flag & ~(MS_BIND|MS_REC))) {
+ if (strcmp(mnt->dst, "/") == 0) {
+ /* XXX: Hack */
+ if (chdir(opt->cur_dir_path) == -1) {
+ perror("secure-mount: chdir(.)");
+ return false;
+ }
+ close(opt->cur_dir_fd);
+ opt->cur_dir_fd = Eopen(".", O_RDONLY|O_DIRECTORY, 0);
+ Efcntl(opt->cur_dir_fd, F_SETFD, FD_CLOEXEC);
+ }
+ if (!vc_isSupported(vcFEATURE_BME) &&
+ (mnt->flag & MS_BIND) &&
+ (mnt->mask & ~(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, ".",
+ if (mount(mnt->src, mnt->name,
mnt->type ? mnt->type : "",
(mnt->flag | MS_REMOUNT), NULL) == -1 &&
errno != EBUSY) { /* Returned on older kernels */
else if (!callExternalMount(mnt))
return false;
- if (!opt->ignore_mtab &&
+ if (!opt->ignore_mtab && (mnt->xflag & XFLAG_NOMTAB)==0 &&
updateMtab(mnt, opt)==-1) {
WRITE_MSG(2, "Failed to update mtab-file\n");
// no error
info->flag = MS_NODEV;
info->mask = 0;
info->xflag = 0;
+ info->name = ".";
if (strcmp(info->type, "swap") ==0) return prIGNORE;
else if (strcmp(info->type, "none") ==0) info->type = 0;
Vwrite(fd, buf, len);
}
+static void
+adjustFileMount(struct MountInfo *mnt)
+{
+ char *buf = strrchr(mnt->dst, '/');
+
+ if (buf)
+ *buf++ = 0;
+
+ mnt->name = buf;
+ mnt->xflag |= XFLAG_FILE;
+}
static bool
-mountFstab(struct Options const *opt)
+mountFstab(struct Options *opt)
{
bool res = false;
int fd;
Echdir("/");
if (( is_rootfs && opt->rootfs==rfsNO) ||
(!is_rootfs && opt->rootfs==rfsONLY)) { /* ignore the entry */ }
- else if (!mountSingle(&mnt, opt)) {
- showFstabPosition(2, opt->fstab, line_nr, 1);
- WRITE_MSG(2, ": failed to mount fstab-entry\n");
+ else {
+ if (utilvserver_isFile(mnt.dst, 0))
+ adjustFileMount(&mnt);
+ if (!mountSingle(&mnt, opt)) {
+ showFstabPosition(2, opt->fstab, line_nr, 1);
+ WRITE_MSG(2, ": failed to mount fstab-entry\n");
+ }
}
break;
}
Efcntl(opt->cur_dir_fd, F_SETFD, FD_CLOEXEC);
Efcntl(opt->cur_rootdir_fd, F_SETFD, FD_CLOEXEC);
+
+ if (getcwd(opt->cur_dir_path, sizeof(opt->cur_dir_path)) == NULL) {
+ perror("secure-mount: getcwd()");
+ exit(wrapper_exit_code);
+ }
}
static RootFsOption
struct MountInfo mnt = {
.src = 0,
.dst = 0,
+ .name = ".",
.type = 0,
.flag = MS_NODEV,
.xflag = 0,
mnt.src = argv[optind++];
mnt.dst = argv[optind++];
- if (!mountSingle(&mnt, &opt)) return EXIT_FAILURE;
+ if (utilvserver_isFile(mnt.dst, 0))
+ adjustFileMount(&mnt);
+ if (!mountSingle(&mnt, &opt))
+ return EXIT_FAILURE;
return EXIT_SUCCESS;
}