lkml.org 
[lkml]   [2004]   [Feb]   [5]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    SubjectRe: PATCH - ext2fs privacy (i.e. secure deletion) patch
    Ok, I've update the secure delete patch to now check

    is_secure_delete(inode)

    to see if either the chattr +s bit is set, or if the superblock has
    EXT2FS_MOUNT_SECRM (which I've added) set.

    I believe I've correctly modified the super.c to support a "secrm" mount
    option, but I haven't tested it so I can't say for sure. That is to say
    it compiles, but I haven't tried to run it. This rev of the patch is to
    see if the direction (and logic) of the secure delete functionality is
    in line with what people are thinking.

    There is some complexity around directory files. If a directory file has
    chattr +s set, then any directory entry within that file will be erased
    when the entry is removed. If a file has chattr +s set, or the fs was
    mounted with SECRM then the directory entry is removed. I would like
    people to pay particular attention to this part of the patch, its the
    area I'm least confident with.

    A directory entry's rec_len is preserved, in case we are removing the
    first entry for a directory block.

    The rest of the patch is basicly unchanged from the previous patchs. I
    haven't done a patch for ext3, when this one is agreed on then I'll it
    port acroos to ext3.


    peace,

    --gq
    --- linux-2.6.2/include/linux/ext2_fs.h 2004-02-04 03:43:12.000000000 +0000
    +++ linux-2.6.2/include/linux/ext2_fs.h-secrm 2004-02-05 22:08:59.000000000 +0000
    @@ -310,6 +310,7 @@
    #define EXT2_MOUNT_MINIX_DF 0x0080 /* Mimics the Minix statfs */
    #define EXT2_MOUNT_NOBH 0x0100 /* No buffer_heads */
    #define EXT2_MOUNT_NO_UID32 0x0200 /* Disable 32-bit UIDs */
    +#define EXT2_MOUNT_SECRM 0x0400 /* Securely delete files */
    #define EXT2_MOUNT_XATTR_USER 0x4000 /* Extended user attributes */
    #define EXT2_MOUNT_POSIX_ACL 0x8000 /* POSIX Access Control Lists */

    --- linux-2.6.2/fs/ext2/balloc.c 2004-02-04 03:43:42.000000000 +0000
    +++ linux-2.6.2/fs/ext2-secrm/balloc.c 2004-02-05 21:02:10.000000000 +0000
    @@ -173,6 +173,21 @@
    }
    }

    +static inline void delete_block(struct super_block *sb, unsigned long block)
    +{
    + struct buffer_head * bh;
    +
    + bh = sb_getblk(sb, block);
    +
    + memset(bh->b_data, 0, bh->b_size);
    +
    + mark_buffer_dirty(bh);
    + wait_on_buffer(bh); /* XXX is this necessary? */
    + brelse(bh);
    +
    + return;
    +}
    +
    /* Free given blocks, update quota and i_blocks field */
    void ext2_free_blocks (struct inode * inode, unsigned long block,
    unsigned long count)
    @@ -240,8 +255,11 @@
    ext2_error (sb, "ext2_free_blocks",
    "bit already cleared for block %lu",
    block + i);
    - else
    + else {
    + if (is_secure_delete(inode))
    + delete_block(inode->i_sb, block + i);
    group_freed++;
    + }
    }

    mark_buffer_dirty(bitmap_bh);
    --- linux-2.6.2/fs/ext2/dir.c 2004-02-04 03:43:56.000000000 +0000
    +++ linux-2.6.2/fs/ext2-secrm/dir.c 2004-02-05 22:01:00.000000000 +0000
    @@ -530,6 +530,7 @@
    {
    struct address_space *mapping = page->mapping;
    struct inode *inode = mapping->host;
    + struct inode *dino;
    char *kaddr = page_address(page);
    unsigned from = ((char*)dir - kaddr) & ~(ext2_chunk_size(inode)-1);
    unsigned to = ((char*)dir - kaddr) + le16_to_cpu(dir->rec_len);
    @@ -555,9 +556,24 @@
    BUG();
    if (pde)
    pde->rec_len = cpu_to_le16(to-from);
    - dir->inode = 0;
    +
    + dino = iget(inode->i_sb, dir->inode);
    + if (!dino || (!is_secure_delete(dino) && !is_secure_delete(inode))) {
    + dir->inode = 0;
    + inode->i_ctime = inode->i_mtime = CURRENT_TIME;
    + } else {
    + unsigned short rec_len = dir->rec_len;
    +
    + memset(dir, 0, dir->rec_len);
    + dir->rec_len = rec_len;
    + }
    +
    + if (dino)
    + iput(dino);
    +
    err = ext2_commit_chunk(page, from, to);
    - inode->i_ctime = inode->i_mtime = CURRENT_TIME;
    +
    + /* XXX should this be in the if (!is_secure_delete()) above? */
    EXT2_I(inode)->i_flags &= ~EXT2_BTREE_FL;
    mark_inode_dirty(inode);
    out:
    --- linux-2.6.2/fs/ext2/ext2.h 2004-02-05 20:46:40.000000000 +0000
    +++ linux-2.6.2/fs/ext2-secrm/ext2.h 2004-02-05 20:45:25.000000000 +0000
    @@ -79,6 +79,16 @@
    return container_of(inode, struct ext2_inode_info, vfs_inode);
    }

    +static inline int is_secure_delete(struct inode *inode)
    +{
    + /* expanded for readibility */
    + if (EXT2_I(inode)->i_flags & EXT2_SECRM_FL)
    + return 1;
    + if (test_opt(inode->i_sb, SECRM))
    + return 1;
    + return 0;
    +}
    +
    /* balloc.c */
    extern int ext2_bg_has_super(struct super_block *sb, int group);
    extern unsigned long ext2_bg_num_gdb(struct super_block *sb, int group);
    --- linux-2.6.2/fs/ext2/inode.c 2004-02-04 03:43:09.000000000 +0000
    +++ linux-2.6.2/fs/ext2-secrm/inode.c 2004-02-05 22:18:56.000000000 +0000
    @@ -64,6 +64,36 @@
    ext2_discard_prealloc(inode);
    }

    +static inline void delete_inode(struct inode *inode)
    +{
    + if (!is_secure_delete(inode))
    + EXT2_I(inode)->i_dtime = get_seconds();
    + else {
    + inode->i_mode = 0;
    + inode->i_uid = 0;
    + inode->i_gid = 0;
    + inode->i_nlink = 0;
    + inode->i_atime.tv_sec = 0;
    + inode->i_atime.tv_nsec = 0;
    + inode->i_ctime.tv_sec = 0;
    + inode->i_ctime.tv_nsec = 0;
    + inode->i_mtime.tv_sec = 0;
    + inode->i_mtime.tv_nsec = 0;
    + EXT2_I(inode)->i_dtime = 0;
    + EXT2_I(inode)->i_faddr = 0;
    + EXT2_I(inode)->i_frag_no = 0;
    + EXT2_I(inode)->i_frag_size = 0;
    + EXT2_I(inode)->i_file_acl = 0;
    + inode->i_generation = 0;
    + }
    +}
    +
    +static inline void delete_blocks(struct inode *inode)
    +{
    + inode->i_blocks = 0;
    + memset(EXT2_I(inode)->i_data, 0, sizeof(EXT2_I(inode)->i_data));
    +}
    +
    /*
    * Called at the last iput() if i_nlink is zero.
    */
    @@ -71,13 +101,21 @@
    {
    if (is_bad_inode(inode))
    goto no_delete;
    - EXT2_I(inode)->i_dtime = get_seconds();
    + delete_inode(inode);
    mark_inode_dirty(inode);
    ext2_update_inode(inode, inode_needs_sync(inode));

    inode->i_size = 0;
    if (inode->i_blocks)
    ext2_truncate (inode);
    +
    + if (is_secure_delete(inode)) {
    + EXT2_I(inode)->i_flags = 0;
    +
    + delete_blocks(inode);
    + mark_inode_dirty(inode);
    + ext2_update_inode(inode, inode_needs_sync(inode));
    + }
    ext2_free_inode (inode);

    return;
    --- linux-2.6.2/fs/ext2/super.c 2004-02-04 03:44:04.000000000 +0000
    +++ linux-2.6.2/fs/ext2-secrm/super.c 2004-02-05 22:04:17.000000000 +0000
    @@ -270,7 +270,7 @@
    Opt_bsd_df, Opt_minix_df, Opt_grpid, Opt_nogrpid,
    Opt_resgid, Opt_resuid, Opt_sb, Opt_err_cont, Opt_err_panic, Opt_err_ro,
    Opt_nouid32, Opt_check, Opt_nocheck, Opt_debug, Opt_oldalloc, Opt_orlov, Opt_nobh,
    - Opt_user_xattr, Opt_nouser_xattr, Opt_acl, Opt_noacl,
    + Opt_user_xattr, Opt_nouser_xattr, Opt_acl, Opt_noacl, Opt_secrm,
    Opt_ignore, Opt_err,
    };

    @@ -299,6 +299,7 @@
    {Opt_nouser_xattr, "nouser_xattr"},
    {Opt_acl, "acl"},
    {Opt_noacl, "noacl"},
    + {Opt_secrm, "secrm"},
    {Opt_ignore, "grpquota"},
    {Opt_ignore, "noquota"},
    {Opt_ignore, "quota"},
    @@ -410,6 +411,9 @@
    printk("EXT2 (no)acl options not supported\n");
    break;
    #endif
    + case Opt_secrm:
    + set_opt(sbi->s_mount_opt, SECRM);
    + break;
    case Opt_ignore:
    break;
    default:
    \
     
     \ /
      Last update: 2005-03-22 14:00    [W:0.043 / U:0.060 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site