Is there a way to nullify SIGSTOP for a certain script? - linux

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".

Related

Why use nohup when the app can be run as system service?

I put this question on stackoverflow, because I found lots of quesions on the topic here already.
Short introduction
Simply put, nohup can be used to run apps in the background and keeps them running after the user logs off or the terminal or ssh session is closed e.g.
There are many example quesitons here on stackoverflow, like this or that.
My question is simple.
Why opt for nohup, when there are options like upstart, systemd, ... which manage the app as service in a much more convenient way (runlevels, ...)?
Reading the many questions on similar topics, the only option seems to be nohup. Almost never the answer is something like: "... use an upstart script, so it is all handled for you..."
I would mainly go with e.g. upstart, except maybe for a quick and dirty test scenario.
Am I missing something important?
nohup is quick, easy, doesn't require root access and doesn't make permanent changes in the system. That's why many people use it (or try to use it) instead of configuring services.
Running things in the background without any supervision is usually a bad idea, although there are many legitimate use cases which don't fit traditional service model. For example:
Background process might be needed only sometimes, after certain user actions.
More than one instance might be needed. For example: one per user or one per session.
Process might not need to to be running all the time. It just quits after doing its job.
Some real world examples (which use something like nohup and would be hard to implement as system services):
git will sometimes run git gc in background to optimize repository without blocking user work
adb will start its service in background and keep it running until user asks to terminate it
Some compilers have option to keep running in the background to reduce startup times of subsequent invocations
Your understanding is correct, the way those questions were asked the natural answer is nohup - upstart would be the answer to a different question such as How to make sure an application keeps running on Linux

Intricacies of Launching a complex shell script from CGI

Ok, so over the past year I have built some rather complex automation scripts (mostly bash, but with some perl here and there) for some of the more common work we do at my place of business. They rely heavily on ImageMagick, Ghostscript, and PhantomJS to name just a few. They also traverse a huge number of directories across the network and several different file systems and host OSs... Frankly the fact that they work is a bit of a miracle and perhaps a testament to my willingness to keep beating my head against the wall... Also, trust me, this is easier and more effective than trying to corral my resources. Our archives are... organic... and certain high-ranking individuals in the company think of them as belonging to them and do not look out for the interests of the company in their management. They are, at least, relatively well backed-up these days.
In any case these scripts automate the production of a number of image-based print-ready products of varying degrees of complexity up to multi-hundred page image-heavy books, and as such some of them accept absurdly complex argument structures to do all the things they do. (P.S. embedded Javascript in SVGS is a MAGICAL thing!) These systems have been in "working beta" for a while now, which basically means I've been hand entering the commands at a terminal to run them, and I want to move them up to production and offer them as a webservice so that those in production who are not friends with the command line can use them, and to also potentially integrate them with our new custom-developed order management system.
TL;DR below
so that's the background, the problem is this:
I'm running everything on a headless CentOS 6.4 virtual machine with SELINUX disabled.
Apache2 serves up my interface.sh CGI just fine, and the internet has already helped me make the POST data into shell variables. Now I need to launch the worker scripts that actually direct the heavy lifting and coordinate the binaries... from the CGI:
#get post data from form and make it into variables...
/bin/bash /path/to/script/worker.sh $arg1 $arg2 $arg3 $arg5 $arg6 $opt1 $arg7
Nothing.
httpd log shows permission denied, fair enough!
Ok, googling suggests that the script being called by the CGI must also be owned by the apache user and group, or by root with 755 permissions. Done!
now httpd log show permission denied for things worker.sh is trying to do :/
Google has lead me to believe that for security reasons fcgi requires that everything interacted with by the CGI process chain must have correctly controlled permissions, all the way down to the binaries and source files... Sure, this is smart for security and damage control, but almost impossible in my case. We have very dynamic data and terabytes of resources... :/
the script worker.sh exports its own environment and runs all it's commands as root. This is largely to overcome the minefield of permissions disasters that I have to contend with and CentOS's own paranoia about allowing stuff to happen. I had hoped this might be a work around, but no.
One suggestion I have seen is to simply write out the composed command to a text file and have cron or incron do something with the text file. Seems like that would work... BUT, I'd love to be able to get STDIO back into my web page as there are verbose errors and notifications (though no interaction) in many of these worker scripts, and I would like to provide notification of completion as well. Is there any way to do this that doesn't require a permissions war to be waged?
To run certain commands as another user, you can use sudo.
Set up sudo to allow passwordless access to run your command by the apache user. Then you can have the CGI script call sudo /path/to/script args to run it as root (or -u for another user of your choice).
It's very hard to make this secure, so you should make sure your CGI script is only accessible by trustworthy individuals.

How do I make a completely ACCESS DENIED Process on Windows?

I'm making a security software that is a parental control monitoring system and I don't want any user / administrator or a program to kill my process.
I have tried using SetSecurityInfo() but that didn't work. Then SetKernelObjectSecurity but that also didn't do what I wanted.
How would I do this?
I would also love to have a clear explanation of any code provided.
EDIT: If so, how do antivirus programs do it ???
Can you please help me. Im new to WINAPI I would like to know about something which is simple... Sorry to trouble you guys but at least you can show me the code for some 'watch dog' process or something . . .
This is not controlled by the process itself, and certainly not by its calling a magic API function. If it were, all malicious software would set itself up as "unkillable" and totally pwn your system. Rather, it is a security attribute of the executable file—specifically, the "Terminate" permission.
You can explore this for yourself by downloading Process Explorer:
Open the properties for your process
Switch to the "Security" tab
Click the "Permissions" button
Click the "Advanced" button
Select the desired user or group
Change the setting of the "Terminate" permission.
System processes have the "Terminate" permission denied to all users except the SYSTEM user. This is why even administrators receive the "Access Denied" message, because they lack the "Terminate" permission for system processes.
Of course, even setting this attribute correctly does not make the process "unkillable". It just makes it more difficult. There is plenty of software available online for a free download that allows users to kill such processes, and anyone with basic knowledge of the Windows security model can work around it without even requiring special software.
And none of this makes much sense for parental control software. You should be using the Windows security model to your advantage, not trying to work against it. Install the software as an administrator (i.e., the parent's account), and then set the child(ren) up with a limited user account. Limited user accounts won't be able to kill your process because they don't have the requisite permissions. If an administrator wants to kill your process, then you should let them, not give them some spurious "ACCESS DENIED" headache.
No it's not possible. No matter what you do, I can always turn the machine off.
First of all, lets make it clear it is impossible.
But, you can make it harder.
Besides, what "Code Gray" wrote I'm adding:
You can use another process to be a watchdog, and your process watches the watchdog as well (cyclic watchdog), so if one of you is being terminate, it re-runs the other one. You can bypass that by killing your process and the watchdog before any of them get the chance to start the other one.
1a. An attacker can freeze the process instead of terminating it, therefore (1) wouldn't work, so you can "ping" each other every N seconds, and if a ping is missing, something is wrong (not sure how to recover this, depends on the product).
If you are a service, you can set windows to recover your service once its down.
Just an idea, I would not do that in a product. You can API-hook an important function in an important process (a function that is being called quite a lot). Everytime the function is being called, check if your process is up, if not, REBOOT! :-P.
Another wild idea (That I wouldn't do in a product!!!), write a driver and look for a terminate event for your process. If it someone terminates your process, cause a blue screen! That will show 'em! 8-P
Good Luck!
Hooking NtTerminateProcess in kernel mode may helps you.
PS: Hook also NtTerminateThread, because I remember one version of NOD32 antivirus with dumb bug, when killing process was denied, but killing all threads was possible. :-)

Configuring SELinux permissions on (SVS-V) IPC Semaphores

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

How do I disable SELinux for a subprocess launched from Apache?

My Apache module launches a helper subprocess which does, for example, but not limited by, the following things:
It sets up a socket so that it can communicate with Apache.
Reads and writes files in a temporary location that is deleted when Apache exits. These files are used e.g. for storing large amounts of data received over the network, in case that data does not comfortably fit in RAM.
It spawns user-specified executables. Similar to CGI. Each of these spawned processes are run as their own dedicated user.
The helper subprocess is launched as root so that it can manage file ownerships and permissions and can spawn more processes as specific users.
Some users of my module run on systems with SELinux installed, e.g. RedHat-based distros. SELinux usually interferes with my module. Until now I've been telling people to disable SELinux system-wide because I can't figure out how to write a proper policy for my software. Documentation is very scattered, complex and usually only targets system administrators, not software developers.
As a step into the right direction, I want to implement minimal support for SELinux. I'm looking for a way to launch my helper subprocess without any SELinux constraints without disabling SELinux system-wide. Is there a way to do that, and if so, how?
Well... you could write a rule that transitions your domain to unconfined_t, but then you'd piss off quite a few sysadmins. Best to write yourself a new domain that inherits from httpd_t and also adds the appropriate contexts for access.

Resources