protect files from editing in linux - c

How do you protect a file from editing by an external program or user , even if that user has somehow got root privileges. Let's say I have this File F which I have to protect and by default only the root and user can execute , read and write to F, all others only have read permission.
Let's say I have a program, which is protecting the critical file F, and detects that the circumstances of editing are unusual and seems like the security of the system may have been compromised. How to prevent saving changes to the File F ?If possible also kill that program which tried making that change.
I have found out that fuser can kill that process, but not before any modifications aka damage has been done. I use inotify to detect changes. My problem is most of the editors make a temporary file, make changes, and then save it to original file. Although I receive event like IN_OPEN, IN_CLOSENOWRITE and others, I get IN_CLOSEWRITE and IN_CLOSEMODIFY only after the event is complete ? How do I stop my file F From being modified ?
I understand that my program may be killed after someone gets into the system, but can I somehow save whatever little I can ?
Edit: I forgot to mention I can't change the permissions of any file which are monitored.
Edit #2: I have a set of files which have to be constantly monitored. My program would run in the background and note changes in those files. All files as I wrote earlier can be edited and executed by root, but there are actions(modifications) which may be undesirable and most probably would mean that someone has gained root access and has edited those critical files. I need to stop these harmful changes. From the answers I somehow presume that I will have to get a snapshot of those files. But the problem is the number of files could be huge , around 1 to 4 million. Any solutions which are efficient than snapshot solution are welcome.

There is not way to protect the file if the "attacker" has root. Whatever you do, root can undo.
Having said that, if you want to make it hard, you could put the file on a readonly filesystem, such as a cdrom.

If root is malicious, there's no way to make any guarantees about data integrity. Ideally on such a critical system, nobody should have root whatsoever without taking the system offline and into a maintenance environment (possibly replacing it with a surrogate system while it's offline if constant uptime is critical).

I believe you can do chattr+i (change attribute to immutable) to prevent even the root from editing the files. The root can always revert this, but you might be able to protect your file from a script-kiddie who does not know about chattr.

You should either lock the file from your application or change it's ACL and RWX rights

What if your monitoring app obtained a lock on each file it is monitoring? flock, fctnl for example might work. Then, other applications would not be able to edit the file.
Not sure how this affects deletion (which you said might be valid).

Related

Restricting folder/file access to one program?

What I need, boiled down, is a way to 'selectively' encrypt either a folder or a zip file - Whatever the solution would be, it needs to block (or redirect) all reads/writes EXCEPT from one specific program (not mine, a legacy application that I do not have source code access to - I cannot modify the program who would have the sole permission to perform reads and writes on the encrypted folder/zip file). I would like to avoid having a constantly running background app (as all the end-user would have to do to circumvent the protection would be to kill the program)
The purpose is to, of course, protect the files within the folder from tampering.
I could modify folder permissions at install, but this would block all programs from access wouldn't it? I more or less need to only block File Explorer from accessing the files, but not the program which needs to read them... if that makes sense. Or, if I could protect the (plaintext) files somehow without affecting the legacy application's reading of them... argh.
I wonder if it would be possible with CreateProcess() to run the legacy application as a high-level user and give the folders it needs access to the same permission, such as TrustedInstaller or SYSTEM, (who, in Windows, own things that not even administrators can touch, like System Volume Information)
This would allow the program to read/write to the folders, but not the user.
I was looking at LockFile, seems to be close to what I am looking for but not quite. I need something like semi-exclusive access.
I am fairly fluent in C++, Visual Basic.net, only some Python, but I am willing to use any language which would allow a solution to this problem (Though it probably could be implemented in any language, if possible at all.)

A way to make a file contents snapshot in Linux

What is the best way to create an "atomic" snapshot of file contents in Linux? Emphasis is not on performance, but on getting contents as a whole.
I may think of using sendfile(2) (since 2.6.33) or splice(2), but neither have any indication of operation atomicity. Both are run in the kernel-space entirely, but at least sendfile(2) implies it's using mmap(2) and mmap gives no guarantees that writes to the same mmaped (as MAP_SHARED) region in other processes won't be visible even with MAP_PRIVATE (probably they will, because that are the same pages).
Taking that this functions are writing with performance in mind and sendfile(2) is optimized to be used with DMA, I may only assume that they just copy memory in some background kernel thread and it's quite possible that other operations may also affect the data being copied.
So the only possible solution I see is to place a read lease with fcntl(2) (FD_SETLEASE) and copy file as normal, but if someone opens it for writing, either try to "rush" it (very reliable, I know) and beat the timer, or just give up and try later. Is that correct?
So the only possible [filesystem-independent] solution I see is to place a read lease with fcntl(2) (FD_SETLEASE) and copy file as normal, but if someone opens it for writing, either try to "rush" it (very reliable, I know) and beat the timer, or just give up and try later. Is that correct?
Almost; there is also fanotify. Plus, as mentioned in a comment, there are some filesystem-specific options, and some possibilities only available in certain configurations.
The lease break timer is configurable, /proc/sys/fs/lease_break_time in seconds, and the default is 45 seconds.
"Just give up and try later" is also a bit defeatist; you do have ways to monitor when the snapshot might work. Consider placing an inotify IN_CLOSE_WRITE and IN_CLOSE_NOWRITE watch on the file, and try the snapshot whenever you receive such an event.
fanotify:
For a few years now, I've been monitoring the progress of Linux fanotify, in the hopes that it would grow enough features that it could be used for automagic file versioning. Essentially, whenever someone opens the file with write permissions, the current file would be snapshot to temporary storage, marked with some metadata (timestamp, real human user (backtracked through sudo/su), and so on). When that descriptor is closed, another snapshot is taken, and a helper thread/process diffs the two, annotating the changes (or even pushing it to git).
It is limited to local filesystems, but with 2.6.37 and later kernels (including 3.x), the interface is sufficient for specific files, or an entire mount. In your case, the fanotify interface allows similar features to file leases, except for local filesystems only, but you can simply deny any accesses during the snapshot. (One can argue whether that is a good idea at all, especially if the file to be snapshotted is a system or configuration file; many programmers overlook error checking, because "some files just have to be always accessible, or your system is broken".)
As far as my change monitoring goes, fanotify should now have all sufficient features, but only if an entire mount is monitored. I was hoping to monitor configuration files on multi-admin clusters, but those files reside on the same mount as all system libraries and binaries do, so the monitoring causes considerable overhead. So much so, that it seems more appropriate to just modify SSH configuration, console configuration (getty etc.), sudo configuration, and possibly su, to always include a dynamic library that interposes file access syscalls, and basically does the versioning on behalf of the user. This way service binaries are not affected, only user actions are monitored.
This might work under some circumstances:
(Optional) Do something to prevent new processes to open the file:
a/ rename the file
b/ restrict file permissions
Find all existing file readers/writers via lsof and kill -STOP them
Do your snapshot
kill -CONT all readers/writers
(Optional) Restore action 1.

Prevent unauthorised write access to a part of filesystem or partition

Hello all I have some very important system files which I want to protect from accidental deletion even by root user. I can create a new partition for that and mount it with readonly access but the problem is that I want my application which handles those system files to have write access to that part and be able to modify them. Is that possible using VFS? As VFS handles access to the files I could have a module inserted in the VFS layer which can see if there is a write access to that part then see the authorization and allow it or otherwise reject it.
If not please provide me suggestions regarding how can such a system be implemented what would I need in that case.
If there exists a system like this please suggest about them also.
I am using linux and want to implement this in C, I think it would be possible in C only.
Edit: There are such kind of programs implemented in windows which can restrict access to administrator even, to some important folders, would that be possible in linux?
My application is a system backup and restore program which needs to keep its backup information safe and secure. So I would like to have a secured part of a partition which could not be accidently deleted in any way. There are methods of locking a flashdrive can we use some of those methods for locking a partition in linux also ? so that mount is password protected ? I am not writing a virus application, my application would give user option to delete the backups but I don't wanna allow them to be deleted by any other application.
Edit: I am writing a system restore and backup program for ubuntu, I am a computer engineering student.
Edit: As I have got opinion from Basile Starynkevitch that I would be committing worst sin of programming if I do anything like this, but you could provide me suggestions considering this as a experimental project, I could make some changes in the VFS layer so that this could work.
You could use chattr, e.g.
chattr +i yourfile
But I don't think it is a good thing to do that. People using root access are expected to be careful. Those having root access can still issue the command undoing the above.
There is no way to forbid people having root access, or people having physical access to the computer, to access, remove, change your file, if they really want to (they could update & hack the kernel, for instance). Read more about trusted compute base
And I believe it is even unethical (and perhaps illegal, in some countries) to want to do that. I own my PC, and I don't understand why you should disallow me to change some data on it, because I happened to install some software.
By definition of root on Linux, it can do anything... You won't be able to prohibit him to erase or alter data... People with root access can write arbitrary bytes at arbitrary places on the disk.
And on a machine that I own (or perhaps just have physical access to), I will, thanks God, always be able to remove a file (even under Windows: I could for example boot a Linux CDROM and remove the file from Linux accessing an NTFS, and then reboot the Windows...).
So I think you should not bother and take even a minute to find out how to make root altering your precious files more difficult. Leave them as other root files...
PHILOSOPHICAL RANT
The unix philosophy has always been to trust the system administrator (while protecting newbie users from mistakes), that is the root user. The root is able to do anything (this is why people avoid being root, even on a personal machine). There have never been strong features to prohibit root doing mistakes, because the system administrator is expected to know well the system, and is trusted.
And Unix sysadmins understand this fact: it is part of their culture. (This is probably in contrast with Windows administration culture). They know when to be careful, they don't expect software to prevent mistakes as root.
In order to use root squashing (which makes it so that root can't even see files for a local user) you can set up a local nfs. This forum page explains how to mount an nfs locally. The command is:
mount -t nfs nameofcomputer:/directory_on_that_machine /directory_you_should_have_already_created
nfs has root squashing enabled by default, which should solve your problem. From there, you just make sure your program stores its files on the nfs mount.
Sounds to me like you're trying to write a virus.
No doubt you will disagree.
But I'm willing to bet the poor people that install your software will feel like it's a virus, because it will be behaving like one by making itself hard to remove.
Simply setting r/w flags should suffice for anything else.

Properly running binaries on runtime with safety (seteuid etc)

So if I want to run a binary using exec() on a child process after fork, but want to restrict its file access to a certain directory only, how does one safely do that?
Does this involve of creating a new user in unix/linux, and then setting the uid to that user?Or would this require creating a group (say, webapps) and then using setguid?
Of course, one can just run the binary as is, but it seems that taking some precautions with security is never a bad idea.
I'd take a look at chroot. It a relatively easy way to separate parts of your system.
In a nutshell: you change the root for a particular process, so /path/to/working/dir is now / for that process. Of course you have to add everything that is necessary (utilities, libraries, configuration) to this folder.

How to create an undeletable file in Delphi

[the following is a rephrase of my previous question, which was deemed ambiguous].
I'm digging into creating a basic licensing mechanism for a demo application. What I have in mind goes like that: the application creates an empty "license file" called, say "0b1xa487x.ini" upon the first run, then expires 30 days after it has been first executed and can't be run anymore as long as that specific file is present on the system.
What I'm looking for is a method to protect that specific file in a way to deter deletion. Since it will be a blank file, devoid of any content, I wouldn't mind it to be corrupt, have corrupt headers, invalid date, whatever it takes to stay undeletable.
I've seen a similar approach somewhere based on file attributes (the file had the HX attributes set in place); however, the attribute approach lead me nowhere, as I can't find any documented feature on the existence of a file attribute X.
I also know that there are other approaches including rootkit drivers and system services launched as system user, but this particular one seems to fit best in this scenario. Again, I outline that the file's contents may as well be inaccessible, I'm not planning to use the approach in running any kind of malware from the file, as I've been accused below :)
Corrupt suggests not conforming to some standard. There are no standards for blank files.
Thanks everybody for your suggestions. I found a way to render my file inaccessible, namely by using fortunate combination of file permissions. The downside is that these things don't work on non-NTFS partitions. The good thing is that I can always clean up after my application by simply removing these permissions programatically and deleting everything afterwards.
Regarding your last answer to Henk, I believe it is more easier to create a service, start it automatically with the OS, and open the file in the fmShareExclusive by using a TFileStream.
But, you can not force the kernel of the OS, or an antivirus to make your file 'undeletable'.
Best regards,
Radu

Resources