aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMiklos Szeredi <miklos@szeredi.hu>2004-04-09 17:48:32 +0000
committerMiklos Szeredi <miklos@szeredi.hu>2004-04-09 17:48:32 +0000
commitc26c14d8db2072ca1ddc9f9f3133edb3f1c564aa (patch)
tree5f56f38ae29277f1571436a1abda462a73cc539f
parent2ac5e2a5b478180633f1cff840c54383f41db604 (diff)
downloadlibfuse-c26c14d8db2072ca1ddc9f9f3133edb3f1c564aa.tar.gz
limit checking
-rw-r--r--ChangeLog4
-rw-r--r--include/linux/fuse.h4
-rw-r--r--kernel/dev.c124
-rw-r--r--kernel/dir.c141
-rw-r--r--kernel/file.c54
-rw-r--r--kernel/inode.c36
-rw-r--r--kernel/util.c6
7 files changed, 193 insertions, 176 deletions
diff --git a/ChangeLog b/ChangeLog
index d0c7061..3d78ca5 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+2004-04-09 Miklos Szeredi <mszeredi@inf.bme.hu>
+
+ * Check some limits so userspace won't get too big requests
+
2004-04-05 Miklos Szeredi <mszeredi@inf.bme.hu>
* Kill compile warning
diff --git a/include/linux/fuse.h b/include/linux/fuse.h
index 8467ed6..bee2930 100644
--- a/include/linux/fuse.h
+++ b/include/linux/fuse.h
@@ -123,6 +123,10 @@ enum fuse_opcode {
/* Conservative buffer size for the client */
#define FUSE_MAX_IN 8192
+#define FUSE_NAME_MAX 1024
+#define FUSE_SYMLINK_MAX 4096
+#define FUSE_XATTR_SIZE_MAX 4096
+
struct fuse_entry_out {
unsigned long ino; /* Inode number */
unsigned long generation; /* Inode generation: ino:gen must
diff --git a/kernel/dev.c b/kernel/dev.c
index d8535e7..afc9f4c 100644
--- a/kernel/dev.c
+++ b/kernel/dev.c
@@ -24,7 +24,7 @@ static struct fuse_req *request_new(void)
struct fuse_req *req;
req = (struct fuse_req *) kmem_cache_alloc(fuse_req_cachep, SLAB_NOFS);
- if(req) {
+ if (req) {
INIT_LIST_HEAD(&req->list);
req->issync = 0;
req->locked = 0;
@@ -46,7 +46,7 @@ static void request_free(struct fuse_req *req)
static int request_restartable(enum fuse_opcode opcode)
{
- switch(opcode) {
+ switch (opcode) {
case FUSE_LOOKUP:
case FUSE_GETATTR:
case FUSE_READLINK:
@@ -69,11 +69,11 @@ static void request_wait_answer(struct fuse_req *req)
spin_unlock(&fuse_lock);
intr = wait_event_interruptible(req->waitq, req->finished);
spin_lock(&fuse_lock);
- if(!intr)
+ if (!intr)
return;
/* Request interrupted... Wait for it to be unlocked */
- if(req->locked) {
+ if (req->locked) {
req->interrupted = 1;
spin_unlock(&fuse_lock);
wait_event(req->waitq, !req->locked);
@@ -83,7 +83,7 @@ static void request_wait_answer(struct fuse_req *req)
/* Operations which modify the filesystem cannot safely be
restarted, because it is uncertain whether the operation has
completed or not... */
- if(req->sent && !request_restartable(req->in->h.opcode))
+ if (req->sent && !request_restartable(req->in->h.opcode))
req->out->h.error = -EINTR;
else
req->out->h.error = -ERESTARTSYS;
@@ -92,7 +92,7 @@ static void request_wait_answer(struct fuse_req *req)
static int get_unique(struct fuse_conn *fc)
{
do fc->reqctr++;
- while(!fc->reqctr);
+ while (!fc->reqctr);
return fc->reqctr;
}
@@ -101,7 +101,7 @@ static void request_end(struct fuse_conn *fc, struct fuse_req *req)
{
fuse_reqend_t endfunc = req->end;
- if(!endfunc) {
+ if (!endfunc) {
wake_up(&req->waitq);
spin_unlock(&fuse_lock);
} else {
@@ -118,12 +118,12 @@ void request_send(struct fuse_conn *fc, struct fuse_in *in,
struct fuse_req *req;
out->h.error = -ERESTARTSYS;
- if(down_interruptible(&fc->outstanding))
+ if (down_interruptible(&fc->outstanding))
return;
out->h.error = -ENOMEM;
req = request_new();
- if(req) {
+ if (req) {
req->in = in;
req->out = out;
req->issync = 1;
@@ -131,7 +131,7 @@ void request_send(struct fuse_conn *fc, struct fuse_in *in,
spin_lock(&fuse_lock);
out->h.error = -ENOTCONN;
- if(fc->file) {
+ if (fc->file) {
in->h.unique = get_unique(fc);
list_add_tail(&req->list, &fc->pending);
wake_up(&fc->waitq);
@@ -148,7 +148,7 @@ void request_send(struct fuse_conn *fc, struct fuse_in *in,
static inline void destroy_request(struct fuse_req *req)
{
- if(req) {
+ if (req) {
kfree(req->in);
request_free(req);
}
@@ -162,14 +162,14 @@ int request_send_noreply(struct fuse_conn *fc, struct fuse_in *in)
struct fuse_req *req;
req = request_new();
- if(!req)
+ if (!req)
return -ENOMEM;
req->in = in;
req->issync = 0;
spin_lock(&fuse_lock);
- if(!fc->file) {
+ if (!fc->file) {
spin_unlock(&fuse_lock);
request_free(req);
return -ENOTCONN;
@@ -189,12 +189,12 @@ int request_send_nonblock(struct fuse_conn *fc, struct fuse_in *in,
BUG_ON(!end);
- if(down_trylock(&fc->outstanding))
+ if (down_trylock(&fc->outstanding))
return -EWOULDBLOCK;
err = -ENOMEM;
req = request_new();
- if(req) {
+ if (req) {
req->in = in;
req->out = out;
req->issync = 1;
@@ -203,7 +203,7 @@ int request_send_nonblock(struct fuse_conn *fc, struct fuse_in *in,
spin_lock(&fuse_lock);
err = -ENOTCONN;
- if(fc->file) {
+ if (fc->file) {
in->h.unique = get_unique(fc);
list_add_tail(&req->list, &fc->pending);
wake_up(&fc->waitq);
@@ -222,9 +222,9 @@ static void request_wait(struct fuse_conn *fc)
DECLARE_WAITQUEUE(wait, current);
add_wait_queue_exclusive(&fc->waitq, &wait);
- while(fc->sb != NULL && list_empty(&fc->pending)) {
+ while (fc->sb != NULL && list_empty(&fc->pending)) {
set_current_state(TASK_INTERRUPTIBLE);
- if(signal_pending(current))
+ if (signal_pending(current))
break;
spin_unlock(&fuse_lock);
@@ -238,12 +238,12 @@ static void request_wait(struct fuse_conn *fc)
static inline int copy_in_one(const void *src, size_t srclen, char **dstp,
size_t *dstlenp)
{
- if(*dstlenp < srclen) {
+ if (*dstlenp < srclen) {
printk("fuse_dev_read: buffer too small\n");
return -EINVAL;
}
- if(copy_to_user(*dstp, src, srclen))
+ if (srclen && copy_to_user(*dstp, src, srclen))
return -EFAULT;
*dstp += srclen;
@@ -259,13 +259,13 @@ static inline int copy_in_args(struct fuse_in *in, char *buf, size_t nbytes)
size_t orignbytes = nbytes;
err = copy_in_one(&in->h, sizeof(in->h), &buf, &nbytes);
- if(err)
+ if (err)
return err;
- for(i = 0; i < in->numargs; i++) {
+ for (i = 0; i < in->numargs; i++) {
struct fuse_in_arg *arg = &in->args[i];
err = copy_in_one(arg->value, arg->size, &buf, &nbytes);
- if(err)
+ if (err)
return err;
}
@@ -281,21 +281,21 @@ static ssize_t fuse_dev_read(struct file *file, char *buf, size_t nbytes,
spin_lock(&fuse_lock);
request_wait(fc);
- if(fc->sb != NULL && !list_empty(&fc->pending)) {
+ if (fc->sb != NULL && !list_empty(&fc->pending)) {
req = list_entry(fc->pending.next, struct fuse_req, list);
list_del_init(&req->list);
req->locked = 1;
}
spin_unlock(&fuse_lock);
- if(fc->sb == NULL)
+ if (fc->sb == NULL)
return -ENODEV;
- if(req == NULL)
+ if (req == NULL)
return -EINTR;
ret = copy_in_args(req->in, buf, nbytes);
spin_lock(&fuse_lock);
- if(req->issync) {
- if(ret < 0) {
+ if (req->issync) {
+ if (ret < 0) {
req->out->h.error = -EPROTO;
req->finished = 1;
} else {
@@ -303,7 +303,7 @@ static ssize_t fuse_dev_read(struct file *file, char *buf, size_t nbytes,
req->sent = 1;
}
req->locked = 0;
- if(ret < 0 || req->interrupted)
+ if (ret < 0 || req->interrupted)
/* Unlocks fuse_lock: */
request_end(fc, req);
else
@@ -323,7 +323,7 @@ static struct fuse_req *request_find(struct fuse_conn *fc, unsigned int unique)
list_for_each(entry, &fc->processing) {
struct fuse_req *tmp;
tmp = list_entry(entry, struct fuse_req, list);
- if(tmp->in->h.unique == unique) {
+ if (tmp->in->h.unique == unique) {
req = tmp;
break;
}
@@ -343,18 +343,16 @@ static inline int copy_out_one(struct fuse_out_arg *arg, const char **srcp,
size_t *srclenp, int allowvar)
{
size_t dstlen = arg->size;
- if(*srclenp < dstlen) {
- if(!allowvar) {
+ if (*srclenp < dstlen) {
+ if (!allowvar) {
printk("fuse_dev_write: write is short\n");
return -EINVAL;
}
dstlen = *srclenp;
}
- if(dstlen) {
- if(copy_from_user(arg->value, *srcp, dstlen))
- return -EFAULT;
- }
+ if (dstlen && copy_from_user(arg->value, *srcp, dstlen))
+ return -EFAULT;
*srcp += dstlen;
*srclenp -= dstlen;
@@ -372,23 +370,23 @@ static inline int copy_out_args(struct fuse_out *out, const char *buf,
buf += sizeof(struct fuse_out_header);
nbytes -= sizeof(struct fuse_out_header);
- if(!out->h.error) {
- for(i = 0; i < out->numargs; i++) {
+ if (!out->h.error) {
+ for (i = 0; i < out->numargs; i++) {
struct fuse_out_arg *arg = &out->args[i];
int allowvar;
- if(out->argvar && i == out->numargs - 1)
+ if (out->argvar && i == out->numargs - 1)
allowvar = 1;
else
allowvar = 0;
err = copy_out_one(arg, &buf, &nbytes, allowvar);
- if(err)
+ if (err)
return err;
}
}
- if(nbytes != 0) {
+ if (nbytes != 0) {
printk("fuse_dev_write: write is long\n");
return -EINVAL;
}
@@ -399,12 +397,12 @@ static inline int copy_out_args(struct fuse_out *out, const char *buf,
static inline int copy_out_header(struct fuse_out_header *oh, const char *buf,
size_t nbytes)
{
- if(nbytes < sizeof(struct fuse_out_header)) {
+ if (nbytes < sizeof(struct fuse_out_header)) {
printk("fuse_dev_write: write is short\n");
return -EINVAL;
}
- if(copy_from_user(oh, buf, sizeof(struct fuse_out_header)))
+ if (copy_from_user(oh, buf, sizeof(struct fuse_out_header)))
return -EFAULT;
return 0;
@@ -425,8 +423,8 @@ static int fuse_invalidate(struct fuse_conn *fc, struct fuse_user_header *uh)
{
struct inode *inode = iget(fc->sb, uh->ino);
int err = -ENOENT;
- if(inode) {
- if(inode->u.generic_ip) {
+ if (inode) {
+ if (inode->u.generic_ip) {
invalidate_inode_pages(inode);
err = 0;
}
@@ -447,10 +445,10 @@ static int fuse_user_request(struct fuse_conn *fc, const char *buf,
return -EINVAL;
}
- if(copy_from_user(&uh, buf, sizeof(struct fuse_out_header)))
+ if (copy_from_user(&uh, buf, sizeof(struct fuse_out_header)))
return -EFAULT;
- switch(uh.opcode) {
+ switch (uh.opcode) {
case FUSE_INVALIDATE:
err = fuse_invalidate(fc, &uh);
break;
@@ -470,11 +468,11 @@ static ssize_t fuse_dev_write(struct file *file, const char *buf,
struct fuse_req *req;
struct fuse_out_header oh;
- if(!fc->sb)
+ if (!fc->sb)
return -EPERM;
err = copy_out_header(&oh, buf, nbytes);
- if(err)
+ if (err)
return err;
if (!oh.unique) {
@@ -489,23 +487,23 @@ static ssize_t fuse_dev_write(struct file *file, const char *buf,
spin_lock(&fuse_lock);
req = request_find(fc, oh.unique);
- if(req != NULL) {
+ if (req != NULL) {
list_del_init(&req->list);
req->locked = 1;
}
spin_unlock(&fuse_lock);
- if(!req)
+ if (!req)
return -ENOENT;
req->out->h = oh;
err = copy_out_args(req->out, buf, nbytes);
spin_lock(&fuse_lock);
- if(err)
+ if (err)
req->out->h.error = -EPROTO;
else {
/* fget() needs to be done in this context */
- if(req->in->h.opcode == FUSE_GETDIR && !oh.error)
+ if (req->in->h.opcode == FUSE_GETDIR && !oh.error)
process_getdir(req);
}
req->finished = 1;
@@ -514,7 +512,7 @@ static ssize_t fuse_dev_write(struct file *file, const char *buf,
request_end(fc, req);
out:
- if(!err)
+ if (!err)
return nbytes;
else
return err;
@@ -526,7 +524,7 @@ static unsigned int fuse_dev_poll(struct file *file, poll_table *wait)
struct fuse_conn *fc = DEV_FC(file);
unsigned int mask = POLLOUT | POLLWRNORM;
- if(!fc->sb)
+ if (!fc->sb)
return -EPERM;
poll_wait(file, &fc->waitq, wait);
@@ -544,7 +542,7 @@ static struct fuse_conn *new_conn(void)
struct fuse_conn *fc;
fc = kmalloc(sizeof(*fc), GFP_KERNEL);
- if(fc != NULL) {
+ if (fc != NULL) {
fc->sb = NULL;
fc->file = NULL;
fc->flags = 0;
@@ -563,7 +561,7 @@ static int fuse_dev_open(struct inode *inode, struct file *file)
struct fuse_conn *fc;
fc = new_conn();
- if(!fc)
+ if (!fc)
return -ENOMEM;
fc->file = file;
@@ -574,11 +572,11 @@ static int fuse_dev_open(struct inode *inode, struct file *file)
static void end_requests(struct fuse_conn *fc, struct list_head *head)
{
- while(!list_empty(head)) {
+ while (!list_empty(head)) {
struct fuse_req *req;
req = list_entry(head->next, struct fuse_req, list);
list_del_init(&req->list);
- if(req->issync) {
+ if (req->issync) {
req->out->h.error = -ECONNABORTED;
req->finished = 1;
/* Unlocks fuse_lock: */
@@ -628,17 +626,17 @@ int fuse_dev_init()
fuse_req_cachep = kmem_cache_create("fuser_request",
sizeof(struct fuse_req),
0, 0, NULL, NULL);
- if(!fuse_req_cachep)
+ if (!fuse_req_cachep)
return -ENOMEM;
proc_fs_fuse = proc_mkdir("fuse", proc_root_fs);
- if(proc_fs_fuse) {
+ if (proc_fs_fuse) {
struct proc_dir_entry *de;
proc_fs_fuse->owner = THIS_MODULE;
proc_fuse_dev = create_proc_entry("dev", S_IFSOCK | 0666,
proc_fs_fuse);
- if(proc_fuse_dev) {
+ if (proc_fuse_dev) {
proc_fuse_dev->owner = THIS_MODULE;
proc_fuse_dev->proc_fops = &fuse_dev_operations;
}
@@ -653,7 +651,7 @@ int fuse_dev_init()
void fuse_dev_cleanup()
{
- if(proc_fs_fuse) {
+ if (proc_fs_fuse) {
remove_proc_entry("dev", proc_fs_fuse);
remove_proc_entry("version", proc_fs_fuse);
remove_proc_entry("fuse", proc_root_fs);
diff --git a/kernel/dir.c b/kernel/dir.c
index d5d79b1..73f8043 100644
--- a/kernel/dir.c
+++ b/kernel/dir.c
@@ -27,7 +27,7 @@ static struct dentry_operations fuse_dentry_operations;
static void change_attributes(struct inode *inode, struct fuse_attr *attr)
{
- if(S_ISREG(inode->i_mode) && i_size_read(inode) != attr->size) {
+ if (S_ISREG(inode->i_mode) && i_size_read(inode) != attr->size) {
#ifdef KERNEL_2_6
invalidate_inode_pages(inode->i_mapping);
#else
@@ -60,19 +60,19 @@ static void fuse_init_inode(struct inode *inode, struct fuse_attr *attr)
{
inode->i_mode = attr->mode & S_IFMT;
i_size_write(inode, attr->size);
- if(S_ISREG(inode->i_mode)) {
+ if (S_ISREG(inode->i_mode)) {
inode->i_op = &fuse_file_inode_operations;
fuse_init_file_inode(inode);
}
- else if(S_ISDIR(inode->i_mode)) {
+ else if (S_ISDIR(inode->i_mode)) {
inode->i_op = &fuse_dir_inode_operations;
inode->i_fop = &fuse_dir_operations;
}
- else if(S_ISLNK(inode->i_mode)) {
+ else if (S_ISLNK(inode->i_mode)) {
inode->i_op = &fuse_symlink_inode_operations;
}
- else if(S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode) ||
- S_ISFIFO(inode->i_mode) || S_ISSOCK(inode->i_mode)){
+ else if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode) ||
+ S_ISFIFO(inode->i_mode) || S_ISSOCK(inode->i_mode)){
inode->i_op = &fuse_file_inode_operations;
init_special_inode(inode, inode->i_mode,
new_decode_dev(attr->rdev));
@@ -88,11 +88,11 @@ struct inode *fuse_iget(struct super_block *sb, ino_t ino, int generation,
struct inode *inode;
inode = iget(sb, ino);
- if(inode) {
- if(!inode->u.generic_ip) {
+ if (inode) {
+ if (!inode->u.generic_ip) {
inode->i_generation = generation;
fuse_init_inode(inode, attr);
- } else if(inode->i_generation != generation)
+ } else if (inode->i_generation != generation)
printk("fuse_iget: bad generation for ino %lu\n", ino);
change_attributes(inode, attr);
@@ -109,6 +109,10 @@ static int fuse_do_lookup(struct inode *dir, struct dentry *entry,
struct fuse_in in = FUSE_IN_INIT;
struct fuse_out out = FUSE_OUT_INIT;
+
+ if (entry->d_name.len > FUSE_NAME_MAX)
+ return -ENAMETOOLONG;
+
in.h.opcode = FUSE_LOOKUP;
in.h.ino = dir->i_ino;
in.numargs = 1;
@@ -127,7 +131,7 @@ static inline unsigned long time_to_jiffies(unsigned long sec,
unsigned long nsec)
{
/* prevent wrapping of jiffies */
- if(sec + 1 >= LONG_MAX / HZ)
+ if (sec + 1 >= LONG_MAX / HZ)
return 0;
return jiffies + sec * HZ + nsec / (1000000000 / HZ);
@@ -142,12 +146,12 @@ static int fuse_lookup_iget(struct inode *dir, struct dentry *entry,
struct inode *inode = NULL;
err = fuse_do_lookup(dir, entry, &outarg, &version);
- if(!err) {
+ if (!err) {
inode = fuse_iget(dir->i_sb, outarg.ino, outarg.generation,
&outarg.attr, version);
- if(!inode)
+ if (!inode)
return -ENOMEM;
- } else if(err != -ENOENT)
+ } else if (err != -ENOENT)
return err;
entry->d_time = time_to_jiffies(outarg.entry_valid,
@@ -164,11 +168,11 @@ static int lookup_new_entry(struct inode *dir, struct dentry *entry,
struct inode *inode;
inode = fuse_iget(dir->i_sb, outarg->ino, outarg->generation,
&outarg->attr, version);
- if(!inode)
+ if (!inode)
return -ENOMEM;
/* Don't allow userspace to do really stupid things... */
- if((inode->i_mode ^ mode) & S_IFMT) {
+ if ((inode->i_mode ^ mode) & S_IFMT) {
iput(inode);
printk("fuse_mknod: inode has wrong type\n");
return -EINVAL;
@@ -204,7 +208,7 @@ static int _fuse_mknod(struct inode *dir, struct dentry *entry, int mode,
out.args[0].value = &outarg;
request_send(fc, &in, &out);
- if(out.h.error)
+ if (out.h.error)
return out.h.error;
return lookup_new_entry(dir, entry, &outarg, out.h.unique, mode);
@@ -238,7 +242,7 @@ static int fuse_mkdir(struct inode *dir, struct dentry *entry, int mode)
out.args[0].size = sizeof(outarg);
out.args[0].value = &outarg;
request_send(fc, &in, &out);
- if(out.h.error)
+ if (out.h.error)
return out.h.error;
return lookup_new_entry(dir, entry, &outarg, out.h.unique, S_IFDIR);
@@ -251,19 +255,23 @@ static int fuse_symlink(struct inode *dir, struct dentry *entry,
struct fuse_in in = FUSE_IN_INIT;
struct fuse_out out = FUSE_OUT_INIT;
struct fuse_entry_out outarg;
+ unsigned int len = strlen(link) + 1;
+
+ if (len > FUSE_SYMLINK_MAX)
+ return -ENAMETOOLONG;
in.h.opcode = FUSE_SYMLINK;
in.h.ino = dir->i_ino;
in.numargs = 2;
in.args[0].size = entry->d_name.len + 1;
in.args[0].value = entry->d_name.name;
- in.args[1].size = strlen(link) + 1;
+ in.args[1].size = len;
in.args[1].value = link;
out.numargs = 1;
out.args[0].size = sizeof(outarg);
out.args[0].value = &outarg;
request_send(fc, &in, &out);
- if(out.h.error)
+ if (out.h.error)
return out.h.error;
return lookup_new_entry(dir, entry, &outarg, out.h.unique, S_IFLNK);
@@ -282,7 +290,7 @@ static int fuse_unlink(struct inode *dir, struct dentry *entry)
in.args[0].value = entry->d_name.name;
request_send(fc, &in, &out);
- if(!out.h.error) {
+ if (!out.h.error) {
/* Set nlink to zero so the inode can be cleared, if
the inode does have more links this will be
discovered at the next lookup/getattr */
@@ -305,7 +313,7 @@ static int fuse_rmdir(struct inode *dir, struct dentry *entry)
in.args[0].size = entry->d_name.len + 1;
in.args[0].value = entry->d_name.name;
request_send(fc, &in, &out);
- if(!out.h.error)
+ if (!out.h.error)
entry->d_inode->i_nlink = 0;
return out.h.error;
@@ -360,7 +368,7 @@ static int fuse_link(struct dentry *entry, struct inode *newdir,
out.args[0].size = sizeof(outarg);
out.args[0].value = &outarg;
request_send(fc, &in, &out);
- if(out.h.error)
+ if (out.h.error)
return out.h.error;
/* Invalidate old entry, so attributes are refreshed */
@@ -383,7 +391,7 @@ int fuse_do_getattr(struct inode *inode)
out.args[0].value = &arg;
request_send(fc, &in, &out);
- if(!out.h.error)
+ if (!out.h.error)
change_attributes(inode, &arg.attr);
return out.h.error;
@@ -394,11 +402,11 @@ static int fuse_revalidate(struct dentry *entry)
struct inode *inode = entry->d_inode;
struct fuse_conn *fc = INO_FC(inode);
- if(inode->i_ino == FUSE_ROOT_INO) {
- if(!(fc->flags & FUSE_ALLOW_OTHER) &&
- current->fsuid != fc->uid)
+ if (inode->i_ino == FUSE_ROOT_INO) {
+ if (!(fc->flags & FUSE_ALLOW_OTHER) &&
+ current->fsuid != fc->uid)
return -EACCES;
- } else if(!entry->d_time || time_before_eq(jiffies, entry->d_time))
+ } else if (!entry->d_time || time_before_eq(jiffies, entry->d_time))
return 0;
return fuse_do_getattr(inode);
@@ -408,18 +416,18 @@ static int _fuse_permission(struct inode *inode, int mask)
{
struct fuse_conn *fc = INO_FC(inode);
- if(!(fc->flags & FUSE_ALLOW_OTHER) && current->fsuid != fc->uid)
+ if (!(fc->flags & FUSE_ALLOW_OTHER) && current->fsuid != fc->uid)
return -EACCES;
- else if(fc->flags & FUSE_DEFAULT_PERMISSIONS) {
+ else if (fc->flags & FUSE_DEFAULT_PERMISSIONS) {
int err = vfs_permission(inode, mask);
/* If permission is denied, try to refresh file
attributes. This is also needed, because the root
node will at first have no permissions */
- if(err == -EACCES) {
+ if (err == -EACCES) {
err = fuse_do_getattr(inode);
- if(!err)
+ if (!err)
err = vfs_permission(inode, mask);
}
@@ -440,20 +448,20 @@ static int _fuse_permission(struct inode *inode, int mask)
static int parse_dirfile(char *buf, size_t nbytes, struct file *file,
void *dstbuf, filldir_t filldir)
{
- while(nbytes >= FUSE_NAME_OFFSET) {
+ while (nbytes >= FUSE_NAME_OFFSET) {
struct fuse_dirent *dirent = (struct fuse_dirent *) buf;
size_t reclen = FUSE_DIRENT_SIZE(dirent);
int over;
- if(dirent->namelen > NAME_MAX) {
+ if (dirent->namelen > NAME_MAX) {
printk("fuse_readdir: name too long\n");
return -EPROTO;
}
- if(reclen > nbytes)
+ if (reclen > nbytes)
break;
over = filldir(dstbuf, dirent->name, dirent->namelen,
file->f_pos, dirent->ino, dirent->type);
- if(over)
+ if (over)
break;
buf += reclen;
@@ -471,15 +479,15 @@ static int fuse_readdir(struct file *file, void *dstbuf, filldir_t filldir)
char *buf;
int ret;
- if(!cfile)
+ if (!cfile)
return -EISDIR;
buf = kmalloc(DIR_BUFSIZE, GFP_KERNEL);
- if(!buf)
+ if (!buf)
return -ENOMEM;
ret = kernel_read(cfile, file->f_pos, buf, DIR_BUFSIZE);
- if(ret < 0)
+ if (ret < 0)
printk("fuse_readdir: failed to read container file\n");
else
ret = parse_dirfile(buf, ret, file, dstbuf, filldir);
@@ -497,7 +505,7 @@ static char *read_link(struct dentry *dentry)
char *link;
link = (char *) __get_free_page(GFP_KERNEL);
- if(!link)
+ if (!link)
return ERR_PTR(-ENOMEM);
in.h.opcode = FUSE_READLINK;
@@ -507,7 +515,7 @@ static char *read_link(struct dentry *dentry)
out.args[0].size = PAGE_SIZE - 1;
out.args[0].value = link;
request_send(fc, &in, &out);
- if(out.h.error) {
+ if (out.h.error) {
free_page((unsigned long) link);
return ERR_PTR(out.h.error);
}
@@ -518,7 +526,7 @@ static char *read_link(struct dentry *dentry)
static void free_link(char *link)
{
- if(!IS_ERR(link))
+ if (!IS_ERR(link))
free_page((unsigned long) link);
}
@@ -557,15 +565,15 @@ static int fuse_dir_open(struct inode *inode, struct file *file)
out.args[0].size = sizeof(struct fuse_getdir_out);
out.args[0].value = &outarg;
request_send(fc, &in, &out);
- if(!out.h.error) {
+ if (!out.h.error) {
struct file *cfile = outarg.file;
struct inode *inode;
- if(!cfile) {
+ if (!cfile) {
printk("fuse_getdir: invalid file\n");
return -EPROTO;
}
inode = cfile->f_dentry->d_inode;
- if(!S_ISREG(inode->i_mode)) {
+ if (!S_ISREG(inode->i_mode)) {
printk("fuse_getdir: not a regular file\n");
fput(cfile);
return -EPROTO;
@@ -581,7 +589,7 @@ static int fuse_dir_release(struct inode *inode, struct file *file)
{
struct file *cfile = file->private_data;
- if(cfile)
+ if (cfile)
fput(cfile);
return 0;
@@ -595,16 +603,16 @@ static unsigned int iattr_to_fattr(struct iattr *iattr,
memset(fattr, 0, sizeof(*fattr));
- if(ivalid & ATTR_MODE)
+ if (ivalid & ATTR_MODE)
fvalid |= FATTR_MODE, fattr->mode = iattr->ia_mode;
- if(ivalid & ATTR_UID)
+ if (ivalid & ATTR_UID)
fvalid |= FATTR_UID, fattr->uid = iattr->ia_uid;
- if(ivalid & ATTR_GID)
+ if (ivalid & ATTR_GID)
fvalid |= FATTR_GID, fattr->gid = iattr->ia_gid;
- if(ivalid & ATTR_SIZE)
+ if (ivalid & ATTR_SIZE)
fvalid |= FATTR_SIZE, fattr->size = iattr->ia_size;
/* You can only _set_ these together (they may change by themselves) */
- if((ivalid & (ATTR_ATIME | ATTR_MTIME)) == (ATTR_ATIME | ATTR_MTIME)) {
+ if ((ivalid & (ATTR_ATIME | ATTR_MTIME)) == (ATTR_ATIME | ATTR_MTIME)) {
fvalid |= FATTR_ATIME | FATTR_MTIME;
#ifdef KERNEL_2_6
fattr->atime = iattr->ia_atime.tv_sec;
@@ -640,9 +648,9 @@ static int fuse_setattr(struct dentry *entry, struct iattr *attr)
out.args[0].value = &outarg;
request_send(fc, &in, &out);
- if(!out.h.error) {
- if(attr->ia_valid & ATTR_SIZE &&
- outarg.attr.size < i_size_read(inode))
+ if (!out.h.error) {
+ if (attr->ia_valid & ATTR_SIZE &&
+ outarg.attr.size < i_size_read(inode))
vmtruncate(inode, outarg.attr.size);
change_attributes(inode, &outarg.attr);
@@ -652,9 +660,9 @@ static int fuse_setattr(struct dentry *entry, struct iattr *attr)
static int _fuse_dentry_revalidate(struct dentry *entry)
{
- if(!entry->d_inode)
+ if (!entry->d_inode)
return 0;
- else if(entry->d_time && time_after(jiffies, entry->d_time)) {
+ else if (entry->d_time && time_after(jiffies, entry->d_time)) {
struct inode *inode = entry->d_inode;
struct fuse_entry_out outarg;
int version;
@@ -662,10 +670,10 @@ static int _fuse_dentry_revalidate(struct dentry *entry)
ret = fuse_do_lookup(entry->d_parent->d_inode, entry, &outarg,
&version);
- if(ret)
+ if (ret)
return 0;
- if(outarg.ino != inode->i_ino)
+ if (outarg.ino != inode->i_ino)
return 0;
change_attributes(inode, &outarg.attr);
@@ -685,7 +693,7 @@ static int fuse_getattr(struct vfsmount *mnt, struct dentry *entry,
{
struct inode *inode = entry->d_inode;
int err = fuse_revalidate(entry);
- if(!err)
+ if (!err)
generic_fillattr(inode, stat);
return err;
@@ -727,6 +735,9 @@ static int fuse_setxattr(struct dentry *entry, const char *name,
struct fuse_out out = FUSE_OUT_INIT;
struct fuse_setxattr_in inarg;
+ if (size > FUSE_XATTR_SIZE_MAX)
+ return -E2BIG;
+
memset(&inarg, 0, sizeof(inarg));
inarg.size = size;
inarg.flags = flags;
@@ -766,7 +777,7 @@ static ssize_t fuse_getxattr(struct dentry *entry, const char *name,
in.args[1].value = name;
/* This is really two different operations rolled into one */
out.numargs = 1;
- if(size) {
+ if (size) {
out.argvar = 1;
out.args[0].size = size;
out.args[0].value = value;
@@ -775,7 +786,7 @@ static ssize_t fuse_getxattr(struct dentry *entry, const char *name,
out.args[0].value = &outarg;
}
request_send(fc, &in, &out);
- if(!out.h.error)
+ if (!out.h.error)
return size ? out.args[0].size : outarg.size;
else
return out.h.error;
@@ -800,7 +811,7 @@ static ssize_t fuse_listxattr(struct dentry *entry, char *list, size_t size)
in.args[0].value = &inarg;
/* This is really two different operations rolled into one */
out.numargs = 1;
- if(size) {
+ if (size) {
out.argvar = 1;
out.args[0].size = size;
out.args[0].value = list;
@@ -809,7 +820,7 @@ static ssize_t fuse_listxattr(struct dentry *entry, char *list, size_t size)
out.args[0].value = &outarg;
}
request_send(fc, &in, &out);
- if(!out.h.error)
+ if (!out.h.error)
return size ? out.args[0].size : outarg.size;
else
return out.h.error;
@@ -843,11 +854,11 @@ static struct dentry *fuse_lookup(struct inode *dir, struct dentry *entry)
struct dentry *alias;
int err = fuse_lookup_iget(dir, entry, &inode);
- if(err)
+ if (err)
return ERR_PTR(err);
- if(inode && S_ISDIR(inode->i_mode) &&
- (alias = d_find_alias(inode)) != NULL) {
+ if (inode && S_ISDIR(inode->i_mode) &&
+ (alias = d_find_alias(inode)) != NULL) {
dput(alias);
iput(inode);
printk("fuse: cannot assign an existing directory\n");
diff --git a/kernel/file.c b/kernel/file.c
index 8e24a01..2c9473f 100644
--- a/kernel/file.c
+++ b/kernel/file.c
@@ -19,7 +19,7 @@
#ifndef NO_MM
#define filemap_fdatawrite filemap_fdatasync
#else
-#define filemap_fdatawrite do {} while(0)
+#define filemap_fdatawrite do {} while (0)
#endif
#endif
@@ -32,14 +32,14 @@ static int fuse_open(struct inode *inode, struct file *file)
int err;
err = generic_file_open(inode, file);
- if(err)
+ if (err)
return err;
/* If opening the root node, no lookup has been performed on
it, so the attributes must be refreshed */
- if(inode->i_ino == FUSE_ROOT_INO) {
+ if (inode->i_ino == FUSE_ROOT_INO) {
int err = fuse_do_getattr(inode);
- if(err)
+ if (err)
return err;
}
@@ -52,7 +52,7 @@ static int fuse_open(struct inode *inode, struct file *file)
in.args[0].size = sizeof(inarg);
in.args[0].value = &inarg;
request_send(fc, &in, &out);
- if(!out.h.error && !(fc->flags & FUSE_KERNEL_CACHE)) {
+ if (!out.h.error && !(fc->flags & FUSE_KERNEL_CACHE)) {
#ifdef KERNEL_2_6
invalidate_inode_pages(inode->i_mapping);
#else
@@ -70,11 +70,11 @@ static int fuse_release(struct inode *inode, struct file *file)
struct fuse_open_in *inarg = NULL;
unsigned int s = sizeof(struct fuse_in) + sizeof(struct fuse_open_in);
- if(file->f_mode & FMODE_WRITE)
+ if (file->f_mode & FMODE_WRITE)
filemap_fdatawrite(inode->i_mapping);
in = kmalloc(s, GFP_NOFS);
- if(!in)
+ if (!in)
return -ENOMEM;
memset(in, 0, s);
inarg = (struct fuse_open_in *) (in + 1);
@@ -85,7 +85,7 @@ static int fuse_release(struct inode *inode, struct file *file)
in->numargs = 1;
in->args[0].size = sizeof(struct fuse_open_in);
in->args[0].value = inarg;
- if(!request_send_noreply(fc, in))
+ if (!request_send_noreply(fc, in))
return 0;
kfree(in);
@@ -142,9 +142,9 @@ static int fuse_readpage(struct file *file, struct page *page)
out.args[0].value = buffer;
request_send(fc, &in, &out);
- if(!out.h.error) {
+ if (!out.h.error) {
size_t outsize = out.args[0].size;
- if(outsize < PAGE_CACHE_SIZE)
+ if (outsize < PAGE_CACHE_SIZE)
memset(buffer + outsize, 0, PAGE_CACHE_SIZE - outsize);
flush_dcache_page(page);
SetPageUptodate(page);
@@ -287,7 +287,7 @@ static ssize_t fuse_file_read(struct file *filp, char *buf,
struct inode *inode = mapping->host;
struct fuse_conn *fc = INO_FC(inode);
- if(fc->flags & FUSE_LARGE_READ)
+ if (fc->flags & FUSE_LARGE_READ)
fuse_file_bigread(mapping, inode, *ppos, count);
return generic_file_read(filp, buf, count, ppos);
@@ -318,7 +318,7 @@ static int write_buffer(struct inode *inode, struct page *page,
in.args[1].value = buffer + offset;
request_send(fc, &in, &out);
kunmap(page);
- if(out.h.error)
+ if (out.h.error)
SetPageError(page);
return out.h.error;
@@ -331,11 +331,11 @@ static int get_write_count(struct inode *inode, struct page *page)
int count;
end_index = size >> PAGE_CACHE_SHIFT;
- if(page->index < end_index)
+ if (page->index < end_index)
count = PAGE_CACHE_SIZE;
else {
count = size & (PAGE_CACHE_SIZE - 1);
- if(page->index > end_index || count == 0)
+ if (page->index > end_index || count == 0)
return 0;
}
return count;
@@ -349,9 +349,9 @@ static void write_buffer_end(struct fuse_conn *fc, struct fuse_in *in,
struct page *page = (struct page *) _page;
lock_page(page);
- if(out->h.error) {
+ if (out->h.error) {
SetPageError(page);
- if(out->h.error == -ENOSPC)
+ if (out->h.error == -ENOSPC)
set_bit(AS_ENOSPC, &page->mapping->flags);
else
set_bit(AS_EIO, &page->mapping->flags);
@@ -375,7 +375,7 @@ static int write_buffer_nonblock(struct inode *inode, struct page *page,
sizeof(struct fuse_write_in);
in = kmalloc(s, GFP_NOFS);
- if(!in)
+ if (!in)
return -ENOMEM;
memset(in, 0, s);
out = (struct fuse_out *)(in + 1);
@@ -394,8 +394,8 @@ static int write_buffer_nonblock(struct inode *inode, struct page *page,
in->args[1].size = count;
in->args[1].value = buffer + offset;
err = request_send_nonblock(fc, in, out, write_buffer_end, page);
- if(err) {
- if(err != -EWOULDBLOCK)
+ if (err) {
+ if (err != -EWOULDBLOCK)
SetPageError(page);
kunmap(page);
kfree(in);
@@ -410,14 +410,14 @@ static int fuse_writepage(struct page *page, struct writeback_control *wbc)
unsigned count = get_write_count(inode, page);
err = -EINVAL;
- if(count) {
+ if (count) {
/* FIXME: check sync_mode, and wait for previous writes (or
signal userspace to do this) */
- if(wbc->nonblocking) {
+ if (wbc->nonblocking) {
err = write_buffer_nonblock(inode, page, 0, count);
- if(!err)
+ if (!err)
SetPageWriteback(page);
- else if(err == -EWOULDBLOCK) {
+ else if (err == -EWOULDBLOCK) {
__set_page_dirty_nobuffers(page);
err = 0;
}
@@ -435,7 +435,7 @@ static int fuse_writepage(struct page *page)
struct inode *inode = page->mapping->host;
int count = get_write_count(inode, page);
err = -EINVAL;
- if(count)
+ if (count)
err = write_buffer(inode, page, 0, count);
unlock_page(page);
@@ -457,9 +457,9 @@ static int fuse_commit_write(struct file *file, struct page *page,
struct inode *inode = page->mapping->host;
err = write_buffer(inode, page, offset, to - offset);
- if(!err) {
+ if (!err) {
loff_t pos = (page->index << PAGE_CACHE_SHIFT) + to;
- if(pos > i_size_read(inode))
+ if (pos > i_size_read(inode))
i_size_write(inode, pos);
}
return err;
@@ -490,7 +490,7 @@ void fuse_init_file_inode(struct inode *inode)
struct fuse_conn *fc = INO_FC(inode);
/* Readahead somehow defeats big reads on 2.6 (says Michael
Grigoriev) */
- if(fc->flags & FUSE_LARGE_READ)
+ if (fc->flags & FUSE_LARGE_READ)
inode->i_mapping->backing_dev_info->ra_pages = 0;
#endif
inode->i_fop = &fuse_file_operations;
diff --git a/kernel/inode.c b/kernel/inode.c
index 22b424a..17c0f60 100644
--- a/kernel/inode.c
+++ b/kernel/inode.c
@@ -42,11 +42,11 @@ static void fuse_clear_inode(struct inode *inode)
struct fuse_forget_in *inarg = NULL;
unsigned int s = sizeof(struct fuse_in) + sizeof(struct fuse_forget_in);
- if(fc == NULL)
+ if (fc == NULL)
return;
in = kmalloc(s, GFP_NOFS);
- if(!in)
+ if (!in)
return;
memset(in, 0, s);
inarg = (struct fuse_forget_in *) (in + 1);
@@ -58,7 +58,7 @@ static void fuse_clear_inode(struct inode *inode)
in->args[0].size = sizeof(struct fuse_forget_in);
in->args[0].value = inarg;
- if(!request_send_noreply(fc, in))
+ if (!request_send_noreply(fc, in))
return;
kfree(in);
@@ -105,7 +105,7 @@ static int fuse_statfs(struct super_block *sb, struct kstatfs *buf)
out.args[0].size = sizeof(outarg);
out.args[0].value = &outarg;
request_send(fc, &in, &out);
- if(!out.h.error)
+ if (!out.h.error)
convert_fuse_statfs(buf, &outarg.st);
return out.h.error;
@@ -117,17 +117,17 @@ static struct fuse_conn *get_conn(struct fuse_mount_data *d)
struct file *file;
struct inode *ino;
- if(d == NULL) {
+ if (d == NULL) {
printk("fuse_read_super: Bad mount data\n");
return NULL;
}
file = fget(d->fd);
ino = NULL;
- if(file)
+ if (file)
ino = file->f_dentry->d_inode;
- if(!ino || !proc_fuse_dev || proc_fuse_dev->low_ino != ino->i_ino) {
+ if (!ino || !proc_fuse_dev || proc_fuse_dev->low_ino != ino->i_ino) {
printk("fuse_read_super: Bad file: %i\n", d->fd);
goto out;
}
@@ -160,15 +160,15 @@ static struct dentry *fuse_get_dentry(struct super_block *sb, void *vobjp)
struct inode *inode;
struct dentry *entry;
- if(ino == 0)
+ if (ino == 0)
return ERR_PTR(-ESTALE);
inode = ilookup(sb, ino);
- if(!inode || inode->i_generation != generation)
+ if (!inode || inode->i_generation != generation)
return ERR_PTR(-ESTALE);
entry = d_alloc_anon(inode);
- if(!entry) {
+ if (!entry) {
iput(inode);
return ERR_PTR(-ENOMEM);
}
@@ -194,8 +194,8 @@ static int fuse_read_super(struct super_block *sb, void *data, int silent)
struct inode *root;
struct fuse_mount_data *d = data;
- if(!capable(CAP_SYS_ADMIN)) {
- if(d->flags & FUSE_ALLOW_OTHER)
+ if (!capable(CAP_SYS_ADMIN)) {
+ if (d->flags & FUSE_ALLOW_OTHER)
return -EPERM;
}
@@ -209,10 +209,10 @@ static int fuse_read_super(struct super_block *sb, void *data, int silent)
#endif
fc = get_conn(d);
- if(fc == NULL)
+ if (fc == NULL)
return -EINVAL;
spin_lock(&fuse_lock);
- if(fc->sb != NULL) {
+ if (fc->sb != NULL) {
printk("fuse_read_super: connection already mounted\n");
spin_unlock(&fuse_lock);
return -EINVAL;
@@ -227,13 +227,13 @@ static int fuse_read_super(struct super_block *sb, void *data, int silent)
SB_FC(sb) = fc;
root = get_root_inode(sb, d->rootmode);
- if(root == NULL) {
+ if (root == NULL) {
printk("fuse_read_super: failed to get root inode\n");
return -EINVAL;
}
sb->s_root = d_alloc_root(root);
- if(!sb->s_root)
+ if (!sb->s_root)
return -EINVAL;
return 0;
@@ -259,7 +259,7 @@ static struct super_block *fuse_read_super_compat(struct super_block *sb,
void *data, int silent)
{
int err = fuse_read_super(sb, data, silent);
- if(err)
+ if (err)
return NULL;
else
return sb;
@@ -273,7 +273,7 @@ int fuse_fs_init()
int res;
res = register_filesystem(&fuse_fs_type);
- if(res)
+ if (res)
printk("fuse: failed to register filesystem\n");
return res;
diff --git a/kernel/util.c b/kernel/util.c
index 6764157..faffb08 100644
--- a/kernel/util.c
+++ b/kernel/util.c
@@ -22,7 +22,7 @@ spinlock_t fuse_lock = SPIN_LOCK_UNLOCKED;
/* Must be called with the fuse lock held */
void fuse_release_conn(struct fuse_conn *fc)
{
- if(fc->sb == NULL && fc->file == NULL) {
+ if (fc->sb == NULL && fc->file == NULL) {
kfree(fc);
}
}
@@ -36,11 +36,11 @@ int __init fuse_init(void)
FUSE_KERNEL_VERSION, FUSE_KERNEL_MINOR_VERSION);
res = fuse_fs_init();
- if(res)
+ if (res)
goto err;
res = fuse_dev_init();
- if(res)
+ if (res)
goto err_fs_cleanup;
return 0;