1f08c3bdfSopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later 2f08c3bdfSopenharmony_ci/* 3f08c3bdfSopenharmony_ci * Copyright (c) 2021 Joerg Vehlow <joerg.vehlow@aox-tech.de> 4f08c3bdfSopenharmony_ci */ 5f08c3bdfSopenharmony_ci 6f08c3bdfSopenharmony_ci/*\ 7f08c3bdfSopenharmony_ci * [Description] 8f08c3bdfSopenharmony_ci * 9f08c3bdfSopenharmony_ci * Kernel commits 10f08c3bdfSopenharmony_ci * 11f08c3bdfSopenharmony_ci * - f37aa4c7366 (squashfs: add more sanity checks in id lookup) 12f08c3bdfSopenharmony_ci * - eabac19e40c (squashfs: add more sanity checks in inode lookup) 13f08c3bdfSopenharmony_ci * - 506220d2ba2 (squashfs: add more sanity checks in xattr id lookup) 14f08c3bdfSopenharmony_ci * 15f08c3bdfSopenharmony_ci * added some sanity checks, that verify the size of 16f08c3bdfSopenharmony_ci * inode lookup, id (uid/gid) and xattr blocks in the squashfs, 17f08c3bdfSopenharmony_ci * but broke mounting filesystems with completely filled blocks. 18f08c3bdfSopenharmony_ci * A block has a max size of 8192. 19f08c3bdfSopenharmony_ci * An inode lookup entry has an uncompressed size of 8 bytes, 20f08c3bdfSopenharmony_ci * an id block 4 bytes and an xattr block 16 bytes. 21f08c3bdfSopenharmony_ci * 22f08c3bdfSopenharmony_ci * 23f08c3bdfSopenharmony_ci * To fill up at least one block for each of the three tables, 24f08c3bdfSopenharmony_ci * 2048 files with unique uid/gid and xattr are created. 25f08c3bdfSopenharmony_ci * 26f08c3bdfSopenharmony_ci * 27f08c3bdfSopenharmony_ci * The bugs are fixed in kernel commits 28f08c3bdfSopenharmony_ci * 29f08c3bdfSopenharmony_ci * - c1b2028315c (squashfs: fix inode lookup sanity checks) 30f08c3bdfSopenharmony_ci * - 8b44ca2b634 (squashfs: fix xattr id and id lookup sanity checks) 31f08c3bdfSopenharmony_ci */ 32f08c3bdfSopenharmony_ci 33f08c3bdfSopenharmony_ci#include <stdio.h> 34f08c3bdfSopenharmony_ci#include <sys/mount.h> 35f08c3bdfSopenharmony_ci 36f08c3bdfSopenharmony_ci#include "tst_test.h" 37f08c3bdfSopenharmony_ci#include "tst_safe_macros.h" 38f08c3bdfSopenharmony_ci 39f08c3bdfSopenharmony_cistatic const char *MOUNT_DIR = "mnt"; 40f08c3bdfSopenharmony_cistatic const char *DATA_DIR = "data"; 41f08c3bdfSopenharmony_ci 42f08c3bdfSopenharmony_cistatic int mounted; 43f08c3bdfSopenharmony_ci 44f08c3bdfSopenharmony_cistatic void cleanup(void) 45f08c3bdfSopenharmony_ci{ 46f08c3bdfSopenharmony_ci if (mounted) 47f08c3bdfSopenharmony_ci SAFE_UMOUNT("mnt"); 48f08c3bdfSopenharmony_ci} 49f08c3bdfSopenharmony_ci 50f08c3bdfSopenharmony_cistatic void setup(void) 51f08c3bdfSopenharmony_ci{ 52f08c3bdfSopenharmony_ci int i; 53f08c3bdfSopenharmony_ci 54f08c3bdfSopenharmony_ci tst_res(TINFO, "Test squashfs sanity check regressions"); 55f08c3bdfSopenharmony_ci 56f08c3bdfSopenharmony_ci SAFE_MKDIR(DATA_DIR, 0777); 57f08c3bdfSopenharmony_ci 58f08c3bdfSopenharmony_ci for (i = 0; i < 2048; ++i) { 59f08c3bdfSopenharmony_ci int fd; 60f08c3bdfSopenharmony_ci char name[20]; 61f08c3bdfSopenharmony_ci 62f08c3bdfSopenharmony_ci sprintf(name, "%s/%d", DATA_DIR, i); 63f08c3bdfSopenharmony_ci fd = SAFE_OPEN(name, O_CREAT | O_EXCL, 0666); 64f08c3bdfSopenharmony_ci SAFE_FCHOWN(fd, i, i); 65f08c3bdfSopenharmony_ci 66f08c3bdfSopenharmony_ci /* This must be either "security", "user" or "trusted" namespace, 67f08c3bdfSopenharmony_ci * because squashfs cannot store other namespaces. 68f08c3bdfSopenharmony_ci * Since the files are most likely created on a tmpfs, 69f08c3bdfSopenharmony_ci * "user" namespace is not possible, because it is not allowed. 70f08c3bdfSopenharmony_ci */ 71f08c3bdfSopenharmony_ci SAFE_FSETXATTR(fd, "security.x", &i, sizeof(i), 0); 72f08c3bdfSopenharmony_ci close(fd); 73f08c3bdfSopenharmony_ci } 74f08c3bdfSopenharmony_ci 75f08c3bdfSopenharmony_ci /* Create squashfs without any compression. 76f08c3bdfSopenharmony_ci * This allows reasoning about block sizes. 77f08c3bdfSopenharmony_ci * Redirect stdout, to get rid of undefined uid messages 78f08c3bdfSopenharmony_ci */ 79f08c3bdfSopenharmony_ci const char *argv[] = { 80f08c3bdfSopenharmony_ci "mksquashfs", DATA_DIR, tst_device->dev, 81f08c3bdfSopenharmony_ci "-noappend", "-noI", "-noD", "-noX", "-noF", NULL 82f08c3bdfSopenharmony_ci }; 83f08c3bdfSopenharmony_ci tst_cmd(argv, "/dev/null", NULL, 0); 84f08c3bdfSopenharmony_ci 85f08c3bdfSopenharmony_ci SAFE_MKDIR(MOUNT_DIR, 0777); 86f08c3bdfSopenharmony_ci} 87f08c3bdfSopenharmony_ci 88f08c3bdfSopenharmony_cistatic void run(void) 89f08c3bdfSopenharmony_ci{ 90f08c3bdfSopenharmony_ci if (mount(tst_device->dev, MOUNT_DIR, "squashfs", 0, NULL) != 0) 91f08c3bdfSopenharmony_ci tst_brk(TFAIL | TERRNO, "Mount failed"); 92f08c3bdfSopenharmony_ci mounted = 1; 93f08c3bdfSopenharmony_ci 94f08c3bdfSopenharmony_ci SAFE_UMOUNT("mnt"); 95f08c3bdfSopenharmony_ci mounted = 0; 96f08c3bdfSopenharmony_ci 97f08c3bdfSopenharmony_ci tst_res(TPASS, "Regression not detected"); 98f08c3bdfSopenharmony_ci} 99f08c3bdfSopenharmony_ci 100f08c3bdfSopenharmony_cistatic struct tst_test test = { 101f08c3bdfSopenharmony_ci .test_all = run, 102f08c3bdfSopenharmony_ci .cleanup = cleanup, 103f08c3bdfSopenharmony_ci .setup = setup, 104f08c3bdfSopenharmony_ci .needs_root = 1, 105f08c3bdfSopenharmony_ci .needs_device = 1, 106f08c3bdfSopenharmony_ci .dev_min_size = 1, 107f08c3bdfSopenharmony_ci .needs_cmds = (const char *const []) { 108f08c3bdfSopenharmony_ci "mksquashfs", 109f08c3bdfSopenharmony_ci NULL 110f08c3bdfSopenharmony_ci }, 111f08c3bdfSopenharmony_ci .needs_drivers = (const char *const []) { 112f08c3bdfSopenharmony_ci "squashfs", 113f08c3bdfSopenharmony_ci NULL 114f08c3bdfSopenharmony_ci }, 115f08c3bdfSopenharmony_ci .tags = (const struct tst_tag[]) { 116f08c3bdfSopenharmony_ci {"linux-git", "c1b2028315c"}, 117f08c3bdfSopenharmony_ci {"linux-git", "8b44ca2b634"}, 118f08c3bdfSopenharmony_ci {} 119f08c3bdfSopenharmony_ci }, 120f08c3bdfSopenharmony_ci}; 121