get data as pfiles within kernel module code in solaris - c

When I execute on solaris 11.0:
pfiles /proc/PROCESSID
The result is process information, a small chunk of output is what interest me:
4: S_IFSOCK mode:0666 dev:543,0 ino:46228 uid:0 gid:0 size:0
O_RDWR|O_NONBLOCK
SOCK_STREAM
SO_REUSEADDR,SO_KEEPALIVE,SO_SNDBUF(49152),SO_RCVBUF(128480)
sockname: AF_INET6 ::ffff:10.10.50.28 port: 22
peername: AF_INET6 ::ffff:10.16.6.150 port: 55504
The process I pfiles /proc/PROCESSID is the sshd session itself.
My question is given a process id, how can i get this (pfiles) information from within a kernel code ?
When looking in struct proc i could not find something that give me this data.
Is there a pointer to struct that hold all open files occupied by the process on the proccess' proc?
I also executed truss pfiles /proc/PROCESSID but could not find the exact call

If you look in /usr/include/sys/user.h you'll see the open file information can be found in the p_user.u_finfo structure of the current process.
Walking that structure is not trivial. Just look at what the proc filesystem code has to do to look up the attributes of just one open file descriptor. There's lots of locking needed - you can't simply walk the data structures while things are running.
And, the following is beyond the scope of the question, but it's important...
For what it's worth, what you're doing can't work. It's fundamentally flawed - technically and legally.
What you're trying to do - track users who share a user account - is worthless anyway. You will never be able to prove that just because a certain login session executed some code that the code was executed because the user logged into that session purposely ran that code. Because any of the users with access to that account can modify the environment of the shared account such that malware is run by someone else. And they can make it look just like a typed-in command.
Shared credentials and accounts violate nonrepudiation. That's your insurmountable legal flaw in using any data your custom kernel tracking may produce - even if you manage to produce a system that's foolproof, which isn't likely.
If I'm logged into a shared account, you can never prove that the code I ran was run intentionally.
Well, that's not entirely true - if you have perfect auditing where you can trace every thing a user does down to the bytes modified on disk, you can. And "perfect" in this case means those users have no access whatsoever to change any part of the auditing system.
But if you already have perfect auditing in place, you don't need to write kernel modules to try and implement it.
Of course, it's impossible to prove you have perfect auditing in place because you can't prove that you don't have holes in it.
See the problem?
We're right back to "You CAN'T prove I did it intentionally."
You'd be much better off just using the OS-provided auditing services. Whatever you come up with isn't going to be useful in proving "who did it" for any intelligent bad actor - like someone who figures out a way to insert malicious code into another user's session. And the OS auditing will be sufficient to catch anyone who has no clue in how to cover their tracks.
But you won't be able to provably catch any bad actor who knows what he's doing when shared accounts are involved. And if you can't prove it, you might not even be able to do anything at all to someone you suspect. Because someone who really knows what they're doing will be able to pin the apparent blame on someone who's innocent - if they can't hide or destroy the evidence of the bad act[s] in the first place.
What are you going to do if you find the shared .profile file has a line in it that after a certain date emails sensitive data to a throwaway email account, but only when the login comes from a certain IP address?
Any one of the users who share that one account could have put it in there.
No auditing system in the world can solve that problem unless it's perfect and tracks every file change.
If the data you're trying to protect is important, whoever is tasking you to solve the problem by writing custom kernel modules needs to grow a brain and solve the real problem - shared user accounts. Get rid of them.
There's a reason why every security guide says not to use shared accounts, and every security audit I've ever seen will fail anyone using shared accounts.

Related

How to automatically get information about dhcp address renewal?

I need to control dhcp address renew actions on Linux in my application written in C. I am trying to find the best way to retrieve this information from the system. So far I have actually come up with only one way - parsing the system logs and looking for address renewal information. However, this way is very inefficient. I can try to improve this by redirecting the logs from dhclient to a separate file and check only this one file. But it still seems to be a poor solution. Do you have any idea how to retrieve this information in a better way in C or bash? Thank you very much for any hints.

C multiple write access to a log file (linux env)

I have a set of independent programs that I wrote in C. I would like all of them to write their log to the same file. Obviously comes the issue of control access. Two or more of them could end up writing simultaneously.
What is the most pragmatic way to achieve this?
I came across solutions using pthread/mutexes/etc but that sounds overkill implementation for something like that.
I am also looking at syslog but wonder if this is really for the purpose of what I need to do?
I feel that I need a daemon service taking the message and control when they are written. I wonder if that already exists.
I am also looking at syslog but wonder if this is really for the purpose of what I need to do?
Yes
I feel that I need a daemon service taking the message and control when they are written. I wonder if that already exists.
It exists in the Unix derivatives (including Linux) and is called... syslogd
More seriously, the syslog function is intended to pass a message to a syslogd daemon that will route it according to its configuration file. Most common uses include writing it down to a file or to the system console (specially for panic level messages when nobody can be sure whether the file system is still accessible). The syslog system may come with more features than what you are asking for, but it is an extremely robust and extensively tested piece of software. In addition, it is certainly already active on your system, so you should have a strong reason to roll your own instead of using it.
You have two way :
First : Using something that already exist.
For the logging part, syslog (and syslog-ng) are well-know and well-used.
From that point, you can parametre syslog-ng to listen to an ip connection, and scan a dir for new file.
Your program can, when they will want to log, either connect to syslogng directly and send the log, and if the connection fail, write a new file in the directory that syslogng watch.
That allow to not have the loss of the log is syslog-ng are interrupted for a reason or another.
Second : Develop something really similar to syslog-ng.
In that case, it's up to you.

Drop privileges as regular non-root user for sandboxing?

Is it possible to use a set of C library or system calls to drop all user privileges on POSIX, or at least on Linux? Note that I am not asking how to drop root privileges, which is what all of the other StackOverflow search results seem to be asking and answering.
I want the same effect as switching to user nobody, but stronger if possible. That is, I want my C application to do the following:
Run as a normal user, not root, and without the setuid file permission bit
Retain the ability to access specific files and open outgoing network connections
Voluntarily and permanently lose the ability to read and write files in specified (or all) directories, especially $HOME
If possible, give up or sandbox all other nonessential abilities, like opening a listening socket with accept
Things I have considered so far that don't fit the bill:
Switching to user nobody with setuid/setgid
Ordinary users are forbidden from switching to other users (like nobody), and the application should not require root just to switch to nobody.
Linux/POSIX.1e Capabilities
Capabilities only add root-like privileges, not take away ordinary user privileges
Traditional seccomp
My application will need more than just exit, sigreturn, read, and write
Things that look interesting, but for which I couldn't find documentation, appear to be unmaintained, or appear to be non-portable:
seccomp-bpf
AppArmor
grsecurity RBAC/role-based access control
So is there a well-documented, preferably portable way to drop nonessential user privileges and sandbox a process without having to become root first?
It's unlikely any solution will work on all POSIX, since POSIX doesn't define the mechanism you're looking for.
Looking at just the requirements and just Linux, probably the easiest way to satisfy them is actual via the security modules. Any of apparmor, selinux, RBAC will do what you need, but only via external profile - not something built into your app. The problem may be that adding a profile in all those cases requires the root user to do it (but the profile applies to user process too).
A bit more complicated solution that almost satisfies the requirements is seccomp. While it doesn't understand paths at all (you can only see pointers), there are ways to limit the access: seccomp policies can be defined per thread, so you could redesign your system to have a "path verification thread", which doesn't do anything apart from reading paths and returning sockets if they match your specification. Then limit that thread to just recv(), open() and send(). Thread doing other work can then drop open() and use the other service.
Or if you can configure the paths at program startup, you can put them into an array, mark that page as read-only, and setup seccomp policy which will only accept open() with filenames from that array (that's just a pointer comparison in that case).
To some extent, the approach of splitting application into separate processes which have very limited responsibilities is something you could replicate on other systems, but without the same guarantees as on Linux. For example qmail is kind of a system of very small processes which work as a pipeline for data (simplification). On Linux you could still apply seccomp to them, on Solaris just drop exec and other capabilities, on other systems... I don't know, but probably you can do something.

how to execute c code securely

In this scenario the user will submit his/her C code to my server through a browser.
The code will then be compiled and executed on my server and the output will be sent to the user.
Since the user can submit any code (including Viruses, or other malfunctioning code). I will have to take care of that.
So my question is, how can I secure my server from such code?
I cannot answer you for windows -- I can tell you for linux.
This is an extremly complex problem. You need to think to:
quota limit
process that compiles/executes the code to be runned as an unprivileged user.
do not allow the process to run more than N seconds
do not allow process to allocate too much memory
I can say that this is a long-term project that you can not finish correctly in a few weeks.
Your question is perhaps equivalent to the halting problem, and probably has no bullet proof answer (think of asm in malicious C code, forged function pointers, computed goto, buffer overflow trashing the return address, dlsym & dlopen, etc.).
As mentioned by Shawn in his comment (referring to this question), you could use sand-boxing techniques. Alinsoar's answer shows you the complexity of the issue.
Other problem to think to : what rights to allow the guest process: is he allowed to open a socket ? If so , what traffic do you allow him ?
In the case you open a socket, then the problem becomes even more complex, because he can deliver an attack over that socket...
You might consider using ideone API, some mobile devices software do so (CodeToGo for example)

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.

Resources