Re: [PATCH v8 8/9] tmpfs: Expose filesystem features via sysfs

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

 



Hi Nathan,

Em 31/10/2024 02:18, Nathan Chancellor escreveu:
Hi André,

On Mon, Oct 21, 2024 at 01:37:24PM -0300, André Almeida wrote:
Expose filesystem features through sysfs, so userspace can query if
tmpfs support casefold.

This follows the same setup as defined by ext4 and f2fs to expose
casefold support to userspace.

Signed-off-by: André Almeida <andrealmeid@xxxxxxxxxx>
Reviewed-by: Gabriel Krisman Bertazi <krisman@xxxxxxx>
---
  mm/shmem.c | 37 +++++++++++++++++++++++++++++++++++++
  1 file changed, 37 insertions(+)

diff --git a/mm/shmem.c b/mm/shmem.c
index ea01628e443423d82d44277e085b867ab9bf4b28..0739143d1419c732359d3a3c3457c3acb90c5b22 100644
--- a/mm/shmem.c
+++ b/mm/shmem.c
@@ -5546,3 +5546,40 @@ struct page *shmem_read_mapping_page_gfp(struct address_space *mapping,
  	return page;
  }
  EXPORT_SYMBOL_GPL(shmem_read_mapping_page_gfp);
+
+#if defined(CONFIG_SYSFS) && defined(CONFIG_TMPFS)
+#if IS_ENABLED(CONFIG_UNICODE)
+static DEVICE_STRING_ATTR_RO(casefold, 0444, "supported");
+#endif
+
+static struct attribute *tmpfs_attributes[] = {
+#if IS_ENABLED(CONFIG_UNICODE)
+	&dev_attr_casefold.attr.attr,
+#endif
+	NULL
+};
+
+static const struct attribute_group tmpfs_attribute_group = {
+	.attrs = tmpfs_attributes,
+	.name = "features"
+};
+
+static struct kobject *tmpfs_kobj;
+
+static int __init tmpfs_sysfs_init(void)
+{
+	int ret;
+
+	tmpfs_kobj = kobject_create_and_add("tmpfs", fs_kobj);
+	if (!tmpfs_kobj)
+		return -ENOMEM;
+
+	ret = sysfs_create_group(tmpfs_kobj, &tmpfs_attribute_group);
+	if (ret)
+		kobject_put(tmpfs_kobj);
+
+	return ret;
+}
+
+fs_initcall(tmpfs_sysfs_init);
+#endif /* CONFIG_SYSFS && CONFIG_TMPFS */

--
2.47.0


This change as commit 5132f08bd332 ("tmpfs: Expose filesystem features
via sysfs") in -next introduces a kCFI violation when accessing
/sys/fs/tmpfs/features/casefold. An attribute group created with
sysfs_create_group() has ->sysfs_ops() set to kobj_sysfs_ops, which has
a ->show() value of kobj_attr_show(). When kobj_attr_show() goes to call
the attribute's ->show() value after container_of(), there will be a
type mismatch in the case of the casefold attr, as it was defined with a
->show() value of device_show_string() but that does not match the type
of ->show() in 'struct kobj_attribute'.

I can easily reproduce this with the following commands:

   $ printf 'CONFIG_%s=y\n' CFI_CLANG UNICODE >kernel/configs/repro.config

   $ make -skj"$(nproc)" ARCH=arm64 LLVM=1 mrproper virtconfig repro.config Image.gz
   ...

   $ curl -LSs https://github.com/ClangBuiltLinux/boot-utils/releases/download/20230707-182910/arm64-rootfs.cpio.zst | zstd -d >rootfs.cpio

   $ qemu-system-aarch64 \
       -display none \
       -nodefaults \
       -cpu max,pauth-impdef=true \
       -machine virt,gic-version=max,virtualization=true \
       -append 'console=ttyAMA0 earlycon rdinit=/bin/sh' \
       -kernel arch/arm64/boot/Image.gz \
       -initrd rootfs.cpio \
       -m 512m \
       -serial mon:stdio
   ...
   # mount -t sysfs sys /sys
   # cat /sys/fs/tmpfs/features/casefold
   [   70.558496] CFI failure at kobj_attr_show+0x2c/0x4c (target: device_show_string+0x0/0x38; expected type: 0xc527b809)
   [   70.560018] Internal error: Oops - CFI: 00000000f2008228 [#1] PREEMPT SMP
   [   70.560647] Modules linked in:
   [   70.561770] CPU: 0 UID: 0 PID: 46 Comm: cat Not tainted 6.12.0-rc4-00008-g5132f08bd332 #1
   [   70.562429] Hardware name: linux,dummy-virt (DT)
   [   70.562897] pstate: 21402009 (nzCv daif +PAN -UAO -TCO +DIT -SSBS BTYPE=--)
   [   70.563377] pc : kobj_attr_show+0x2c/0x4c
   [   70.563674] lr : sysfs_kf_seq_show+0xb4/0x130
   [   70.563987] sp : ffff80008043bac0
   [   70.564236] x29: ffff80008043bac0 x28: 000000007ffff001 x27: 0000000000000000
   [   70.564877] x26: 0000000001000000 x25: 000000007ffff001 x24: 0000000000000001
   [   70.565339] x23: fff000000238a000 x22: ffff9fa31a3996f8 x21: fff00000023fc000
   [   70.565806] x20: fff000000201df80 x19: fff000000238b000 x18: 0000000000000000
   [   70.566273] x17: 00000000c527b809 x16: 00000000df43c25c x15: fff000001fef8200
   [   70.566727] x14: 0000000000000000 x13: fff00000022450f0 x12: 0000000000001000
   [   70.567177] x11: fff00000023fc000 x10: 0000000000000000 x9 : ffff9fa31a18fac4
   [   70.567682] x8 : ffff9fa319badde4 x7 : 0000000000000000 x6 : 000000000000003f
   [   70.568138] x5 : 0000000000000040 x4 : 0000000000000000 x3 : 0000000000000004
   [   70.568585] x2 : fff00000023fc000 x1 : ffff9fa31a881f90 x0 : fff000000201df80
   [   70.569169] Call trace:
   [   70.569389]  kobj_attr_show+0x2c/0x4c
   [   70.569706]  sysfs_kf_seq_show+0xb4/0x130
   [   70.570020]  kernfs_seq_show+0x44/0x54
   [   70.570280]  seq_read_iter+0x14c/0x4b0
   [   70.570543]  kernfs_fop_read_iter+0x60/0x198
   [   70.570820]  copy_splice_read+0x1f0/0x2f4
   [   70.571092]  splice_direct_to_actor+0xf4/0x2e0
   [   70.571376]  do_splice_direct+0x68/0xb8
   [   70.571626]  do_sendfile+0x1e8/0x488
   [   70.571874]  __arm64_sys_sendfile64+0xe0/0x12c
   [   70.572161]  invoke_syscall+0x58/0x114
   [   70.572424]  el0_svc_common+0xa8/0xdc
   [   70.572676]  do_el0_svc+0x1c/0x28
   [   70.572910]  el0_svc+0x38/0x68
   [   70.573132]  el0t_64_sync_handler+0x90/0xfc
   [   70.573394]  el0t_64_sync+0x190/0x19
   [   70.574001] Code: 72970131 72b8a4f1 6b11021f 54000040 (d4304500)
   [   70.574635] ---[ end trace 0000000000000000 ]---

I am not sure if there is a better API exists or if a local copy should
be rolled but I think the current scheme is definitely wrong because
there is no 'struct device' here.


Thank you for the report, I'm trying to fix it, it seems I have used something for device drivers in a filesystem. I wonder how btrfs doesn't get this error, since tmpfs_sysfs_init() is very similar to btrfs_init_sysfs().

If there is any patch I can test or further information I can provide, I
am more than happy to do so.

Cheers,
Nathan





[Index of Archives]     [Linux ARM Kernel]     [Linux ARM]     [Linux Omap]     [Fedora ARM]     [IETF Annouce]     [Bugtraq]     [Linux OMAP]     [Linux MIPS]     [eCos]     [Asterisk Internet PBX]     [Linux API]

  Powered by Linux