diff mbox series

[v3] squashfs: Add regression test for sanity check bug

Message ID 20210715050812.1950884-1-lkml@jv-coder.de
State Accepted
Headers show
Series [v3] squashfs: Add regression test for sanity check bug | expand

Commit Message

Joerg Vehlow July 15, 2021, 5:08 a.m. UTC
From: Joerg Vehlow <joerg.vehlow@aox-tech.de>

Adds a regression test for the fixes
c1b2028315 ("squashfs: fix inode lookup sanity checks")
and
8b44ca2b62 ("squashfs: fix xattr id and id lookup sanity checks")

Signed-off-by: Joerg Vehlow <joerg.vehlow@aox-tech.de>
---

Changes to v2:
 - Rename to squashfs01
 - Add mksquashfs to needs_cmds
 - Use needs_device and mount syscall instead of mount tool
 - Moved test file creation to setup
 - Use tst_cmd instead of tst_system
 - Use flag to call umount conditionally in cleanup

Changes to v1:
 - Implement whole test in c
 - Fixed whitespaces...

 runtest/fs                                |   2 +
 testcases/kernel/fs/squashfs/.gitignore   |   1 +
 testcases/kernel/fs/squashfs/Makefile     |   9 ++
 testcases/kernel/fs/squashfs/squashfs01.c | 121 ++++++++++++++++++++++
 4 files changed, 133 insertions(+)
 create mode 100644 testcases/kernel/fs/squashfs/.gitignore
 create mode 100644 testcases/kernel/fs/squashfs/Makefile
 create mode 100644 testcases/kernel/fs/squashfs/squashfs01.c

Comments

Richard Palethorpe July 15, 2021, 8 a.m. UTC | #1
Hello Joerg,

Joerg Vehlow <lkml@jv-coder.de> writes:

> From: Joerg Vehlow <joerg.vehlow@aox-tech.de>
>
> Adds a regression test for the fixes
> c1b2028315 ("squashfs: fix inode lookup sanity checks")
> and
> 8b44ca2b62 ("squashfs: fix xattr id and id lookup sanity checks")
>
> Signed-off-by: Joerg Vehlow <joerg.vehlow@aox-tech.de>

Acked-by: Richard Palethorpe <rpalethorpe@suse.com>
Yang Xu July 15, 2021, 8:21 a.m. UTC | #2
Hi Joery
> From: Joerg Vehlow<joerg.vehlow@aox-tech.de>
>
> Adds a regression test for the fixes
> c1b2028315 ("squashfs: fix inode lookup sanity checks")
> and
> 8b44ca2b62 ("squashfs: fix xattr id and id lookup sanity checks")
>
> Signed-off-by: Joerg Vehlow<joerg.vehlow@aox-tech.de>
> ---
>
> Changes to v2:
>   - Rename to squashfs01
>   - Add mksquashfs to needs_cmds
>   - Use needs_device and mount syscall instead of mount tool
>   - Moved test file creation to setup
>   - Use tst_cmd instead of tst_system
>   - Use flag to call umount conditionally in cleanup
>
> Changes to v1:
>   - Implement whole test in c
>   - Fixed whitespaces...
>
>   runtest/fs                                |   2 +
>   testcases/kernel/fs/squashfs/.gitignore   |   1 +
>   testcases/kernel/fs/squashfs/Makefile     |   9 ++
>   testcases/kernel/fs/squashfs/squashfs01.c | 121 ++++++++++++++++++++++
>   4 files changed, 133 insertions(+)
>   create mode 100644 testcases/kernel/fs/squashfs/.gitignore
>   create mode 100644 testcases/kernel/fs/squashfs/Makefile
>   create mode 100644 testcases/kernel/fs/squashfs/squashfs01.c
>
> diff --git a/runtest/fs b/runtest/fs
> index 17b1415eb..1d753e0dd 100644
> --- a/runtest/fs
> +++ b/runtest/fs
> @@ -85,3 +85,5 @@ fs_fill fs_fill
>
>   binfmt_misc01 binfmt_misc01.sh
>   binfmt_misc02 binfmt_misc02.sh
> +
> +squashfs01 squashfs01
> diff --git a/testcases/kernel/fs/squashfs/.gitignore b/testcases/kernel/fs/squashfs/.gitignore
> new file mode 100644
> index 000000000..d28920fe8
> --- /dev/null
> +++ b/testcases/kernel/fs/squashfs/.gitignore
> @@ -0,0 +1 @@
> +squashfs01
> diff --git a/testcases/kernel/fs/squashfs/Makefile b/testcases/kernel/fs/squashfs/Makefile
> new file mode 100644
> index 000000000..67021139c
> --- /dev/null
> +++ b/testcases/kernel/fs/squashfs/Makefile
> @@ -0,0 +1,9 @@
> +# SPDX-License-Identifier: GPL-2.0-or-later
> +# Copyright (C) 2009, Cisco Systems Inc.
> +# Ngie Cooper, July 2009
> +
> +top_srcdir		?= ../../../..
> +
> +include $(top_srcdir)/include/mk/testcases.mk
> +
> +include $(top_srcdir)/include/mk/generic_leaf_target.mk
> diff --git a/testcases/kernel/fs/squashfs/squashfs01.c b/testcases/kernel/fs/squashfs/squashfs01.c
> new file mode 100644
> index 000000000..f02c91f83
> --- /dev/null
> +++ b/testcases/kernel/fs/squashfs/squashfs01.c
> @@ -0,0 +1,121 @@
> +// SPDX-License-Identifier: GPL-2.0-or-later
> +/*
> + * Copyright (c) 2021 Joerg Vehlow<joerg.vehlow@aox-tech.de>
> + */
> +
> +/*\
> + * [Description]
> + *
> + * Kernel commits
> + *
> + * - f37aa4c7366 (squashfs: add more sanity checks in id lookup)
> + * - eabac19e40c (squashfs: add more sanity checks in inode lookup)
> + * - 506220d2ba2 (squashfs: add more sanity checks in xattr id lookup)
> + *
> + * added some sanity checks, that verify the size of
> + * inode lookup, id (uid/gid) and xattr blocks in the squashfs,
> + * but broke mounting filesystems with completely filled blocks.
> + * A block has a max size of 8192.
> + * An inode lookup entry has an uncompressed size of 8 bytes,
> + * an id block 4 bytes and an xattr block 16 bytes.
> + *
> + *
> + * To fill up at least one block for each of the three tables,
> + * 2048 files with unique uid/gid and xattr are created.
> + *
> + *
> + * The bugs are fixed in kernel commits
> + *
> + * - c1b2028315c (squashfs: fix inode lookup sanity checks)
> + * - 8b44ca2b634 (squashfs: fix xattr id and id lookup sanity checks)
> + */
> +
> +#include<stdio.h>
> +#include<sys/mount.h>
> +
> +#include "tst_test.h"
> +#include "tst_safe_macros.h"
> +
> +static const char *MOUNT_DIR = "mnt";
> +static const char *DATA_DIR = "data";
> +
> +static int mounted;
> +
> +static void cleanup(void)
> +{
> +	if (mounted)
> +		SAFE_UMOUNT("mnt");
> +}
> +
> +static void setup(void)
> +{
> +	int i;
> +
> +	SAFE_MKDIR(DATA_DIR, 0777);
> +
> +	for (i = 0; i<  2048; ++i) {
> +		int fd;
> +		char name[20];
> +
> +		sprintf(name, "%s/%d", DATA_DIR, i);
> +		fd = SAFE_OPEN(name, O_CREAT | O_EXCL, 0666);
> +		SAFE_FCHOWN(fd, i, i);
> +
> +		/* This must be either "security", "user" or "trusted" namespace,
> +		 * because squashfs cannot store other namespaces.
> +		 * Since the files are most likely created on a tmpfs,
> +		 * "user" namespace is not possible, because it is not allowed.
> +		 */
> +		SAFE_FSETXATTR(fd, "security.x",&i, sizeof(i), 0);
> +		close(fd);
> +	}
> +
> +	/* Create squashfs without any compression.
> +	 * This allows reasoning about block sizes.
> +	 * Redirect stdout, to get rid of undefined uid messages
> +	 */
> +	const char *argv[] = {
> +		"mksquashfs", DATA_DIR, tst_device->dev,
> +		"-noappend", "-noI", "-noD", "-noX", "-noF", NULL
> +	};
> +	tst_cmd(argv, "/dev/null", NULL, 0);
We have SAFE_CMD api.
> +
> +	SAFE_MKDIR(MOUNT_DIR, 0777);
> +}
> +
> +static void run(void)
> +{
> +	tst_res(TINFO, "Test squashfs sanity check regressions");
> +
> +	if (mount(tst_device->dev, MOUNT_DIR, "squashfs", 0, NULL) != 0)
> +		tst_brk(TFAIL | TERRNO, "Mount failed");
> +	mounted = 1;
> +
> +	SAFE_UMOUNT("mnt");
> +	mounted = 0;
> +
> +	tst_res(TPASS, "Test passed");
> +}
> +
> +static struct tst_test test = {
> +	.test_all = run,
> +	.cleanup = cleanup,
> +	.setup = setup,
> +	.needs_root = 1,
> +	.needs_device = 1,
> +	.dev_min_size = 1,
> +	.needs_cmds = (const char *const []) {
> +		"mksquashfs",
> +		NULL
> +	},
> +	.needs_drivers = (const char *const []) {
> +		"squashfs",
> +		NULL
> +	},
> +	.tags = (const struct tst_tag[]) {
> +		{"linux-git", "c1b2028315c"},
> +		{"linux-git", "8b44ca2b634"},
> +		{}
> +	},
> +	.needs_tmpdir = 1,
needs_device has enabled needs_tmpdir in internal, so we don't need to 
set it here.
> +};
Joerg Vehlow July 15, 2021, 8:44 a.m. UTC | #3
Hi,


On 7/15/2021 10:21 AM, xuyang2018.jy@fujitsu.com wrote:
>
>> +	tst_cmd(argv, "/dev/null", NULL, 0);
> We have SAFE_CMD api.
Yes makes sense. This can be replaced during merge I guess.
-       tst_cmd(argv, "/dev/null", NULL, 0);
+       SAFE_CMD(argv, "/dev/null", NULL);
>> +static struct tst_test test = {
>> +	.test_all = run,
>> +	.cleanup = cleanup,
>> +	.setup = setup,
>> +	.needs_root = 1,
>> +	.needs_device = 1,
>> +	.dev_min_size = 1,
>> +	.needs_cmds = (const char *const []) {
>> +		"mksquashfs",
>> +		NULL
>> +	},
>> +	.needs_drivers = (const char *const []) {
>> +		"squashfs",
>> +		NULL
>> +	},
>> +	.tags = (const struct tst_tag[]) {
>> +		{"linux-git", "c1b2028315c"},
>> +		{"linux-git", "8b44ca2b634"},
>> +		{}
>> +	},
>> +	.needs_tmpdir = 1,
> needs_device has enabled needs_tmpdir in internal, so we don't need to
> set it here.
Honestly I hate implicitness like that. I think if the test itself needs 
the tmpdir, it should state it and not rely on some other "needs_*" 
stuff to also enable it.
But if whoever merges this agrees with you, he can change it...

Joerg
Cyril Hrubis July 15, 2021, 9:27 a.m. UTC | #4
Hi!
> >> +static struct tst_test test = {
> >> +	.test_all = run,
> >> +	.cleanup = cleanup,
> >> +	.setup = setup,
> >> +	.needs_root = 1,
> >> +	.needs_device = 1,
> >> +	.dev_min_size = 1,
> >> +	.needs_cmds = (const char *const []) {
> >> +		"mksquashfs",
> >> +		NULL
> >> +	},
> >> +	.needs_drivers = (const char *const []) {
> >> +		"squashfs",
> >> +		NULL
> >> +	},
> >> +	.tags = (const struct tst_tag[]) {
> >> +		{"linux-git", "c1b2028315c"},
> >> +		{"linux-git", "8b44ca2b634"},
> >> +		{}
> >> +	},
> >> +	.needs_tmpdir = 1,
> > needs_device has enabled needs_tmpdir in internal, so we don't need to
> > set it here.
> Honestly I hate implicitness like that. I think if the test itself needs 
> the tmpdir, it should state it and not rely on some other "needs_*" 
> stuff to also enable it.
> But if whoever merges this agrees with you, he can change it...

We tend to avoid listing full subtree of dependencies, in this case it's
not that bad, but it tends to get out of hand quickly.

For instance mount_device flag needs implies format_device which implies
needs_device which implies needs_tmpdir.

Also the dev_min_size = 1 does not have any efect here, since it can be
used only to request bigger-than-default size and gets ignored here. I
guess that we can merge this as it is and I will add needs_loopdev to
the tst_test structure later which will just allocate loop device and
pass it down to the test.
Cyril Hrubis July 15, 2021, 10:09 a.m. UTC | #5
Hi!
> > For instance mount_device flag needs implies format_device which implies
> > needs_device which implies needs_tmpdir.
> I agree with that. If needs_tmpdir was only required, because 
> needs_device is required, I wouldn't add it.
> But if needs_device implementation is changed, the test still needs a 
> tmpdir. That's why I would always vote for adding it here.

The .needs_device flag implies .needs_tmpdir that's a part of the test
library API.

> > Also the dev_min_size = 1 does not have any efect here, since it can be
> > used only to request bigger-than-default size and gets ignored here. I
> > guess that we can merge this as it is and I will add needs_loopdev to
> > the tst_test structure later which will just allocate loop device and
> > pass it down to the test.
> This is true, but the test should also specify what it needs. If for 
> whatever reason DEV_SIZE_MB is redefined to a smaller value, the test 
> would still work.

The DEV_SIZE_MB will never go backward, this is actually the minimal
size that is needed in order to create all supported Linux filesystems
and we need to bump the size up every few years. I think that it was
100MB when I started to work on LTP and it got up to 256MB, which is
also the reason the tests cannot know and why this is hidden in the
library.

> To be honest, for "1" it doesn't matter. But it it was bigger, it makes 
> total sense to specify the size if the test knows it...

Also LTP allows to be passed a real block device to the tests, in a case
that you want to test a block driver, in which case the test has no
exact controll on the device size, which is also the reason why we
allow minimal size to be specified but not exact size.

> I don't understand why a lot of developers like implicit definitions so 
> much more over explicit definitions.
> I could understand it for language intrinsic stuff, because that is (or 
> could be) known to all developers.
> But for someone, who rarely works on a project or switches between 
> different projects implicit information is bad!

I think that we can actually make things better by adding all of the
text I've written above as a top level description in the tst_device.c.
Joerg Vehlow July 15, 2021, 10:12 a.m. UTC | #6
Hi Cyril,

On 7/15/2021 11:27 AM, Cyril Hrubis wrote:
> Hi!
>>>> +static struct tst_test test = {
>>>> +	.test_all = run,
>>>> +	.cleanup = cleanup,
>>>> +	.setup = setup,
>>>> +	.needs_root = 1,
>>>> +	.needs_device = 1,
>>>> +	.dev_min_size = 1,
>>>> +	.needs_cmds = (const char *const []) {
>>>> +		"mksquashfs",
>>>> +		NULL
>>>> +	},
>>>> +	.needs_drivers = (const char *const []) {
>>>> +		"squashfs",
>>>> +		NULL
>>>> +	},
>>>> +	.tags = (const struct tst_tag[]) {
>>>> +		{"linux-git", "c1b2028315c"},
>>>> +		{"linux-git", "8b44ca2b634"},
>>>> +		{}
>>>> +	},
>>>> +	.needs_tmpdir = 1,
>>> needs_device has enabled needs_tmpdir in internal, so we don't need to
>>> set it here.
>> Honestly I hate implicitness like that. I think if the test itself needs
>> the tmpdir, it should state it and not rely on some other "needs_*"
>> stuff to also enable it.
>> But if whoever merges this agrees with you, he can change it...
> We tend to avoid listing full subtree of dependencies, in this case it's
> not that bad, but it tends to get out of hand quickly.
>
> For instance mount_device flag needs implies format_device which implies
> needs_device which implies needs_tmpdir.
I agree with that. If needs_tmpdir was only required, because 
needs_device is required, I wouldn't add it.
But if needs_device implementation is changed, the test still needs a 
tmpdir. That's why I would always vote for adding it here.
> Also the dev_min_size = 1 does not have any efect here, since it can be
> used only to request bigger-than-default size and gets ignored here. I
> guess that we can merge this as it is and I will add needs_loopdev to
> the tst_test structure later which will just allocate loop device and
> pass it down to the test.
This is true, but the test should also specify what it needs. If for 
whatever reason DEV_SIZE_MB is redefined to a smaller value, the test 
would still work.
To be honest, for "1" it doesn't matter. But it it was bigger, it makes 
total sense to specify the size if the test knows it...

I don't understand why a lot of developers like implicit definitions so 
much more over explicit definitions.
I could understand it for language intrinsic stuff, because that is (or 
could be) known to all developers.
But for someone, who rarely works on a project or switches between 
different projects implicit information is bad!

Joerg
Joerg Vehlow July 15, 2021, 10:40 a.m. UTC | #7
Hi C

On 7/15/2021 12:09 PM, Cyril Hrubis wrote:
> Hi!
>>> For instance mount_device flag needs implies format_device which implies
>>> needs_device which implies needs_tmpdir.
>> I agree with that. If needs_tmpdir was only required, because
>> needs_device is required, I wouldn't add it.
>> But if needs_device implementation is changed, the test still needs a
>> tmpdir. That's why I would always vote for adding it here.
> The .needs_device flag implies .needs_tmpdir that's a part of the test
> library API.
>
>>> Also the dev_min_size = 1 does not have any efect here, since it can be
>>> used only to request bigger-than-default size and gets ignored here. I
>>> guess that we can merge this as it is and I will add needs_loopdev to
>>> the tst_test structure later which will just allocate loop device and
>>> pass it down to the test.
>> This is true, but the test should also specify what it needs. If for
>> whatever reason DEV_SIZE_MB is redefined to a smaller value, the test
>> would still work.
> The DEV_SIZE_MB will never go backward, this is actually the minimal
> size that is needed in order to create all supported Linux filesystems
> and we need to bump the size up every few years. I think that it was
> 100MB when I started to work on LTP and it got up to 256MB, which is
> also the reason the tests cannot know and why this is hidden in the
> library.
>
>> To be honest, for "1" it doesn't matter. But it it was bigger, it makes
>> total sense to specify the size if the test knows it...
> Also LTP allows to be passed a real block device to the tests, in a case
> that you want to test a block driver, in which case the test has no
> exact controll on the device size, which is also the reason why we
> allow minimal size to be specified but not exact size.
>
>> I don't understand why a lot of developers like implicit definitions so
>> much more over explicit definitions.
>> I could understand it for language intrinsic stuff, because that is (or
>> could be) known to all developers.
>> But for someone, who rarely works on a project or switches between
>> different projects implicit information is bad!
> I think that we can actually make things better by adding all of the
> text I've written above as a top level description in the tst_device.c.
>

I guess we agree to disagree on this matter. It is the same as the 
discussion mailinglist vs. github for patches.
Change the metadata in whatever way you like while merging.

Joerg
Cyril Hrubis July 21, 2021, 11:47 a.m. UTC | #8
Hi!
> > Also the dev_min_size = 1 does not have any efect here, since it can be
> > used only to request bigger-than-default size and gets ignored here. I
> > guess that we can merge this as it is and I will add needs_loopdev to
> > the tst_test structure later which will just allocate loop device and
> > pass it down to the test.
> This is true, but the test should also specify what it needs. If for 
> whatever reason DEV_SIZE_MB is redefined to a smaller value, the test 
> would still work.
> To be honest, for "1" it doesn't matter. But it it was bigger, it makes 
> total sense to specify the size if the test knows it...

I was thinking about it and we can easily allow the test to request
smaller than the default size with a pretty minimal change:

diff --git a/lib/tst_device.c b/lib/tst_device.c
index c91c6cd55..4ef802c41 100644
--- a/lib/tst_device.c
+++ b/lib/tst_device.c
@@ -300,7 +300,7 @@ const char *tst_acquire_device__(unsigned int size)
        unsigned int acq_dev_size;
        uint64_t ltp_dev_size;

-       acq_dev_size = MAX(size, DEV_SIZE_MB);
+       acq_dev_size = size ? size : DEV_SIZE_MB;

        dev = getenv("LTP_DEV");


This shouldn't break anything while it allows better controll for the
test over the device size.
Cyril Hrubis Aug. 4, 2021, 2:05 p.m. UTC | #9
Hi!
Pushed with minor changes, thanks.

Apart from removing the needs_tmpdir I've also changed the TPASS message
to something more meaningful and move the TINFO message to setup so that
it's not printed on each iteration.

Full diff:

diff --git a/testcases/kernel/fs/squashfs/squashfs01.c b/testcases/kernel/fs/squashfs/squashfs01.c
index f02c91f83..502de419d 100644
--- a/testcases/kernel/fs/squashfs/squashfs01.c
+++ b/testcases/kernel/fs/squashfs/squashfs01.c
@@ -51,6 +51,8 @@ static void setup(void)
 {
 	int i;
 
+	tst_res(TINFO, "Test squashfs sanity check regressions");
+
 	SAFE_MKDIR(DATA_DIR, 0777);
 
 	for (i = 0; i < 2048; ++i) {
@@ -85,8 +87,6 @@ static void setup(void)
 
 static void run(void)
 {
-	tst_res(TINFO, "Test squashfs sanity check regressions");
-
 	if (mount(tst_device->dev, MOUNT_DIR, "squashfs", 0, NULL) != 0)
 		tst_brk(TFAIL | TERRNO, "Mount failed");
 	mounted = 1;
@@ -94,7 +94,7 @@ static void run(void)
 	SAFE_UMOUNT("mnt");
 	mounted = 0;
 
-	tst_res(TPASS, "Test passed");
+	tst_res(TPASS, "Regression not detected");
 }
 
 static struct tst_test test = {
@@ -117,5 +117,4 @@ static struct tst_test test = {
 		{"linux-git", "8b44ca2b634"},
 		{}
 	},
-	.needs_tmpdir = 1,
 };
diff mbox series

Patch

diff --git a/runtest/fs b/runtest/fs
index 17b1415eb..1d753e0dd 100644
--- a/runtest/fs
+++ b/runtest/fs
@@ -85,3 +85,5 @@  fs_fill fs_fill
 
 binfmt_misc01 binfmt_misc01.sh
 binfmt_misc02 binfmt_misc02.sh
+
+squashfs01 squashfs01
diff --git a/testcases/kernel/fs/squashfs/.gitignore b/testcases/kernel/fs/squashfs/.gitignore
new file mode 100644
index 000000000..d28920fe8
--- /dev/null
+++ b/testcases/kernel/fs/squashfs/.gitignore
@@ -0,0 +1 @@ 
+squashfs01
diff --git a/testcases/kernel/fs/squashfs/Makefile b/testcases/kernel/fs/squashfs/Makefile
new file mode 100644
index 000000000..67021139c
--- /dev/null
+++ b/testcases/kernel/fs/squashfs/Makefile
@@ -0,0 +1,9 @@ 
+# SPDX-License-Identifier: GPL-2.0-or-later
+# Copyright (C) 2009, Cisco Systems Inc.
+# Ngie Cooper, July 2009
+
+top_srcdir		?= ../../../..
+
+include $(top_srcdir)/include/mk/testcases.mk
+
+include $(top_srcdir)/include/mk/generic_leaf_target.mk
diff --git a/testcases/kernel/fs/squashfs/squashfs01.c b/testcases/kernel/fs/squashfs/squashfs01.c
new file mode 100644
index 000000000..f02c91f83
--- /dev/null
+++ b/testcases/kernel/fs/squashfs/squashfs01.c
@@ -0,0 +1,121 @@ 
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2021 Joerg Vehlow <joerg.vehlow@aox-tech.de>
+ */
+
+/*\
+ * [Description]
+ *
+ * Kernel commits
+ *
+ * - f37aa4c7366 (squashfs: add more sanity checks in id lookup)
+ * - eabac19e40c (squashfs: add more sanity checks in inode lookup)
+ * - 506220d2ba2 (squashfs: add more sanity checks in xattr id lookup)
+ *
+ * added some sanity checks, that verify the size of
+ * inode lookup, id (uid/gid) and xattr blocks in the squashfs,
+ * but broke mounting filesystems with completely filled blocks.
+ * A block has a max size of 8192.
+ * An inode lookup entry has an uncompressed size of 8 bytes,
+ * an id block 4 bytes and an xattr block 16 bytes.
+ *
+ *
+ * To fill up at least one block for each of the three tables,
+ * 2048 files with unique uid/gid and xattr are created.
+ *
+ *
+ * The bugs are fixed in kernel commits
+ *
+ * - c1b2028315c (squashfs: fix inode lookup sanity checks)
+ * - 8b44ca2b634 (squashfs: fix xattr id and id lookup sanity checks)
+ */
+
+#include <stdio.h>
+#include <sys/mount.h>
+
+#include "tst_test.h"
+#include "tst_safe_macros.h"
+
+static const char *MOUNT_DIR = "mnt";
+static const char *DATA_DIR = "data";
+
+static int mounted;
+
+static void cleanup(void)
+{
+	if (mounted)
+		SAFE_UMOUNT("mnt");
+}
+
+static void setup(void)
+{
+	int i;
+
+	SAFE_MKDIR(DATA_DIR, 0777);
+
+	for (i = 0; i < 2048; ++i) {
+		int fd;
+		char name[20];
+
+		sprintf(name, "%s/%d", DATA_DIR, i);
+		fd = SAFE_OPEN(name, O_CREAT | O_EXCL, 0666);
+		SAFE_FCHOWN(fd, i, i);
+
+		/* This must be either "security", "user" or "trusted" namespace,
+		 * because squashfs cannot store other namespaces.
+		 * Since the files are most likely created on a tmpfs,
+		 * "user" namespace is not possible, because it is not allowed.
+		 */
+		SAFE_FSETXATTR(fd, "security.x", &i, sizeof(i), 0);
+		close(fd);
+	}
+
+	/* Create squashfs without any compression.
+	 * This allows reasoning about block sizes.
+	 * Redirect stdout, to get rid of undefined uid messages
+	 */
+	const char *argv[] = {
+		"mksquashfs", DATA_DIR, tst_device->dev,
+		"-noappend", "-noI", "-noD", "-noX", "-noF", NULL
+	};
+	tst_cmd(argv, "/dev/null", NULL, 0);
+
+	SAFE_MKDIR(MOUNT_DIR, 0777);
+}
+
+static void run(void)
+{
+	tst_res(TINFO, "Test squashfs sanity check regressions");
+
+	if (mount(tst_device->dev, MOUNT_DIR, "squashfs", 0, NULL) != 0)
+		tst_brk(TFAIL | TERRNO, "Mount failed");
+	mounted = 1;
+
+	SAFE_UMOUNT("mnt");
+	mounted = 0;
+
+	tst_res(TPASS, "Test passed");
+}
+
+static struct tst_test test = {
+	.test_all = run,
+	.cleanup = cleanup,
+	.setup = setup,
+	.needs_root = 1,
+	.needs_device = 1,
+	.dev_min_size = 1,
+	.needs_cmds = (const char *const []) {
+		"mksquashfs",
+		NULL
+	},
+	.needs_drivers = (const char *const []) {
+		"squashfs",
+		NULL
+	},
+	.tags = (const struct tst_tag[]) {
+		{"linux-git", "c1b2028315c"},
+		{"linux-git", "8b44ca2b634"},
+		{}
+	},
+	.needs_tmpdir = 1,
+};