Suppose I have a Linux executable, which fails to perform some operation with EPERM (Permission Denied) error code. I also, can track the specific API it calls with strace. Suppose also, it caused because kernel check fails on specific user or executable capability, which is needed for this operation.
Is it possible to identify, somehow, the exact capability id that failed the check in kernel and caused generic EPERM error?
Now, I know that there's man page for capability which describes in general the existing capabilities, and how to use them. Still I wonder if there's away to automatically expose the capability that has to be added.
The goal of cause is to create user or file with minimum capability set that us sufficient to perform the task.
Related
I was looking if there exists a program in c/c++ which gives the process and thread information which access files within a given folder. Actually when my application is running all of sudden I am getting the "Reason = 13 (Permission denied)" for fopen() method call. I have tried googling this, but I didn't get relevant information. There is a chance of other applications also access the file. So I would like to log the process and thread information when I got the above mentioned error. I am unaware of anything which does this and would like to know if one exists.
The error says that you don't have permissions to access the file. See Traditional Unix permissions
for more details.
This error is not related to the file being used by other processes.
I have created a script and I want it to be virtually "immune" to SIGSTOP.
I understand that both SIGKILL and SIGSTOP cannot be trapped or ignored.
I know that the init system for Linux cannot receive a "fatal" signal due to it having the SIGNAL_UNKILLABLE flag on its signal struct flags (although the latter half of that sentence flies over my head for the most part).
I'm willing to edit my kernel to grant this script immunity, the only problem is that I don't know how.
So, my question is, is there a way to nullify SIGSTOP for a certain script/process?
I was able to deal with SIGKILL thanks to the Restart parameter in the service file for my script (using systemd), and while I have scrolled through the manuals looking for something similar for suspended processes, I haven't found anything yet.
Is there anything similar to Restart=always for process suspension caused by SIGSTOP?
I would rather not have to go through the process of changing things in or related to the kernel, but if it's the only way I will.
Thanks.
Okay so the best solution I can come up with is SELinux.
SELinux is a kernel add-on created by the NSA that was later released to the public. It is commonly used on Linux systems and comes by default on Android devices. SELinux allows the creation of "contexts". Contexts are an additional label provided to files and processes that allow the subdivision of responsibility and permissions.
How does this solve your problem? Well, you can limit your SELinux permissions for your user processes (even for the root user) so that you're not even allowed to signal this other process at all. In fact, you can prevent any interaction with it whatsoever. If you'd like, you could go so far as to prevent yourself from even being able to turn SELinux off (although it's probably better that you don't if you can avoid it from an operational perspective). This is at some level probably the closest you'll get to a solution that is anywhere near the range of not-hackable. That being said, SELinux setup and configuration for this purpose is not exactly a walk in the park. Documentation is limited (but exists), distro-specific, and in some cases even esoteric. I do have some experience with SELinux myself.
Edit:
Doing some quick googling, it appears possible to install SELinux on Arch, but like most things on Arch, it requires some effort - more than should fit in a StackOverflow comment block. However I'll briefly describe your set of goals here once SELinux is installed:
Determine the context that you are currently in. Using the "id" command should provide this context.
Use a context process transition so that when you execute your script, that script runs in a new context. You will probably need to create a new context for your script to run in.
Create sepolicy rules allowing that script to interact with your processes however you need. Perhaps this includes the ability to kill other processes in a different context, or read from a tcp port using sniffing, etc. etc. You can use the audit2allow program to help you create these rules.
By default, SELinux denies anything it doesn't explicitly allow. Your goal now is to make sure that everything you might want to do on your system is allowed, and add policy rules to allow all those things. Looking at the SELinux audit logs is a great way to see everything SELinux is complaining about - it's your job to go through and convert all those audit failures into "allow" rules.
Once all that is done, just make sure not to "allow" whatever context your processes/shell start in from being able to kill or signal the context that your script runs in, and you should be done. Now trying to SIGSTOP or SIGKILL should generate a "Permission denied error".
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.
What's the best way to compute a minimal set of Linux capabilities for any process?
Suppose you're hardening an operating system and some of you tools may require CAP_NET_ADMIN and related network privileges while other tools may require CAP_SYS_NICE. There should be a way to tell for each executable which capabilities are really required.
Two possible approaches to determine required capabilities at runtime:
Subsequently run your program under strace without root privileges. Determine which system calls failed with EPERM and add corresponding capabilities to your program. Repeat this until all capabilities are gathered.
Use SystemTap, DTrace or Kprobes to log or
intercept capability checks in kernel made for your program. (e.g. use capable from BCC tools suite as described here)
Unit tests with good coverage will help a lot, I guess. Also note that capabilities(7) manual page lists system calls that may require each capability (although it is not a complete list).
Update:
The article referenced by #RodrigoBelem mentions capable_probe module, which is based on KProbes.
Original article with this module was "POSIX file capabilities: Parceling the power of root" and it's not availble now (it was hosted here). But you can find the source code and some docs in the Internet.
I have a bunch of programs which use IPC Semaphores to interact (semget).
One of the programs is an Apache module, which runs in (some sort of) restricted SELinux context (which I don't understand too well).
The module is capable of interacting with any regular files correctly, if of-course the files have their SELinux security context set appropriately.
However - when my (Module) goes to access the IPC Semaphore, the semget call fails with a EPERM. When SELinux is turned off, I don't get this error.
So - there is obviously something I need to do to set some sort of SELinux security context or something on the Semaphore for this to work. If it was a regular file, I could just call "chcon" on it. Since it's a System-V IPC Semaphore, I can't do that.
What can I do to make this work??
The basic steps to get SELinux working with the changes you need are:
Enable permissive mode
Capture denials
Add a new policy module or modify an existing policy module
Enable enforcing mode and test
Exactly how to do these steps depends on what Linux distribution you are using; here are references for CentOS, Debian, Gentoo, RedHat and Ubuntu. You can also find SELinux information from NSA. The best documentation I found is from Gentoo: step 1, step 2, step 3, step 4.
As #smassey noted, you most probably need to modify some IPC permission.
SELinux has persmission setting for more than just regular files, but also device and special files.
http://seedit.sourceforge.net/doc/access_vectors/access_vectors.html#SECTION00044000000000000000 is what you're looking for. Give read/write/etc permissions to the "sem" object.
Cheers