diff options
Diffstat (limited to 'sys-fs/aufs3/files/pax.patch')
-rw-r--r-- | sys-fs/aufs3/files/pax.patch | 135 |
1 files changed, 135 insertions, 0 deletions
diff --git a/sys-fs/aufs3/files/pax.patch b/sys-fs/aufs3/files/pax.patch new file mode 100644 index 000000000000..df53004daddb --- /dev/null +++ b/sys-fs/aufs3/files/pax.patch @@ -0,0 +1,135 @@ +commit 584bf002ec62a333840b87193b93ee5a521063f7 +Author: J. R. Okajima <hooanon05@yahoo.co.jp> +Date: Thu May 27 11:28:41 2010 +0900 + + aufs: dynop supports grsec/pax patch + + The grsec/pax patches make member of struct brabra_operation 'const.' + I don't understand why they need these 'const'. They modifies some of + structures, but other structures. + What do they want to protect from what? + + The keyword 'const' is essentially a feature of C language and it never + modifes the behaviour of software. It just prohibits the assignment (or + modification) to a variable which is expected not to be modified. + In other word, it is a feature for programmers and doesn't enhance the + security level. Actually programmers can bypass 'const' easily by + indirect assignment as this patch does. + + Also the grsec/pax patches modifies some assignments to the member + of struct brabra_operation in mainline kernel, but they don't make the + confirmation fot that. For example, they replaced these assignments by + declaring a structure statically. + + - /* inherit and extend fuse_dev_operations */ + - cuse_channel_fops = fuse_dev_operations; + - cuse_channel_fops.owner = THIS_MODULE; + - cuse_channel_fops.open = cuse_channel_open; + - cuse_channel_fops.release = cuse_channel_release; + + +static const struct file_operations cuse_channel_fops = { + + .owner = THIS_MODULE, + + .llseek = no_llseek, + + .read = do_sync_read, + + .aio_read = fuse_dev_read, + + .write = do_sync_write, + + .aio_write = fuse_dev_write, + + .poll = fuse_dev_poll, + + .open = cuse_channel_open, + + .release = cuse_channel_release, + + .fasync = fuse_dev_fasync, + +}; + + By this modification, there exists major possible future problem I am + afraid. _If_ fuse_dev_operations is modified, then this code needs to + follow the change. But it is hard to detect such modification since + there is no trick to do so. Generally it is recommended to put code such + like this. + + ---------------------------------------------------------------------- + int n; + n++; + BUG_ON(super.member != derive.member); + } while (0); + + n++; /* owner */ + MakeSure(fuse_dev_operations, cuse_channel_fops, llseek); + MakeSure(fuse_dev_operations, cuse_channel_fops, read); + ::: + BUG_ON(n != sizeof(cuse_channel_fops)/sizeof(cuse_channel_fops.owner)); + ---------------------------------------------------------------------- + + This piece of code ensures two things. + - cuse_channel_fops correctly inherits fuse_dev_operations, eg. all + members are equivalent except the overrided ones. + - if some members are added or deleted from struct file_operations, it + should be detected by a debugging feature, the variable 'n'. + + Without such trick, I am afraid the simple modification is a regression. + + Signed-off-by: J. R. Okajima <hooanon05@yahoo.co.jp> + +diff --git a/fs/aufs/dynop.c b/fs/aufs/dynop.c +index 12ea894..109d3bb 100644 +--- a/fs/aufs/dynop.c ++++ b/fs/aufs/dynop.c +@@ -146,11 +146,22 @@ void au_dy_put(struct au_dykey *key) + #define DyDbgInc(cnt) do {} while (0) + #endif + ++#define AuGrsecPaxPtr(func, dst, src) do { \ ++ union { \ ++ const void *o; \ ++ char **p; \ ++ } u; \ ++ BUILD_BUG_ON(sizeof(u.o) != sizeof(&dst.func)); \ ++ BUILD_BUG_ON(sizeof(*u.p) != sizeof(src.func)); \ ++ u.o = (void *)&dst.func; \ ++ *u.p = (void *)src.func; \ ++} while (0) ++ + #define DySet(func, dst, src, h_op, h_sb) do { \ + DyDbgInc(cnt); \ + if (h_op->func) { \ + if (src.func) \ +- dst.func = src.func; \ ++ AuGrsecPaxPtr(func, dst, src); \ + else \ + AuDbg("%s %s\n", au_sbtype(h_sb), #func); \ + } \ +@@ -159,7 +170,7 @@ void au_dy_put(struct au_dykey *key) + #define DySetForce(func, dst, src) do { \ + AuDebugOn(!src.func); \ + DyDbgInc(cnt); \ +- dst.func = src.func; \ ++ AuGrsecPaxPtr(func, dst, src); \ + } while (0) + + #define DySetAop(func) \ +@@ -297,14 +308,21 @@ out: + */ + static void dy_adx(struct au_dyaop *dyaop, int do_dx) + { ++ union { ++ void *direct_IO, *get_xip_mem; ++ } grsec_pax_dummy = { ++ .get_xip_mem = NULL ++ }; ++ + if (!do_dx) { +- dyaop->da_op.direct_IO = NULL; +- dyaop->da_op.get_xip_mem = NULL; ++ AuGrsecPaxPtr(direct_IO, dyaop->da_op, grsec_pax_dummy); ++ AuGrsecPaxPtr(get_xip_mem, dyaop->da_op, grsec_pax_dummy); + } else { +- dyaop->da_op.direct_IO = aufs_aop.direct_IO; +- dyaop->da_op.get_xip_mem = aufs_aop.get_xip_mem; ++ AuGrsecPaxPtr(direct_IO, dyaop->da_op, aufs_aop); ++ AuGrsecPaxPtr(get_xip_mem, dyaop->da_op, aufs_aop); + if (!dyaop->da_get_xip_mem) +- dyaop->da_op.get_xip_mem = NULL; ++ AuGrsecPaxPtr(get_xip_mem, dyaop->da_op, ++ grsec_pax_dummy); + } + } + |