lkml.org 
[lkml]   [2008]   [Mar]   [17]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH prototype] [2/8] Add support to override mmap exec write protection with O_FORCEWRITE
    Date

    pbitmaps need to write to files mapped as executable, so add
    a way to bypass the normal write protection using a new O_FORCEWRITE
    flag.

    Right now the flag can be set from user space too. If have not
    made up my mind if that is a good or a bad thing (I don't think
    it has any real security implications). Probably it's more bad
    than good.

    Signed-off-by: Andi Kleen <andi@firstfloor.org>

    ---
    fs/namei.c | 9 +++++++--
    fs/open.c | 2 +-
    include/asm-generic/fcntl.h | 4 ++++
    include/linux/fs.h | 1 +
    4 files changed, 13 insertions(+), 3 deletions(-)

    Index: linux/fs/namei.c
    ===================================================================
    --- linux.orig/fs/namei.c
    +++ linux/fs/namei.c
    @@ -334,10 +334,10 @@ int file_permission(struct file *file, i
    * the inode->i_lock spinlock.
    */

    -int get_write_access(struct inode * inode)
    +int __get_write_access(struct inode * inode, int flags)
    {
    spin_lock(&inode->i_lock);
    - if (atomic_read(&inode->i_writecount) < 0) {
    + if (atomic_read(&inode->i_writecount) < 0 && !(flags&O_FORCEWRITE)) {
    spin_unlock(&inode->i_lock);
    return -ETXTBSY;
    }
    @@ -347,6 +347,11 @@ int get_write_access(struct inode * inod
    return 0;
    }

    +int get_write_access(struct inode * inode)
    +{
    + return __get_write_access(inode, 0);
    +}
    +
    int deny_write_access(struct file * file)
    {
    struct inode *inode = file->f_path.dentry->d_inode;
    Index: linux/fs/open.c
    ===================================================================
    --- linux.orig/fs/open.c
    +++ linux/fs/open.c
    @@ -742,7 +742,7 @@ static struct file *__dentry_open(struct
    FMODE_PREAD | FMODE_PWRITE;
    inode = dentry->d_inode;
    if (f->f_mode & FMODE_WRITE) {
    - error = get_write_access(inode);
    + error = __get_write_access(inode, f->f_flags & O_FORCEWRITE);
    if (error)
    goto cleanup_file;
    }
    Index: linux/include/linux/fs.h
    ===================================================================
    --- linux.orig/include/linux/fs.h
    +++ linux/include/linux/fs.h
    @@ -1720,6 +1720,7 @@ extern int generic_permission(struct ino
    int (*check_acl)(struct inode *, int));

    extern int get_write_access(struct inode *);
    +extern int __get_write_access(struct inode *i, int flags);
    extern int deny_write_access(struct file *);
    static inline void put_write_access(struct inode * inode)
    {
    Index: linux/include/asm-generic/fcntl.h
    ===================================================================
    --- linux.orig/include/asm-generic/fcntl.h
    +++ linux/include/asm-generic/fcntl.h
    @@ -54,6 +54,10 @@
    #ifndef O_NDELAY
    #define O_NDELAY O_NONBLOCK
    #endif
    +/* ignore ETXTBSY -- should probably hide it from user space */
    +#ifndef O_FORCEWRITE
    +#define O_FORCEWRITE 02000000
    +#endif

    #define F_DUPFD 0 /* dup */
    #define F_GETFD 1 /* get close_on_exec */

    \
     
     \ /
      Last update: 2008-03-18 02:13    [W:0.023 / U:60.264 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site