statfs: enforce statfs[64] structure initialization
authorIlya Leoshkevich <iii@linux.ibm.com>
Thu, 4 May 2023 14:40:20 +0000 (16:40 +0200)
committerAlexander Gordeev <agordeev@linux.ibm.com>
Wed, 17 May 2023 13:20:17 +0000 (15:20 +0200)
s390's struct statfs and struct statfs64 contain padding, which
field-by-field copying does not set. Initialize the respective structs
with zeros before filling them and copying them to userspace, like it's
already done for the compat versions of these structs.

Found by KMSAN.

[agordeev@linux.ibm.com: fixed typo in patch description]
Acked-by: Heiko Carstens <hca@linux.ibm.com>
Cc: stable@vger.kernel.org # v4.14+
Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com>
Reviewed-by: Andrew Morton <akpm@linux-foundation.org>
Link: https://lore.kernel.org/r/20230504144021.808932-2-iii@linux.ibm.com
Signed-off-by: Alexander Gordeev <agordeev@linux.ibm.com>
fs/statfs.c

index 0ba34c1355932401d44ad7007679e82fba2abb3a..96d1c3edf289c035b629a82060f5b5d7e5955595 100644 (file)
@@ -130,6 +130,7 @@ static int do_statfs_native(struct kstatfs *st, struct statfs __user *p)
        if (sizeof(buf) == sizeof(*st))
                memcpy(&buf, st, sizeof(*st));
        else {
+               memset(&buf, 0, sizeof(buf));
                if (sizeof buf.f_blocks == 4) {
                        if ((st->f_blocks | st->f_bfree | st->f_bavail |
                             st->f_bsize | st->f_frsize) &
@@ -158,7 +159,6 @@ static int do_statfs_native(struct kstatfs *st, struct statfs __user *p)
                buf.f_namelen = st->f_namelen;
                buf.f_frsize = st->f_frsize;
                buf.f_flags = st->f_flags;
-               memset(buf.f_spare, 0, sizeof(buf.f_spare));
        }
        if (copy_to_user(p, &buf, sizeof(buf)))
                return -EFAULT;
@@ -171,6 +171,7 @@ static int do_statfs64(struct kstatfs *st, struct statfs64 __user *p)
        if (sizeof(buf) == sizeof(*st))
                memcpy(&buf, st, sizeof(*st));
        else {
+               memset(&buf, 0, sizeof(buf));
                buf.f_type = st->f_type;
                buf.f_bsize = st->f_bsize;
                buf.f_blocks = st->f_blocks;
@@ -182,7 +183,6 @@ static int do_statfs64(struct kstatfs *st, struct statfs64 __user *p)
                buf.f_namelen = st->f_namelen;
                buf.f_frsize = st->f_frsize;
                buf.f_flags = st->f_flags;
-               memset(buf.f_spare, 0, sizeof(buf.f_spare));
        }
        if (copy_to_user(p, &buf, sizeof(buf)))
                return -EFAULT;