diff options
author | Jeff Garzik <jeff@garzik.org> | 2006-04-24 19:29:13 -0400 |
---|---|---|
committer | Jeff Garzik <jeff@garzik.org> | 2006-04-24 19:29:13 -0400 |
commit | d00dcb774440bbe1ea88cce69c5fd1cbf307aca5 (patch) | |
tree | 3e7d13dd8125a094c804aca7df527db317ee69c2 | |
parent | 1d897ec1409f8e4fff6db1261208f608cd45eddb (diff) | |
download | dbfs-d00dcb774440bbe1ea88cce69c5fd1cbf307aca5.tar.gz |
dbfs: validate mknod mode. extract inline code into helper dbfs_mode_type().
-rw-r--r-- | dbfs-backend.c | 36 | ||||
-rw-r--r-- | dbfs.c | 43 |
2 files changed, 65 insertions, 14 deletions
diff --git a/dbfs-backend.c b/dbfs-backend.c index c5db978..eea99d0 100644 --- a/dbfs-backend.c +++ b/dbfs-backend.c @@ -218,6 +218,26 @@ static int dbfs_inode_write(struct dbfs_inode *ino) return db_meta->get(db_meta, NULL, &key, &val, 0) ? -EIO : 0; } +static int dbfs_mode_type(guint32 mode, enum dbfs_inode_type *itype) +{ + if (S_ISDIR(mode)) + *itype = IT_DIR; + else if (S_ISCHR(mode) || S_ISBLK(mode)) + *itype = IT_DEV; + else if (S_ISFIFO(mode)) + *itype = IT_FIFO; + else if (S_ISLNK(mode)) + *itype = IT_SYMLINK; + else if (S_ISSOCK(mode)) + *itype = IT_SOCKET; + else if (S_ISREG(mode)) + *itype = IT_REG; + else + return -EINVAL; + + return 0; +} + int dbfs_inode_read(guint64 ino_n, struct dbfs_inode **ino_out) { int rc; @@ -254,20 +274,8 @@ int dbfs_inode_read(guint64 ino_n, struct dbfs_inode **ino_out) /* deduce inode type */ mode = GUINT32_FROM_LE(ino->raw_inode->mode); - if (S_ISDIR(mode)) - ino->type = IT_DIR; - else if (S_ISCHR(mode) || S_ISBLK(mode)) - ino->type = IT_DEV; - else if (S_ISFIFO(mode)) - ino->type = IT_FIFO; - else if (S_ISLNK(mode)) - ino->type = IT_SYMLINK; - else if (S_ISSOCK(mode)) - ino->type = IT_SOCKET; - else { - g_assert(S_ISREG(mode)); - ino->type = IT_REG; - } + rc = dbfs_mode_type(mode, &ino->type); + g_assert(rc == 0); *ino_out = ino; @@ -95,6 +95,43 @@ static void dbfs_op_readlink(fuse_req_t req, fuse_ino_t ino) free(val.data); } +static int dbfs_mode_validate(mode_t mode) +{ + unsigned int ifmt = mode & S_IFMT; + int rc = 0; + + if (S_ISREG(mode)) { + if (ifmt & ~S_IFREG) + rc = -EINVAL; + } + else if (S_ISDIR(mode)) { + if (ifmt & ~S_IFDIR) + rc = -EINVAL; + } + else if (S_ISCHR(mode)) { + if (ifmt & ~S_IFCHR) + rc = -EINVAL; + } + else if (S_ISBLK(mode)) { + if (ifmt & ~S_IFBLK) + rc = -EINVAL; + } + else if (S_ISFIFO(mode)) { + if (ifmt & ~S_IFIFO) + rc = -EINVAL; + } + else if (S_ISLNK(mode)) + rc = -EINVAL; + else if (S_ISSOCK(mode)) { + if (ifmt & ~S_IFSOCK) + rc = -EINVAL; + } + else + rc = -EINVAL; + + return rc; +} + static void dbfs_op_mknod(fuse_req_t req, fuse_ino_t parent, const char *name, mode_t mode, dev_t rdev) { @@ -102,6 +139,12 @@ static void dbfs_op_mknod(fuse_req_t req, fuse_ino_t parent, const char *name, struct dbfs_inode *ino; int rc; + rc = dbfs_mode_validate(mode); + if (rc) { + fuse_reply_err(req, rc); + return; + } + rc = dbfs_mknod(parent, name, mode, rdev, &ino); if (rc) { fuse_reply_err(req, rc); |