File read(i.e. using vfs_read()) from LKM init_module() - linux

I would like to read files from my LKM "initialization" function so that I can config the LKM from some configuration files.
I'm wondering if it is not a good practice to read files even from the initialization function of LKM; I heard that it is NOT recommended to read files from LKM after all kernel was initialized.
Please advice me.
Thank you.
Daum

Reading from/writing to files from the kernel is definitely not recommended.
The Kernel Newbies wiki page describes it quite nicely.
For several reasons:
Selecting where and in what format to read/write data is a policy and policy does not belong to kernel. A userland daemon is much
easier to replace with one that receives or sends the data over a
network, generates or converts them from/to different format etc.
Filesystem operations need a user context (i.e.: current != NULL). You can't be sure you're in user context so you can't write something
from (for example) an interrupt handler.
The kernel allows multiple filesystem namespaces for user processes. Which one should it use? How do you make sure it indeed
uses the one you want?
Kernel should not depend on particular layout of a filesystem nor on availability of writable filesystem. The location of the file is
a policy decision and policy decisions should be done in userspace.
Maybe you want to dump the kernel output in a remote MySQL server
tomorrow, that kind of policy is so much easier in userland.
Kernel code should be kept simple and stupid, because any bug in it is likely to have serious consequences. Working with files requires
being aware of various locking issues and would add unnecessary
complexity.
If you want to configure the behaviour of the kernel module you're writing, you can pass module parameters that configure it on start up. Alternatively, your module can expose interfaces to sysfs that can be used to configure it at run time.

Related

Mounting FS from Kernel

I am experimenting eCryptfs. It is quite good. I have encrypted one directory which is having some confidential data. I can view/edit this data by mounting it via ecrypts tools. While mounting it does ask me password. So I write a short script which will be non-interactive. All is good so far.
Now I am afraid that if someone reads this script then he might see that confidential data. So thinking if I write a short and simple kernel module, which will mount this directory for me OR this module will create a script upon insertion, which I can execute while boot up from initramfs itself and delete this script immediately once it's work done.
I am not sure that is this possible at all! If possible then is it ethical to do so?
If possible then it will be really helpful if someone guides me in proper direction.
Underlying OS is Ubuntu-22.04 and I am using custom kernel i.e. 5.15.85

Hooking into Windows File System and Insert Virtual File System

I'm working on an application similar to a program called Mod Organizer. Essentially what the program does is let people download and install mods to the game, Skyrim. However, Mod Organizer does something interesting; rather than install the mods directly to the game's data directory (like other mod managers), MO installs each mod to its own directory in some other arbitrary location and then loads all the mods together once the game launches. This is important because it makes mod managing much less of a hassle.
My question is: how might I create this on the fly file system or make Windows "pretend" a directory full of mod files is somewhere else.
At first I thought of creating symlinks with my code, but This guide put me onto the trail of "hooking," and specifically recommended trying EasyHook. While I think can understand the underlying concept of hooking (essentially intercepting signals from the OS and redirecting them for whatever purpose), I don't really know how to make the hook actually redirect files.
If anyone knows a good resource for this kind of hooking or has better approach to my problem, I'd appreciate the help.
What you have described in done with a filesystem filter driver. This driver intercepts requests to the filesystem and inserts additional information, such as tells the system about the files and directories which don't really exist on the disk. If the files are preset somewhere on the disk, the request can be simply redirected to the existing file or directory.
Filesystem filter driver is a kernel-mode driver, not easy to implement. You can use a pre-created driver that lets you perform tasks in user mode API, eg. our CBFS Filter.

Win32API/Win drivers: How to detect if file is accessed

I would like to create something like "file honeypot" on Windows OS.
The problem I would like to answer is this:
I need to detect that file is accessed (Malware wants to read file to send it over internet) so I can react to it. But I do not know how exacly tackle this thing.
I can periodically test file - Do not like this sollution. Would like some event driven without need to bother processor every few ms. But could work if file is huge enought so it cannot be read between checks.
I could exclusively open file myselve and somehow detect if file is accessed. But I have no idea how to do this thing.
Any idea about how to resolve this issue effectively? Maybe creating specialized driver could help but I have little experience in this.
Thanks
Tracking (and possibly preventing) filesystem access on Windows is accomplished using filesystem filter drivers. But you must be aware that kernel-mode code (rootkits etc) can bypass the filter driver stack and send the request directly to the filesystem. In this case only the filesystem driver itself can log or intercept access.
I'm going to assume that what you're writing is a relatively simple honeypot. The integrity of the system on which you're running has not been compromised, there is no rootkit or filter driver installation by malware and there is no process running that can implement avoidance or anti-avoidance measures.
The most likely scenario I can think of is that a server process running on the computer is subject to some kind of external control which would allow files containing sensitive data to be read remotely. It could be a web server, a mail server, an FTP server or something else but I assume nothing else on the computer has been compromised. And the task at hand is to watch particular files and see if anything is reading them.
With these assumptions a file system watcher will not help. It can monitor parts of the system for the creation of new files or modification or deletion of existing ones, but as far as I know it cannot monitor for read only access.
The only event-driven mechanism I am aware of is a filter driver. This is a specialised piece of driver software that can be inserted into the driver chain and monitor access to files. With the constraints above, it is a reliable solution to the problem at the cost of being quite hard to write.
If a polling mechanism is sufficient then I can see two avenues. One is to try to lock the file exclusively, which will fail if it is open. This is easy, but slow.
The other is to monitor the open file handles. I know it can be done because I know programs that do it, but I can't tell you how without some research.
If my assumptions are wrong, please edit your question and provide additional information.

How can I sandbox filesystem activity, particularly writes?

Gentoo has a feature in portage, that prevents and logs writes outside of the build and packaging directories.
Checkinstall is able to monitor writes, and package up all the generated files after completion.
Autotools have the DESTDIR macro that enables you to usually direct most of the filesystem activity to an alternate location.
How can I do this myself with the
safety of the Gentoo sandboxing
method?
Can I use SELinux, rlimit, or
some other resource limiting API?
What APIs are available do this from
C, Python?
Update0
The mechanism used will not require root privileges or any involved/persistent system modification. This rules out creating users and using chroot().
Please link to the documentation for APIs that you mention, for some reason they're exceptionally difficult to find.
Update1
This is to prevent accidents. I'm not worried about malicious code, only the poorly written variety.
The way Debian handles this sort of problem is to not run the installation code as root in the first place. Package build scripts are run as a normal user, and install scripts are run using fakeroot - this LD_PRELOAD library redirects permission-checking calls to make it look like the installer is actually running as root, so the resulting file ownership and permissions are right (ie, if you run /usr/bin/install from within the fakeroot environment, further stats from within the environment show proper root ownership), but in fact the installer is run as an ordinary user.
Builds are also, in some cases (primarily for development), done in chroots using eg pbuilder - this is likely easier on a binary distribution however, as each build using pbuilder reinstalls all dependencies beyond the base system, acting as a test that all necessary dependencies are specified (this is the primary reason for using a chroot; not for protection against accidental installs)
One approach is to virtualize a process, similar to how wine does it, and reinterpret file paths. That's rather heavy duty to implement though.
A more elegant approach is to use the chroot() system call which sets a subtree of the filesystem as a process's root directory. Create a virtual subtree, including /bin, /tmp, /usr, /etc as you want the process to see them, call chroot with the virtual tree, then exec the target executable. I can't recall if it is possible to have symbolic links within the tree reference files outside, but I don't think so. But certainly everything needed could be copied into the sandbox, and then when it is done, check for changes against the originals.
Maybe get the sandbox safety with regular user permissions? So the process running the show has specific access to specific directories.
chroot would be an option but I can't figure out how to track these tries to write outside the root.
Another idea would be along the lines of intercepting system calls. I don't know much about this but strace is a start, try running a program through it and check if you see something you like.
edit:
is using kernel modules an option? because you could replace the write system call with your own so you could prevent whatever you needed and also log it.
It sounds a bit like what you are describing is containers. Once you've got the container infrastructure set up, it's pretty cheap to create containers, and they're quite secure.
There are two methods to do this. One is to use LD_PRELOAD to hook library calls that result in syscalls, such as those in libc, and call dlsym/dlopen. This will not allow you to directly hook syscalls.
The second method, which allows hooking syscalls, is to run your executable under ptrace, which provides options to stop and examine syscalls when they occur. This can be set up programmatically to sandbox calls to restricted areas of the filesystem, among other things.
LD_PRELOAD can not intercept syscalls, but only libcalls?
Dynamic linker tricks: Using LD_PRELOAD to cheat, inject features and investigate programs
Write Yourself an Strace in 70 Lines of Code

Running external code in a restricted environment (linux)

For reasons beyond the scope of this post, I want to run external (user submitted) code similar to the computer language benchmark game. Obviously this needs to be done in a restricted environment. Here are my restriction requirements:
Can only read/write to current working directory (will be large tempdir)
No external access (internet, etc)
Anything else I probably don't care about (e.g., processor/memory usage, etc).
I myself have several restrictions. A solution which uses standard *nix functionality (specifically RHEL 5.x) would be preferred, as then I could use our cluster for the backend. It is also difficult to get software installed there, so something in the base distribution would be optimal.
Now, the questions:
Can this even be done with externally compiled binaries? It seems like it could be possible, but also like it could just be hopeless.
What about if we force the code itself to be submitted, and compile it ourselves. Does that make the problem easier or harder?
Should I just give up on home directory protection, and use a VM/rollback? What about blocking external communication (isn't the VM usually talked to over a bridged LAN connection?)
Something I missed?
Possibly useful ideas:
rssh. Doesn't help with compiled code though
Using a VM with rollback after code finishes (can network be configured so there is a local bridge but no WAN bridge?). Doesn't work on cluster.
I would examine and evaluate both a VM and a special SELinux context.
I don't think you'll be able to do what you need with simple file system protection because you won't be able to prevent access to syscalls which will allow access to the network etc. You can probably use AppArmor to do what you need though. That uses the kernel and virtualizes the foreign binary.

Resources