@@ -51,7 +51,7 @@ typedef struct FileOperations
ssize_t (*readlink)(FsContext *, const char *, char *, size_t);
int (*chmod)(FsContext *, const char *, FsCred *);
int (*chown)(FsContext *, const char *, FsCred *);
- int (*mknod)(FsContext *, const char *, mode_t, dev_t);
+ int (*mknod)(FsContext *, const char *, FsCred *);
int (*mksock)(FsContext *, const char *);
int (*utime)(FsContext *, const char *, const struct utimbuf *);
int (*remove)(FsContext *, const char *);
@@ -195,9 +195,39 @@ static int local_chmod(FsContext *fs_ctx, const char *path, FsCred *credp)
return -1;
}
-static int local_mknod(FsContext *ctx, const char *path, mode_t mode, dev_t dev)
+static int local_mknod(FsContext *fs_ctx, const char *path, FsCred *credp)
{
- return mknod(rpath(ctx, path), mode, dev);
+ int err = -1;
+ int serrno = 0;
+
+ /* Determine the security model */
+ if (fs_ctx->fs_sm == SM_MAPPED) {
+ err = mknod(rpath(fs_ctx, path), SM_LOCAL_MODE_BITS|S_IFREG, 0);
+ if (err == -1) {
+ return err;
+ }
+ local_set_xattr(rpath(fs_ctx, path), credp);
+ if (err == -1) {
+ serrno = errno;
+ goto err_end;
+ }
+ } else if (fs_ctx->fs_sm == SM_PASSTHROUGH) {
+ err = mknod(rpath(fs_ctx, path), credp->fc_mode, credp->fc_rdev);
+ if (err == -1) {
+ return err;
+ }
+ err = local_post_create_passthrough(fs_ctx, path, credp);
+ if (err == -1) {
+ serrno = errno;
+ goto err_end;
+ }
+ }
+ return err;
+
+err_end:
+ remove(rpath(fs_ctx, path));
+ errno = serrno;
+ return err;
}
static int local_mksock(FsContext *ctx2, const char *path)
@@ -160,9 +160,15 @@ static int v9fs_do_chmod(V9fsState *s, V9fsString *path, mode_t mode)
return s->ops->chmod(&s->ctx, path->data, &cred);
}
-static int v9fs_do_mknod(V9fsState *s, V9fsString *path, mode_t mode, dev_t dev)
+static int v9fs_do_mknod(V9fsState *s, V9fsCreateState *vs, mode_t mode,
+ dev_t dev)
{
- return s->ops->mknod(&s->ctx, path->data, mode, dev);
+ FsCred cred;
+ cred_init(&cred);
+ cred.fc_uid = vs->fidp->uid;
+ cred.fc_mode = mode;
+ cred.fc_rdev = dev;
+ return s->ops->mknod(&s->ctx, vs->fullname.data, &cred);
}
static int v9fs_do_mksock(V9fsState *s, V9fsString *path)
@@ -1825,10 +1831,10 @@ static void v9fs_create_post_lstat(V9fsState *s, V9fsCreateState *vs, int err)
}
nmode |= vs->perm & 0777;
- err = v9fs_do_mknod(s, &vs->fullname, nmode, makedev(major, minor));
+ err = v9fs_do_mknod(s, vs, nmode, makedev(major, minor));
v9fs_create_post_perms(s, vs, err);
} else if (vs->perm & P9_STAT_MODE_NAMED_PIPE) {
- err = v9fs_do_mknod(s, &vs->fullname, S_IFIFO | (vs->mode & 0777), 0);
+ err = v9fs_do_mknod(s, vs, S_IFIFO | (vs->perm & 0777), 0);
v9fs_post_create(s, vs, err);
} else if (vs->perm & P9_STAT_MODE_SOCKET) {
err = v9fs_do_mksock(s, &vs->fullname);