From 71f81b774cdca2674e9ed70bce733473a81715b6 Mon Sep 17 00:00:00 2001 From: Miklos Szeredi Date: Sun, 25 Jun 2006 05:48:55 -0700 Subject: [PATCH] --- yaml --- r: 29780 b: refs/heads/master c: 9c8ef5614da22666e339b125263d315cfaa89109 h: refs/heads/master v: v3 --- [refs] | 2 +- trunk/fs/fuse/file.c | 29 ++++++++++++++++++++--------- trunk/fs/fuse/fuse_i.h | 3 +++ trunk/fs/fuse/inode.c | 2 ++ 4 files changed, 26 insertions(+), 10 deletions(-) diff --git a/[refs] b/[refs] index 5acf4c30611d..76e30eb18500 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: a4d27e75ffb7b8ecb7eed0c7db0df975525f3fd7 +refs/heads/master: 9c8ef5614da22666e339b125263d315cfaa89109 diff --git a/trunk/fs/fuse/file.c b/trunk/fs/fuse/file.c index 36f92f181d2f..28aa81eae2cc 100644 --- a/trunk/fs/fuse/file.c +++ b/trunk/fs/fuse/file.c @@ -161,15 +161,25 @@ static int fuse_release(struct inode *inode, struct file *file) } /* - * It would be nice to scramble the ID space, so that the value of the - * files_struct pointer is not exposed to userspace. Symmetric crypto - * functions are overkill, since the inverse function doesn't need to - * be implemented (though it does have to exist). Is there something - * simpler? + * Scramble the ID space with XTEA, so that the value of the files_struct + * pointer is not exposed to userspace. */ -static inline u64 fuse_lock_owner_id(fl_owner_t id) +static u64 fuse_lock_owner_id(struct fuse_conn *fc, fl_owner_t id) { - return (unsigned long) id; + u32 *k = fc->scramble_key; + u64 v = (unsigned long) id; + u32 v0 = v; + u32 v1 = v >> 32; + u32 sum = 0; + int i; + + for (i = 0; i < 32; i++) { + v0 += ((v1 << 4 ^ v1 >> 5) + v1) ^ (sum + k[sum & 3]); + sum += 0x9E3779B9; + v1 += ((v0 << 4 ^ v0 >> 5) + v0) ^ (sum + k[sum>>11 & 3]); + } + + return (u64) v0 + ((u64) v1 << 32); } static 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) req = fuse_get_req_nofail(fc, file); memset(&inarg, 0, sizeof(inarg)); inarg.fh = ff->fh; - inarg.lock_owner = fuse_lock_owner_id(id); + inarg.lock_owner = fuse_lock_owner_id(fc, id); req->in.h.opcode = FUSE_FLUSH; req->in.h.nodeid = get_node_id(inode); req->in.numargs = 1; @@ -644,11 +654,12 @@ static void fuse_lk_fill(struct fuse_req *req, struct file *file, const struct file_lock *fl, int opcode, pid_t pid) { struct inode *inode = file->f_dentry->d_inode; + struct fuse_conn *fc = get_fuse_conn(inode); struct fuse_file *ff = file->private_data; struct fuse_lk_in *arg = &req->misc.lk_in; arg->fh = ff->fh; - arg->owner = fuse_lock_owner_id(fl->fl_owner); + arg->owner = fuse_lock_owner_id(fc, fl->fl_owner); arg->lk.start = fl->fl_start; arg->lk.end = fl->fl_end; arg->lk.type = fl->fl_type; diff --git a/trunk/fs/fuse/fuse_i.h b/trunk/fs/fuse/fuse_i.h index c862df58da92..0dbf96621841 100644 --- a/trunk/fs/fuse/fuse_i.h +++ b/trunk/fs/fuse/fuse_i.h @@ -359,6 +359,9 @@ struct fuse_conn { /** O_ASYNC requests */ struct fasync_struct *fasync; + + /** Key for lock owner ID scrambling */ + u32 scramble_key[4]; }; static inline struct fuse_conn *get_fuse_conn_super(struct super_block *sb) diff --git a/trunk/fs/fuse/inode.c b/trunk/fs/fuse/inode.c index e21ef8a3ad30..5ceb8bd7a189 100644 --- a/trunk/fs/fuse/inode.c +++ b/trunk/fs/fuse/inode.c @@ -16,6 +16,7 @@ #include #include #include +#include MODULE_AUTHOR("Miklos Szeredi "); MODULE_DESCRIPTION("Filesystem in Userspace"); @@ -387,6 +388,7 @@ static struct fuse_conn *new_conn(void) fc->bdi.unplug_io_fn = default_unplug_io_fn; fc->reqctr = 0; fc->blocked = 1; + get_random_bytes(&fc->scramble_key, sizeof(fc->scramble_key)); } return fc; }