aboutsummaryrefslogtreecommitdiffstats
path: root/fs/fuse/file.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/fuse/file.c')
-rw-r--r--fs/fuse/file.c29
1 files changed, 20 insertions, 9 deletions
diff --git a/fs/fuse/file.c b/fs/fuse/file.c
index 36f92f181d2f..28aa81eae2cc 100644
--- a/fs/fuse/file.c
+++ b/fs/fuse/file.c
@@ -161,15 +161,25 @@ static int fuse_release(struct inode *inode, struct file *file)
161} 161}
162 162
163/* 163/*
164 * It would be nice to scramble the ID space, so that the value of the 164 * Scramble the ID space with XTEA, so that the value of the files_struct
165 * files_struct pointer is not exposed to userspace. Symmetric crypto 165 * pointer is not exposed to userspace.
166 * functions are overkill, since the inverse function doesn't need to
167 * be implemented (though it does have to exist). Is there something
168 * simpler?
169 */ 166 */
170static inline u64 fuse_lock_owner_id(fl_owner_t id) 167static u64 fuse_lock_owner_id(struct fuse_conn *fc, fl_owner_t id)
171{ 168{
172 return (unsigned long) id; 169 u32 *k = fc->scramble_key;
170 u64 v = (unsigned long) id;
171 u32 v0 = v;
172 u32 v1 = v >> 32;
173 u32 sum = 0;
174 int i;
175
176 for (i = 0; i < 32; i++) {
177 v0 += ((v1 << 4 ^ v1 >> 5) + v1) ^ (sum + k[sum & 3]);
178 sum += 0x9E3779B9;
179 v1 += ((v0 << 4 ^ v0 >> 5) + v0) ^ (sum + k[sum>>11 & 3]);
180 }
181
182 return (u64) v0 + ((u64) v1 << 32);
173} 183}
174 184
175static int fuse_flush(struct file *file, fl_owner_t id) 185static int fuse_flush(struct file *file, fl_owner_t id)
@@ -190,7 +200,7 @@ static int fuse_flush(struct file *file, fl_owner_t id)
190 req = fuse_get_req_nofail(fc, file); 200 req = fuse_get_req_nofail(fc, file);
191 memset(&inarg, 0, sizeof(inarg)); 201 memset(&inarg, 0, sizeof(inarg));
192 inarg.fh = ff->fh; 202 inarg.fh = ff->fh;
193 inarg.lock_owner = fuse_lock_owner_id(id); 203 inarg.lock_owner = fuse_lock_owner_id(fc, id);
194 req->in.h.opcode = FUSE_FLUSH; 204 req->in.h.opcode = FUSE_FLUSH;
195 req->in.h.nodeid = get_node_id(inode); 205 req->in.h.nodeid = get_node_id(inode);
196 req->in.numargs = 1; 206 req->in.numargs = 1;
@@ -644,11 +654,12 @@ static void fuse_lk_fill(struct fuse_req *req, struct file *file,
644 const struct file_lock *fl, int opcode, pid_t pid) 654 const struct file_lock *fl, int opcode, pid_t pid)
645{ 655{
646 struct inode *inode = file->f_dentry->d_inode; 656 struct inode *inode = file->f_dentry->d_inode;
657 struct fuse_conn *fc = get_fuse_conn(inode);
647 struct fuse_file *ff = file->private_data; 658 struct fuse_file *ff = file->private_data;
648 struct fuse_lk_in *arg = &req->misc.lk_in; 659 struct fuse_lk_in *arg = &req->misc.lk_in;
649 660
650 arg->fh = ff->fh; 661 arg->fh = ff->fh;
651 arg->owner = fuse_lock_owner_id(fl->fl_owner); 662 arg->owner = fuse_lock_owner_id(fc, fl->fl_owner);
652 arg->lk.start = fl->fl_start; 663 arg->lk.start = fl->fl_start;
653 arg->lk.end = fl->fl_end; 664 arg->lk.end = fl->fl_end;
654 arg->lk.type = fl->fl_type; 665 arg->lk.type = fl->fl_type;