[PATCH 15/17] watch_queue: Introduce a non-repeating system-unique superblock ID [ver #5]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Introduce an (effectively) non-repeating system-unique superblock ID that
can be used to determine that two object are in the same superblock without
risking reuse of the ID in the meantime (as is possible with device IDs).

The ID is time-based to make it harder to use it as a covert communications
channel.

In future patches, this ID will be used to tag superblock notification
messages.  It will also be made queryable.

Signed-off-by: David Howells <dhowells@xxxxxxxxxx>
---

 fs/internal.h      |    1 +
 fs/super.c         |   24 ++++++++++++++++++++++++
 include/linux/fs.h |    3 +++
 3 files changed, 28 insertions(+)

diff --git a/fs/internal.h b/fs/internal.h
index f3f280b952a3..a0d90f23593c 100644
--- a/fs/internal.h
+++ b/fs/internal.h
@@ -109,6 +109,7 @@ extern int reconfigure_super(struct fs_context *);
 extern bool trylock_super(struct super_block *sb);
 extern struct super_block *user_get_super(dev_t);
 extern bool mount_capable(struct fs_context *);
+extern void vfs_generate_unique_id(u64 *);
 
 /*
  * open.c
diff --git a/fs/super.c b/fs/super.c
index cd352530eca9..ececa5695fd1 100644
--- a/fs/super.c
+++ b/fs/super.c
@@ -44,6 +44,8 @@ static int thaw_super_locked(struct super_block *sb);
 
 static LIST_HEAD(super_blocks);
 static DEFINE_SPINLOCK(sb_lock);
+static u64 vfs_last_identifier;
+static u64 vfs_identifier_offset;
 
 static char *sb_writers_name[SB_FREEZE_LEVELS] = {
 	"sb_writers",
@@ -273,6 +275,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;
+	vfs_generate_unique_id(&s->s_unique_id);
 	return s;
 
 fail:
@@ -1867,3 +1870,24 @@ int thaw_super(struct super_block *sb)
 	return thaw_super_locked(sb);
 }
 EXPORT_SYMBOL(thaw_super);
+
+/*
+ * Generate a unique identifier for a superblock or mount object.
+ */
+void vfs_generate_unique_id(u64 *_id)
+{
+	u64 id = ktime_to_ns(ktime_get());
+
+	spin_lock(&sb_lock);
+
+	id += vfs_identifier_offset;
+	if (id <= vfs_last_identifier) {
+		id = vfs_last_identifier + 1;
+		vfs_identifier_offset = vfs_last_identifier - id;
+	}
+
+	vfs_last_identifier = id;
+	spin_unlock(&sb_lock);
+
+	*_id = id;
+}
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 3cd4fe6b845e..9de6bfe41016 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -1548,6 +1548,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





[Index of Archives]     [Linux Ext4 Filesystem]     [Union Filesystem]     [Filesystem Testing]     [Ceph Users]     [Ecryptfs]     [AutoFS]     [Kernel Newbies]     [Share Photos]     [Security]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux Cachefs]     [Reiser Filesystem]     [Linux RAID]     [Samba]     [Device Mapper]     [CEPH Development]

  Powered by Linux