From e097935e606d2e39ba1bd1f931c95e7fbbd86969 Mon Sep 17 00:00:00 2001 From: g2px1 Date: Fri, 20 Jun 2025 20:27:15 +0000 Subject: [PATCH] 3 --- .gitignore | 3 +- .libfs.o.d | 252 +++++++++++++++++++++++++++++++++++++++++++++++++++++ init.bash | 4 + libfs.c | 182 +++++++++++++++++++++++++++++++++++--- 4 files changed, 426 insertions(+), 15 deletions(-) create mode 100644 .libfs.o.d create mode 100755 init.bash diff --git a/.gitignore b/.gitignore index 9f65fff..def033f 100644 --- a/.gitignore +++ b/.gitignore @@ -4,9 +4,10 @@ *.mod.c *.mod.o *.o +*.log CMakeLists.txt Module.symvers modules.order .idea cmake-build-debug -build \ No newline at end of file +build diff --git a/.libfs.o.d b/.libfs.o.d new file mode 100644 index 0000000..ffcfc4f --- /dev/null +++ b/.libfs.o.d @@ -0,0 +1,252 @@ +libfs.o: /home/ubuntu/FS/libfs.c include/linux/compiler-version.h \ + include/linux/kconfig.h include/generated/autoconf.h \ + include/linux/compiler_types.h include/linux/compiler_attributes.h \ + include/linux/compiler-gcc.h include/linux/module.h include/linux/list.h \ + include/linux/types.h include/uapi/linux/types.h \ + arch/x86/include/generated/uapi/asm/types.h \ + include/uapi/asm-generic/types.h include/asm-generic/int-ll64.h \ + include/uapi/asm-generic/int-ll64.h \ + arch/x86/include/uapi/asm/bitsperlong.h \ + include/asm-generic/bitsperlong.h include/uapi/asm-generic/bitsperlong.h \ + include/uapi/linux/posix_types.h include/linux/stddef.h \ + include/uapi/linux/stddef.h include/linux/compiler_types.h \ + arch/x86/include/asm/posix_types.h \ + arch/x86/include/uapi/asm/posix_types_64.h \ + include/uapi/asm-generic/posix_types.h include/linux/poison.h \ + include/linux/const.h include/vdso/const.h include/uapi/linux/const.h \ + include/linux/kernel.h include/linux/stdarg.h include/linux/align.h \ + include/linux/limits.h include/uapi/linux/limits.h include/vdso/limits.h \ + include/linux/linkage.h include/linux/stringify.h include/linux/export.h \ + include/linux/compiler.h arch/x86/include/generated/asm/rwonce.h \ + include/asm-generic/rwonce.h include/linux/kasan-checks.h \ + include/linux/kcsan-checks.h arch/x86/include/asm/linkage.h \ + include/linux/bitops.h include/linux/bits.h include/vdso/bits.h \ + include/linux/build_bug.h include/linux/typecheck.h \ + include/uapi/linux/kernel.h include/uapi/linux/sysinfo.h \ + arch/x86/include/asm/bitops.h arch/x86/include/asm/alternative.h \ + arch/x86/include/asm/asm.h arch/x86/include/asm/extable_fixup_types.h \ + arch/x86/include/asm/rmwcc.h arch/x86/include/asm/barrier.h \ + arch/x86/include/asm/nops.h include/asm-generic/barrier.h \ + include/asm-generic/bitops/find.h include/asm-generic/bitops/sched.h \ + arch/x86/include/asm/arch_hweight.h arch/x86/include/asm/cpufeatures.h \ + arch/x86/include/asm/required-features.h \ + arch/x86/include/asm/disabled-features.h \ + include/asm-generic/bitops/const_hweight.h \ + include/asm-generic/bitops/instrumented-atomic.h \ + include/linux/instrumented.h \ + include/asm-generic/bitops/instrumented-non-atomic.h \ + include/asm-generic/bitops/instrumented-lock.h \ + include/asm-generic/bitops/le.h arch/x86/include/uapi/asm/byteorder.h \ + include/linux/byteorder/little_endian.h \ + include/uapi/linux/byteorder/little_endian.h include/linux/swab.h \ + include/uapi/linux/swab.h arch/x86/include/uapi/asm/swab.h \ + include/linux/byteorder/generic.h \ + include/asm-generic/bitops/ext2-atomic-setbit.h include/linux/kstrtox.h \ + include/linux/log2.h include/linux/math.h arch/x86/include/asm/div64.h \ + include/asm-generic/div64.h include/linux/minmax.h include/linux/panic.h \ + include/linux/printk.h include/linux/init.h include/linux/kern_levels.h \ + include/linux/cache.h arch/x86/include/asm/cache.h \ + include/linux/ratelimit_types.h include/uapi/linux/param.h \ + arch/x86/include/generated/uapi/asm/param.h include/asm-generic/param.h \ + include/uapi/asm-generic/param.h include/linux/spinlock_types.h \ + include/linux/spinlock_types_raw.h arch/x86/include/asm/spinlock_types.h \ + include/asm-generic/qspinlock_types.h \ + include/asm-generic/qrwlock_types.h include/linux/lockdep_types.h \ + include/linux/rwlock_types.h include/linux/once_lite.h \ + include/linux/dynamic_debug.h include/linux/jump_label.h \ + arch/x86/include/asm/jump_label.h include/linux/static_call_types.h \ + include/linux/stat.h arch/x86/include/uapi/asm/stat.h \ + include/uapi/linux/stat.h include/linux/time.h include/linux/math64.h \ + include/vdso/math64.h include/linux/time64.h include/vdso/time64.h \ + include/uapi/linux/time.h include/uapi/linux/time_types.h \ + include/linux/time32.h include/linux/timex.h include/uapi/linux/timex.h \ + arch/x86/include/asm/timex.h arch/x86/include/asm/processor.h \ + arch/x86/include/asm/processor-flags.h \ + arch/x86/include/uapi/asm/processor-flags.h include/linux/mem_encrypt.h \ + arch/x86/include/asm/mem_encrypt.h include/linux/cc_platform.h \ + arch/x86/include/uapi/asm/bootparam.h include/linux/screen_info.h \ + include/uapi/linux/screen_info.h include/linux/apm_bios.h \ + include/uapi/linux/apm_bios.h include/uapi/linux/ioctl.h \ + arch/x86/include/generated/uapi/asm/ioctl.h include/asm-generic/ioctl.h \ + include/uapi/asm-generic/ioctl.h include/linux/edd.h \ + include/uapi/linux/edd.h arch/x86/include/asm/ist.h \ + arch/x86/include/uapi/asm/ist.h include/video/edid.h \ + include/uapi/video/edid.h arch/x86/include/asm/math_emu.h \ + arch/x86/include/asm/ptrace.h arch/x86/include/asm/segment.h \ + arch/x86/include/asm/page_types.h arch/x86/include/asm/page_64_types.h \ + arch/x86/include/asm/kaslr.h arch/x86/include/uapi/asm/ptrace.h \ + arch/x86/include/uapi/asm/ptrace-abi.h \ + arch/x86/include/asm/paravirt_types.h arch/x86/include/asm/desc_defs.h \ + arch/x86/include/asm/pgtable_types.h \ + arch/x86/include/asm/pgtable_64_types.h arch/x86/include/asm/sparsemem.h \ + arch/x86/include/asm/nospec-branch.h include/linux/static_key.h \ + include/linux/objtool.h arch/x86/include/asm/msr-index.h \ + arch/x86/include/asm/unwind_hints.h arch/x86/include/asm/orc_types.h \ + arch/x86/include/asm/percpu.h include/asm-generic/percpu.h \ + include/linux/threads.h include/linux/percpu-defs.h \ + arch/x86/include/asm/GEN-for-each-reg.h arch/x86/include/asm/proto.h \ + arch/x86/include/uapi/asm/ldt.h arch/x86/include/uapi/asm/sigcontext.h \ + arch/x86/include/asm/current.h arch/x86/include/asm/page.h \ + arch/x86/include/asm/page_64.h include/linux/range.h \ + include/asm-generic/memory_model.h include/linux/pfn.h \ + include/asm-generic/getorder.h arch/x86/include/asm/msr.h \ + arch/x86/include/asm/msr-index.h \ + arch/x86/include/generated/uapi/asm/errno.h \ + include/uapi/asm-generic/errno.h include/uapi/asm-generic/errno-base.h \ + arch/x86/include/asm/cpumask.h include/linux/cpumask.h \ + include/linux/bitmap.h include/linux/string.h include/linux/err.h \ + include/linux/errno.h include/uapi/linux/errno.h \ + include/linux/overflow.h include/uapi/linux/string.h \ + arch/x86/include/asm/string.h arch/x86/include/asm/string_64.h \ + include/linux/fortify-string.h include/linux/atomic.h \ + arch/x86/include/asm/atomic.h arch/x86/include/asm/cmpxchg.h \ + arch/x86/include/asm/cmpxchg_64.h arch/x86/include/asm/atomic64_64.h \ + include/linux/atomic/atomic-arch-fallback.h \ + include/linux/atomic/atomic-long.h \ + include/linux/atomic/atomic-instrumented.h include/linux/bug.h \ + arch/x86/include/asm/bug.h include/linux/instrumentation.h \ + include/asm-generic/bug.h arch/x86/include/uapi/asm/msr.h \ + include/linux/tracepoint-defs.h arch/x86/include/asm/paravirt.h \ + arch/x86/include/asm/frame.h arch/x86/include/asm/special_insns.h \ + include/linux/irqflags.h arch/x86/include/asm/irqflags.h \ + arch/x86/include/asm/fpu/types.h arch/x86/include/asm/vmxfeatures.h \ + arch/x86/include/asm/vdso/processor.h include/linux/personality.h \ + include/uapi/linux/personality.h arch/x86/include/asm/tsc.h \ + arch/x86/include/asm/cpufeature.h include/vdso/time32.h \ + include/vdso/time.h include/linux/uidgid.h include/linux/highuid.h \ + include/linux/buildid.h include/linux/mm_types.h \ + include/linux/mm_types_task.h arch/x86/include/asm/tlbbatch.h \ + include/linux/auxvec.h include/uapi/linux/auxvec.h \ + arch/x86/include/uapi/asm/auxvec.h include/linux/spinlock.h \ + include/linux/preempt.h arch/x86/include/asm/preempt.h \ + include/linux/thread_info.h include/linux/restart_block.h \ + arch/x86/include/asm/thread_info.h include/linux/bottom_half.h \ + include/linux/lockdep.h include/linux/smp.h include/linux/smp_types.h \ + include/linux/llist.h arch/x86/include/asm/smp.h \ + arch/x86/include/generated/asm/mmiowb.h include/asm-generic/mmiowb.h \ + arch/x86/include/asm/spinlock.h arch/x86/include/asm/qspinlock.h \ + include/asm-generic/qspinlock.h arch/x86/include/asm/qrwlock.h \ + include/asm-generic/qrwlock.h include/linux/rwlock.h \ + include/linux/spinlock_api_smp.h include/linux/rwlock_api_smp.h \ + include/linux/rbtree.h include/linux/rbtree_types.h \ + include/linux/rcupdate.h include/linux/rcutree.h include/linux/rwsem.h \ + include/linux/osq_lock.h include/linux/completion.h \ + include/linux/swait.h include/linux/wait.h include/uapi/linux/wait.h \ + include/linux/uprobes.h arch/x86/include/asm/uprobes.h \ + include/linux/notifier.h include/linux/mutex.h \ + include/linux/debug_locks.h include/linux/srcu.h \ + include/linux/workqueue.h include/linux/timer.h include/linux/ktime.h \ + include/linux/jiffies.h include/vdso/jiffies.h \ + include/generated/timeconst.h include/vdso/ktime.h \ + include/linux/timekeeping.h include/linux/clocksource_ids.h \ + include/linux/debugobjects.h include/linux/rcu_segcblist.h \ + include/linux/srcutree.h include/linux/rcu_node_tree.h \ + include/linux/page-flags-layout.h include/linux/numa.h \ + include/generated/bounds.h include/linux/seqlock.h \ + include/linux/ww_mutex.h include/linux/rtmutex.h \ + arch/x86/include/asm/mmu.h include/linux/kmod.h include/linux/umh.h \ + include/linux/gfp.h include/linux/mmdebug.h include/linux/mmzone.h \ + include/linux/nodemask.h include/linux/pageblock-flags.h \ + include/linux/page-flags.h include/linux/local_lock.h \ + include/linux/local_lock_internal.h include/linux/memory_hotplug.h \ + arch/x86/include/asm/mmzone.h arch/x86/include/asm/mmzone_64.h \ + include/linux/topology.h include/linux/arch_topology.h \ + include/linux/percpu.h arch/x86/include/asm/topology.h \ + arch/x86/include/asm/mpspec.h arch/x86/include/asm/mpspec_def.h \ + arch/x86/include/asm/x86_init.h arch/x86/include/asm/apicdef.h \ + include/asm-generic/topology.h include/linux/sysctl.h \ + include/uapi/linux/sysctl.h include/linux/elf.h \ + arch/x86/include/asm/elf.h arch/x86/include/asm/user.h \ + arch/x86/include/asm/user_64.h arch/x86/include/asm/fsgsbase.h \ + arch/x86/include/asm/vdso.h include/uapi/linux/elf.h \ + include/uapi/linux/elf-em.h include/linux/kobject.h \ + include/linux/sysfs.h include/linux/kernfs.h include/linux/idr.h \ + include/linux/radix-tree.h include/linux/xarray.h \ + include/linux/kconfig.h include/linux/kobject_ns.h include/linux/kref.h \ + include/linux/refcount.h include/linux/moduleparam.h \ + include/linux/rbtree_latch.h include/linux/error-injection.h \ + include/asm-generic/error-injection.h include/linux/cfi.h \ + arch/x86/include/asm/module.h include/asm-generic/module.h \ + arch/x86/include/asm/orc_types.h include/linux/fs.h \ + include/linux/wait_bit.h include/linux/kdev_t.h \ + include/uapi/linux/kdev_t.h include/linux/dcache.h \ + include/linux/rculist.h include/linux/rculist_bl.h \ + include/linux/list_bl.h include/linux/bit_spinlock.h \ + include/linux/lockref.h include/linux/stringhash.h include/linux/hash.h \ + include/linux/path.h include/linux/list_lru.h include/linux/shrinker.h \ + include/linux/pid.h include/linux/capability.h \ + include/uapi/linux/capability.h include/linux/semaphore.h \ + include/linux/fcntl.h include/uapi/linux/fcntl.h \ + arch/x86/include/generated/uapi/asm/fcntl.h \ + include/uapi/asm-generic/fcntl.h include/uapi/linux/openat2.h \ + include/linux/migrate_mode.h include/linux/percpu-rwsem.h \ + include/linux/rcuwait.h include/linux/sched/signal.h \ + include/linux/signal.h include/linux/signal_types.h \ + include/uapi/linux/signal.h arch/x86/include/asm/signal.h \ + arch/x86/include/uapi/asm/signal.h \ + include/uapi/asm-generic/signal-defs.h \ + arch/x86/include/uapi/asm/siginfo.h include/uapi/asm-generic/siginfo.h \ + include/linux/sched.h include/uapi/linux/sched.h include/linux/sem.h \ + include/uapi/linux/sem.h include/linux/ipc.h \ + include/linux/rhashtable-types.h include/uapi/linux/ipc.h \ + arch/x86/include/generated/uapi/asm/ipcbuf.h \ + include/uapi/asm-generic/ipcbuf.h arch/x86/include/uapi/asm/sembuf.h \ + include/linux/shm.h include/uapi/linux/shm.h \ + include/uapi/asm-generic/hugetlb_encode.h \ + arch/x86/include/uapi/asm/shmbuf.h include/uapi/asm-generic/shmbuf.h \ + arch/x86/include/asm/shmparam.h include/linux/plist.h \ + include/linux/hrtimer.h include/linux/hrtimer_defs.h \ + include/linux/timerqueue.h include/linux/seccomp.h \ + include/uapi/linux/seccomp.h arch/x86/include/asm/seccomp.h \ + arch/x86/include/asm/unistd.h arch/x86/include/uapi/asm/unistd.h \ + arch/x86/include/generated/uapi/asm/unistd_64.h \ + arch/x86/include/generated/asm/unistd_64_x32.h \ + arch/x86/include/generated/asm/unistd_32_ia32.h \ + arch/x86/include/asm/ia32_unistd.h include/asm-generic/seccomp.h \ + include/uapi/linux/unistd.h include/linux/resource.h \ + include/uapi/linux/resource.h \ + arch/x86/include/generated/uapi/asm/resource.h \ + include/asm-generic/resource.h include/uapi/asm-generic/resource.h \ + include/linux/latencytop.h include/linux/sched/prio.h \ + include/linux/sched/types.h include/linux/syscall_user_dispatch.h \ + include/linux/task_io_accounting.h include/linux/posix-timers.h \ + include/linux/alarmtimer.h include/linux/task_work.h \ + include/uapi/linux/rseq.h include/linux/kcsan.h \ + arch/x86/include/generated/asm/kmap_size.h \ + include/asm-generic/kmap_size.h include/linux/sched/jobctl.h \ + include/linux/sched/task.h include/linux/uaccess.h \ + include/linux/fault-inject-usercopy.h arch/x86/include/asm/uaccess.h \ + arch/x86/include/asm/smap.h arch/x86/include/asm/extable.h \ + arch/x86/include/asm/uaccess_64.h include/linux/cred.h \ + include/linux/key.h include/linux/assoc_array.h \ + include/linux/sched/user.h include/linux/percpu_counter.h \ + include/linux/ratelimit.h include/linux/rcu_sync.h \ + include/linux/delayed_call.h include/linux/uuid.h \ + include/uapi/linux/uuid.h include/linux/errseq.h include/linux/ioprio.h \ + include/linux/sched/rt.h include/linux/iocontext.h \ + include/uapi/linux/ioprio.h include/linux/fs_types.h \ + include/linux/mount.h include/linux/mnt_idmapping.h \ + include/uapi/linux/fs.h include/linux/quota.h \ + include/uapi/linux/dqblk_xfs.h include/linux/dqblk_v1.h \ + include/linux/dqblk_v2.h include/linux/dqblk_qtree.h \ + include/linux/projid.h include/uapi/linux/quota.h \ + include/linux/nfs_fs_i.h include/linux/pagemap.h include/linux/mm.h \ + include/linux/mmap_lock.h include/linux/percpu-refcount.h \ + include/linux/page_ext.h include/linux/stacktrace.h \ + include/linux/stackdepot.h include/linux/page_ref.h \ + include/linux/memremap.h include/linux/ioport.h include/linux/sizes.h \ + include/linux/pgtable.h arch/x86/include/asm/pgtable.h \ + arch/x86/include/asm/pkru.h arch/x86/include/asm/fpu/api.h \ + include/asm-generic/pgtable_uffd.h arch/x86/include/asm/pgtable_64.h \ + arch/x86/include/asm/fixmap.h arch/x86/include/uapi/asm/vsyscall.h \ + include/asm-generic/fixmap.h arch/x86/include/asm/pgtable-invert.h \ + include/linux/kasan.h include/linux/huge_mm.h \ + include/linux/sched/coredump.h include/linux/vmstat.h \ + include/linux/vm_event_item.h include/linux/highmem.h \ + include/linux/hardirq.h include/linux/context_tracking_state.h \ + include/linux/ftrace_irq.h include/linux/vtime.h \ + arch/x86/include/asm/hardirq.h arch/x86/include/asm/cacheflush.h \ + include/asm-generic/cacheflush.h include/linux/highmem-internal.h \ + include/linux/hugetlb_inline.h include/linux/namei.h \ + include/linux/slab.h include/linux/hashtable.h \ + include/generated/uapi/linux/version.h diff --git a/init.bash b/init.bash new file mode 100755 index 0000000..0d78cfc --- /dev/null +++ b/init.bash @@ -0,0 +1,4 @@ +#!/bin/bash + +sudo touch /home/ubuntu/FS/customfs.log +sudo chmod 666 /home/ubuntu/FS/customfs.log diff --git a/libfs.c b/libfs.c index 1524cc7..0167c77 100644 --- a/libfs.c +++ b/libfs.c @@ -14,6 +14,18 @@ #define MODE_BOOKS 01777 #define MODE_AUTHORS 0777 #define MODE_AUTHOR_SUBDIR 01777 +#define logf(fmt, ...) \ + do { \ + printk(KERN_INFO "customfs: " fmt "\n", ##__VA_ARGS__); \ + struct file *f = filp_open("/home/ubuntu/FS/customfs.log", O_WRONLY | O_CREAT | O_APPEND, 0644); \ + if (!IS_ERR(f)) { \ + char __buf[256]; \ + int __len = snprintf(__buf, sizeof(__buf), fmt "\n", ##__VA_ARGS__); \ + kernel_write(f, __buf, __len, &f->f_pos); \ + filp_close(f, NULL); \ + } \ + } while (0) + MODULE_LICENSE("GPL"); MODULE_AUTHOR("you"); @@ -47,6 +59,7 @@ static bool is_protected_dentry(struct dentry *d) { return strcmp(d->d_name.name, "books") == 0 || strcmp(d->d_name.name, "authors") == 0; } +#if 0 static struct inode *get_inode(struct super_block *sb, umode_t mode) { struct inode *inode = new_inode(sb); if (!inode) @@ -66,7 +79,21 @@ static struct inode *get_inode(struct super_block *sb, umode_t mode) { } return inode; } +#endif +static struct inode *get_inode(struct super_block *sb, umode_t mode) { + struct inode *inode = new_inode(sb); + if (!inode) + return NULL; + + inode_init_owner(&init_user_ns, inode, NULL, mode); + inode->i_ino = get_next_ino(); + inode->i_sb = sb; + inode->i_atime = inode->i_mtime = inode->i_ctime = current_time(inode); + return inode; +} + +#if 0 static int books_create(struct user_namespace *ns, struct inode *dir, struct dentry *dentry, umode_t mode, bool excl) { struct inode *inode = get_inode(dir->i_sb, S_IFREG | mode); @@ -77,6 +104,18 @@ static int books_create(struct user_namespace *ns, struct inode *dir, d_add(dentry, inode); return 0; } +#endif +static int books_create(struct user_namespace *ns, struct inode *dir, + struct dentry *dentry, umode_t mode, bool excl) { + struct inode *inode = get_inode(dir->i_sb, S_IFREG | mode); + if (!inode) + return -ENOMEM; + + inode->i_uid = current_fsuid(); + inode->i_fop = &custom_file_ops; + d_instantiate(dentry, inode); + return 0; +} static const struct inode_operations books_dir_iops = { .lookup = simple_lookup, @@ -87,41 +126,111 @@ static void remove_links_to_inode(struct inode *inode) { int bkt; struct link_entry *entry; struct hlist_node *tmp; + logf("remove_links_to_inode: start for inode %lu", inode->i_ino); + hash_for_each_safe(link_table, bkt, tmp, entry, node) { if (entry->target == inode) { + logf("removing link: dentry=%s", entry->link->d_name.name); d_delete(entry->link); dput(entry->link); hash_del(&entry->node); kfree(entry); - printk(KERN_INFO "customfs: removed link to inode %lu\n", inode->i_ino); } } } +#if 0 static int custom_mkdir(struct user_namespace *ns, struct inode *dir, struct dentry *dentry, umode_t mode) { - if (dir == global_sb->s_root->d_inode) - return -EPERM; + umode_t mode_only = dir->i_mode & 07777; + kuid_t uid = current_fsuid(); - if (S_ISDIR(dir->i_mode)) { - umode_t mode_only = dir->i_mode & 07777; - if ((mode_only == MODE_AUTHORS || mode_only == MODE_AUTHOR_SUBDIR) && - !uid_eq(current_fsuid(), dir->i_uid)) - return -EACCES; + logf("mkdir: parent ino=%lu, mode=%o, uid=%u, name=%s", + dir->i_ino, mode_only, from_kuid(&init_user_ns, uid), dentry->d_name.name); + + if (dir == global_sb->s_root->d_inode) { + logf("mkdir denied: attempt to create in root"); + return -EPERM; + } + + // В authors (0777): любой пользователь может создать свою папку + if (mode_only == MODE_AUTHORS) { + logf("mkdir in authors: allowed"); + } + + // В подкаталогах authors (01777): только владелец каталога может создавать + else if (mode_only == MODE_AUTHOR_SUBDIR && !uid_eq(uid, dir->i_uid)) { + logf("mkdir denied in subdir: uid mismatch (dir uid=%u)", + from_kuid(&init_user_ns, dir->i_uid)); + return -EACCES; } struct inode *inode = get_inode(dir->i_sb, S_IFDIR | MODE_AUTHOR_SUBDIR); - if (!inode) + if (!inode) { + logf("mkdir error: get_inode returned NULL"); return -ENOMEM; - - inode->i_uid = current_fsuid(); - d_add(dentry, inode); + } + + inode->i_uid = uid; + inode->i_op = &fs_dir_iops; + inode->i_fop = &simple_dir_operations; + + d_instantiate(dentry, inode); inc_nlink(dir); + + logf("mkdir success: created %s in ino=%lu by uid=%u", + dentry->d_name.name, dir->i_ino, from_kuid(&init_user_ns, uid)); + return 0; +} +#endif +static int custom_mkdir(struct user_namespace *ns, struct inode *dir, struct dentry *dentry, umode_t mode) { + umode_t mode_only = dir->i_mode & 07777; + kuid_t uid = current_fsuid(); + + logf("mkdir: parent ino=%lu, mode=%o, uid=%u, name=%s", + dir->i_ino, mode_only, from_kuid(&init_user_ns, uid), dentry->d_name.name); + + if (dir == global_sb->s_root->d_inode) { + logf("mkdir denied: attempt to create in root"); + return -EPERM; + } + + if (mode_only == MODE_AUTHORS) { + logf("mkdir in authors: allowed"); + } else if (mode_only == MODE_AUTHOR_SUBDIR && !uid_eq(uid, dir->i_uid)) { + logf("mkdir denied in subdir: uid mismatch (dir uid=%u)", + from_kuid(&init_user_ns, dir->i_uid)); + return -EACCES; + } + + struct inode *inode = get_inode(dir->i_sb, S_IFDIR | MODE_AUTHOR_SUBDIR); + if (!inode) { + logf("mkdir error: get_inode returned NULL"); + return -ENOMEM; + } + + inode->i_uid = uid; + inode->i_op = &fs_dir_iops; + inode->i_fop = &simple_dir_operations; + + d_instantiate(dentry, inode); + inc_nlink(dir); + + logf("mkdir success: created %s in ino=%lu by uid=%u", + dentry->d_name.name, dir->i_ino, from_kuid(&init_user_ns, uid)); return 0; } static int custom_unlink(struct inode *dir, struct dentry *dentry) { + logf("custom_unlink: dir ino=%lu, file=%s", dir->i_ino, dentry->d_name.name); + if (dir == global_sb->s_root->d_inode && is_protected_dentry(dentry)) return -EPERM; + + if (dir == books_inode) { + logf("custom_unlink: removing links to inode %lu", d_inode(dentry)->i_ino); + remove_links_to_inode(d_inode(dentry)); + } + return simple_unlink(dir, dentry); } @@ -169,8 +278,6 @@ static const struct inode_operations fs_dir_iops = { }; static void evict_inode(struct inode *inode) { - if (inode->i_sb == global_sb && inode->i_ino && S_ISREG(inode->i_mode)) - remove_links_to_inode(inode); clear_inode(inode); } @@ -180,6 +287,7 @@ static const struct super_operations fs_sops = { .evict_inode = evict_inode, }; +#if 0 static int fill_super(struct super_block *sb, void *data, int silent) { struct inode *root_inode = get_inode(sb, S_IFDIR | 0755); if (!root_inode) @@ -207,6 +315,7 @@ static int fill_super(struct super_block *sb, void *data, int silent) { struct inode *authors_inode = get_inode(sb, S_IFDIR | MODE_AUTHORS); if (!authors_inode) return -ENOMEM; + authors_inode->i_uid = current_fsuid(); authors_inode->i_op = &fs_dir_iops; authors_inode->i_fop = &simple_dir_operations; struct dentry *authors = d_alloc_name(root_dentry, "authors"); @@ -214,6 +323,50 @@ static int fill_super(struct super_block *sb, void *data, int silent) { return 0; } +#endif +static int fill_super(struct super_block *sb, void *data, int silent) { + struct inode *root_inode = get_inode(sb, S_IFDIR | 0755); + if (!root_inode) + return -ENOMEM; + + root_inode->i_op = &fs_dir_iops; + root_inode->i_fop = &simple_dir_operations; + + struct dentry *root_dentry = d_make_root(root_inode); + if (!root_dentry) + return -ENOMEM; + + sb->s_root = root_dentry; + sb->s_magic = FS_MAGIC; + sb->s_op = &fs_sops; + global_sb = sb; + + // books + books_inode = get_inode(sb, S_IFDIR | MODE_BOOKS); + if (!books_inode) + return -ENOMEM; + books_inode->i_op = &books_dir_iops; + books_inode->i_fop = &simple_dir_operations; + struct dentry *books = d_alloc_name(root_dentry, "books"); + if (!books) + return -ENOMEM; + d_add(books, books_inode); + + // authors + struct inode *authors_inode = get_inode(sb, S_IFDIR | MODE_AUTHORS); + if (!authors_inode) + return -ENOMEM; + authors_inode->i_uid = current_fsuid(); + authors_inode->i_op = &fs_dir_iops; + authors_inode->i_fop = &simple_dir_operations; + struct dentry *authors = d_alloc_name(root_dentry, "authors"); + if (!authors) + return -ENOMEM; + d_add(authors, authors_inode); + + logf("fill_super: books and authors created"); + return 0; +} static struct dentry *mount_fs(struct file_system_type *type, int flags, const char *dev, void *data) { return mount_nodev(type, flags, data, fill_super); @@ -237,3 +390,4 @@ static void __exit fs_exit(void) { module_init(fs_init); module_exit(fs_exit); +