Skip to content

Commit 6834082

Browse files
konisakpm00
authored andcommitted
nilfs2: protect references to superblock parameters exposed in sysfs
The superblock buffers of nilfs2 can not only be overwritten at runtime for modifications/repairs, but they are also regularly swapped, replaced during resizing, and even abandoned when degrading to one side due to backing device issues. So, accessing them requires mutual exclusion using the reader/writer semaphore "nilfs->ns_sem". Some sysfs attribute show methods read this superblock buffer without the necessary mutual exclusion, which can cause problems with pointer dereferencing and memory access, so fix it. Link: https://lkml.kernel.org/r/[email protected] Fixes: da7141f ("nilfs2: add /sys/fs/nilfs2/<device> group") Signed-off-by: Ryusuke Konishi <[email protected]> Cc: <[email protected]> Signed-off-by: Andrew Morton <[email protected]>
1 parent 4828d20 commit 6834082

File tree

1 file changed

+33
-10
lines changed

1 file changed

+33
-10
lines changed

fs/nilfs2/sysfs.c

Lines changed: 33 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -836,9 +836,15 @@ ssize_t nilfs_dev_revision_show(struct nilfs_dev_attr *attr,
836836
struct the_nilfs *nilfs,
837837
char *buf)
838838
{
839-
struct nilfs_super_block **sbp = nilfs->ns_sbp;
840-
u32 major = le32_to_cpu(sbp[0]->s_rev_level);
841-
u16 minor = le16_to_cpu(sbp[0]->s_minor_rev_level);
839+
struct nilfs_super_block *raw_sb;
840+
u32 major;
841+
u16 minor;
842+
843+
down_read(&nilfs->ns_sem);
844+
raw_sb = nilfs->ns_sbp[0];
845+
major = le32_to_cpu(raw_sb->s_rev_level);
846+
minor = le16_to_cpu(raw_sb->s_minor_rev_level);
847+
up_read(&nilfs->ns_sem);
842848

843849
return sysfs_emit(buf, "%d.%d\n", major, minor);
844850
}
@@ -856,8 +862,13 @@ ssize_t nilfs_dev_device_size_show(struct nilfs_dev_attr *attr,
856862
struct the_nilfs *nilfs,
857863
char *buf)
858864
{
859-
struct nilfs_super_block **sbp = nilfs->ns_sbp;
860-
u64 dev_size = le64_to_cpu(sbp[0]->s_dev_size);
865+
struct nilfs_super_block *raw_sb;
866+
u64 dev_size;
867+
868+
down_read(&nilfs->ns_sem);
869+
raw_sb = nilfs->ns_sbp[0];
870+
dev_size = le64_to_cpu(raw_sb->s_dev_size);
871+
up_read(&nilfs->ns_sem);
861872

862873
return sysfs_emit(buf, "%llu\n", dev_size);
863874
}
@@ -879,20 +890,32 @@ ssize_t nilfs_dev_uuid_show(struct nilfs_dev_attr *attr,
879890
struct the_nilfs *nilfs,
880891
char *buf)
881892
{
882-
struct nilfs_super_block **sbp = nilfs->ns_sbp;
893+
struct nilfs_super_block *raw_sb;
894+
ssize_t len;
883895

884-
return sysfs_emit(buf, "%pUb\n", sbp[0]->s_uuid);
896+
down_read(&nilfs->ns_sem);
897+
raw_sb = nilfs->ns_sbp[0];
898+
len = sysfs_emit(buf, "%pUb\n", raw_sb->s_uuid);
899+
up_read(&nilfs->ns_sem);
900+
901+
return len;
885902
}
886903

887904
static
888905
ssize_t nilfs_dev_volume_name_show(struct nilfs_dev_attr *attr,
889906
struct the_nilfs *nilfs,
890907
char *buf)
891908
{
892-
struct nilfs_super_block **sbp = nilfs->ns_sbp;
909+
struct nilfs_super_block *raw_sb;
910+
ssize_t len;
911+
912+
down_read(&nilfs->ns_sem);
913+
raw_sb = nilfs->ns_sbp[0];
914+
len = scnprintf(buf, sizeof(raw_sb->s_volume_name), "%s\n",
915+
raw_sb->s_volume_name);
916+
up_read(&nilfs->ns_sem);
893917

894-
return scnprintf(buf, sizeof(sbp[0]->s_volume_name), "%s\n",
895-
sbp[0]->s_volume_name);
918+
return len;
896919
}
897920

898921
static const char dev_readme_str[] =

0 commit comments

Comments
 (0)