lkml.org 
[lkml]   [2019]   [May]   [28]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Subject[PATCH 06/25] vfs: Introduce a non-repeating system-unique superblock ID [ver #13]
    From
    Date
    Introduce a non-repeating system-unique superblock ID that can be used to
    tag superblock notification messages. The ID is time-based to make it
    harder to use it as a covert communications channel.

    Make it so that this ID can be fetched by the fsinfo() system call.

    Signed-off-by: David Howells <dhowells@redhat.com>
    ---

    fs/fsinfo.c | 1 +
    fs/super.c | 24 ++++++++++++++++++++++++
    include/linux/fs.h | 3 +++
    samples/vfs/test-fsinfo.c | 1 +
    4 files changed, 29 insertions(+)

    diff --git a/fs/fsinfo.c b/fs/fsinfo.c
    index 256a87b62eed..6afeabfe9451 100644
    --- a/fs/fsinfo.c
    +++ b/fs/fsinfo.c
    @@ -92,6 +92,7 @@ static int fsinfo_generic_ids(struct path *path, struct fsinfo_ids *p)
    p->f_fstype = sb->s_magic;
    p->f_dev_major = MAJOR(sb->s_dev);
    p->f_dev_minor = MINOR(sb->s_dev);
    + p->f_sb_id = sb->s_unique_id;

    memcpy(&p->f_fsid, &buf.f_fsid, sizeof(p->f_fsid));
    strlcpy(p->f_fs_name, path->dentry->d_sb->s_type->name,
    diff --git a/fs/super.c b/fs/super.c
    index 27b3e41394c8..61819e8e5469 100644
    --- a/fs/super.c
    +++ b/fs/super.c
    @@ -43,6 +43,8 @@ static int thaw_super_locked(struct super_block *sb);

    static LIST_HEAD(super_blocks);
    static DEFINE_SPINLOCK(sb_lock);
    +static u64 sb_last_identifier;
    +static u64 sb_identifier_offset;

    static char *sb_writers_name[SB_FREEZE_LEVELS] = {
    "sb_writers",
    @@ -187,6 +189,27 @@ static void destroy_unused_super(struct super_block *s)
    destroy_super_work(&s->destroy_work);
    }

    +/*
    + * Generate a unique identifier for a superblock.
    + */
    +static void generate_super_id(struct super_block *s)
    +{
    + u64 id = ktime_to_ns(ktime_get());
    +
    + spin_lock(&sb_lock);
    +
    + id += sb_identifier_offset;
    + if (id <= sb_last_identifier) {
    + id = sb_last_identifier + 1;
    + sb_identifier_offset = sb_last_identifier - id;
    + }
    +
    + sb_last_identifier = id;
    + spin_unlock(&sb_lock);
    +
    + s->s_unique_id = id;
    +}
    +
    /**
    * alloc_super - create new superblock
    * @type: filesystem type superblock should belong to
    @@ -270,6 +293,7 @@ static struct super_block *alloc_super(struct file_system_type *type, int flags,
    goto fail;
    if (list_lru_init_memcg(&s->s_inode_lru, &s->s_shrink))
    goto fail;
    + generate_super_id(s);
    return s;

    fail:
    diff --git a/include/linux/fs.h b/include/linux/fs.h
    index 71ce3b054c42..f1c74596cd77 100644
    --- a/include/linux/fs.h
    +++ b/include/linux/fs.h
    @@ -1527,6 +1527,9 @@ struct super_block {

    spinlock_t s_inode_wblist_lock;
    struct list_head s_inodes_wb; /* writeback inodes */
    +
    + /* Superblock event notifications */
    + u64 s_unique_id;
    } __randomize_layout;

    /* Helper functions so that in most cases filesystems will
    diff --git a/samples/vfs/test-fsinfo.c b/samples/vfs/test-fsinfo.c
    index e98384e8fb46..90926024e1c5 100644
    --- a/samples/vfs/test-fsinfo.c
    +++ b/samples/vfs/test-fsinfo.c
    @@ -179,6 +179,7 @@ static void dump_attr_IDS(union reply *r, int size)
    printf("\tdev : %02x:%02x\n", f->f_dev_major, f->f_dev_minor);
    printf("\tfs : type=%x name=%s\n", f->f_fstype, f->f_fs_name);
    printf("\tfsid : %llx\n", (unsigned long long)f->f_fsid);
    + printf("\tsbid : %llx\n", (unsigned long long)f->f_sb_id);
    }

    static void dump_attr_LIMITS(union reply *r, int size)
    \
     
     \ /
      Last update: 2019-05-28 17:12    [W:4.137 / U:0.280 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site