aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJeff Garzik <jeff@garzik.org>2006-04-24 19:29:13 -0400
committerJeff Garzik <jeff@garzik.org>2006-04-24 19:29:13 -0400
commitd00dcb774440bbe1ea88cce69c5fd1cbf307aca5 (patch)
tree3e7d13dd8125a094c804aca7df527db317ee69c2
parent1d897ec1409f8e4fff6db1261208f608cd45eddb (diff)
downloaddbfs-d00dcb774440bbe1ea88cce69c5fd1cbf307aca5.tar.gz
dbfs: validate mknod mode. extract inline code into helper dbfs_mode_type().
-rw-r--r--dbfs-backend.c36
-rw-r--r--dbfs.c43
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;
diff --git a/dbfs.c b/dbfs.c
index 292dec2..981bf65 100644
--- a/dbfs.c
+++ b/dbfs.c
@@ -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);