How to check which process initiated sys_open - c

I'm taking a course in operating systems and we work in Linux (Red hat 8.0). I'm trying to implement a file open,close tracker that will save for every process a history of files it opens and closes. I expected sys_open,close to also accept the process id and that I could use that to access the history of the process that initiated the call and update it (making the update part of the sysopen,close functions). However, these functions don't accept the pid as a parameter, so I'm a bit lost as to how to associate opening/closing files to the process that initiated that. My only guess is that since at any given time there's only one active process, that its meta-data must be global in some way, but I have no idea where or how to find it. Any advice would be appreciated.

Do you intend to do this in kernel space? Given that you were looking directly at sys_open etc, which sit in kernel space, IIRC, you can use the current pointer to see the current process's pid (current->pid).

Related

"Attach" a user space process from Linux kernel/kernel module

I want to modify the virtual-to-physical address mapping (i.e. page table) of a particular process for every 60 seconds. I do know how to modify the page table, how to flush the cache and TLB accordingly, and how to leverage workqueue to invoke my function every 60 seconds. However, I am not sure how to "attach" to the target process from kernel or kernel module, assuming that the target process does not initiate any system call. By "attach", I mean the target process will behave similar as when it encountered an interrupt (e.g. a page fault) and the execution goes to the kernel immediately with the context being saved. So is it possible to do this?
Pointers to any similar usage in the kernel code or other hints are also appreciated.
Your best bet is to have the process you are interested in applying dynamic virtual address, call in to the module via IOCTL or any other call that ends up in the driver, sleep in process context using wait_* functions and then wake it up every 60 seconds to modify the page table in that thread. You should have assured context then.

Is it possible to pass "signals" to another console program?

My aim: I want to pass a signal (int-type variable) to another running console program.
My idea: Write the data to the disk, and read the data by the other console program.
Possible defect: Too slow, and not efficient.
Is it able to pass "(self-defined / int-type) signals" to another console program ?
Any suggestion (or a better workaround way) would be appreciated.
Yes...
Option 1: Use SendMessage() to send a message to the other process' message queue. (Probably not suitable since you said you have a console program, and it probably doesn't have a message queue.)
Option 2: Use named shared memory.
Option 3: Use a named pipe between the two processes.
Option 4: Use a UDP or TCP network connection between the two processes.
Option 1 is the simplest/easiest, but requires that the target process have a running message queue to receive and process the message.
It depends on what you actually want to pass between the processes involved. If all you need to do is notify the other process, that something has happend (and the other process has the means to find out about the details itself right after being notified), then a named event might be what you need.
If you need to share more information, consider shared memory and mapped files.
Of course, you may also consider to go down the COM route. Define an interface for the process, which should receive the "signal" and have it register an object in the global object table. The sending process can obtain the instance from the object table and use the interface to perform the notification.
There may be countless other ways.
I think we can also pass any signals to any applications in linux using kill .just see 'man kill' for example sending SIGKILL to keil we can write like ..
kill -9 keil
by using kill -l we can see all signals and their respective numbers. and pass their like this 'kill -n app_name'

Set an environment variable from a process that will be visible by all processes

How to set an envirnoment variable from a process that will be visible by all processes?
I'm using C with Glib.
I have 10 processes that use the same library. The problem is that in that library a checking procedure (which is CPU hungry) is performed. I want to avoid that library checking procedure to be executed for every process. For the first process that is using the library it will be enough.
This is simply not possible.
Setting an environment variable (or changing your current environment) is only visible from the children (and descendants) processes of your current process.
Other processes, in particular the parent process (usually the shell running in the terminal where you start your program) are not affected.
You might play dirty tricks like e.g. adding lines into $HOME/.bashrc etc. But you should not.
You just need to document what environment variables are relevant. It is the user's responsibility to set environment variables (perhaps by manually editing his $HOME/.bashrc etc etc). Leave that freedom to your user. Explain to him how to do that and why.
You edited your question to explain that
I have 10 processes that use the same library. The problem is that in that library a checking procedure ( which is CPU hungry ) is performed. I want to avoid that library checking procedure to be executed for every process.
But you definitely should not need to change environment variable for that.
You could
decide and document that the checking is not performed, unless some particular environment variable (or some program argument) is given
decide that the checking is given a particular file name, and use file locked write to write that file, and use file locked reads to read it again
Have the checking write its result in some known in advance file, and read that file before deciding it you want to make the costly checks
Have one process starting all the others, and inform them about the check (perhaps indeed setting some environment variable or some program argument) or use some Inter Process Communication trick to communicate with the others (you could use sockets, locked files, shared memory, etc etc...)
Do many other tricks.
That's not possible. You can set the environment for child processes only.
flock() sounds like it may be your friend.
http://beej.us/guide/bgipc/html/multi/flocking.html
You may also want to look at Semaphores or SHM (Shared Memory).
https://beej.us/guide/bgipc/html/multi/semaphores.html
http://beej.us/guide/bgipc/html/multi/shm.html
It all depends on the level of coordination you want. File locks will be good enough for one process to say stay out while I'm working. Semaphores and shared memory would allow you to coordinate access.

Measuring process statistics in Linux

I am building programming contest software. A user's program is received by our judging system and is evaluated by compiling it and running it via a fork() and exec(). The parent process waits for the child (submission's process) to exit, and then cleans it up.
To give useful information about the program's run, I want to measure the CPU time and peak memory used by the program. Does the Linux kernel keep track of these values? Is there any other way to get this information?
If you call the wait4() system call to reap the child when it finishes, it will fill out a struct rusage structure with the resource usage of the child (ru_utime and ru_stime hold the user and system CPU time used by the child respectively).
You can use the getrusage() or acct() (more info here) syscalls
A low-tech (but easy) solution is to dump the output of top in batch mode periodically and parse it afterwards.
The time(1) program may help, i guess. It is much simpler than polling top.
An excerpt from the man page:
Disregarding the
name of the utility, GNU makes it output lots of useful information,
not only about time used, but also on other resources like memory, I/O
and IPC calls (where available).
You can check the top command. That might be of some help.

In a POSIX environment, how do I track files accessed by a child process?

I have my own POSIX application which starts a child process. I want the parent process to be notified with the names of all files the child process reads or writes, as well as the file names of any child processes the child spawns, and any dynamic libraries it loads. Similarly, I need to monitor all child processes spawned by child processes, etc.
How is this done?
I have two ideas for this.
Method 1 - The "real way".
I think you want ptrace. But it isn't going to be easy to use.
Essentially this call is for writing a debugger. Note that PTRACE_SYSCALL steps until the next syscall. At which point you might be able to use more ptrace calls to peek at the process's memory to observe if it's, say, a call to open().
Method 2 - The lazy, hackish way.
You could use the LD_PRELOAD environment variable. That is, write a shared library with your own implementation of the calls you want to hook (say, open(), dlopen()), adding your own code and dispatching to the normal libc version. Then you point the LD_PRELOAD environment variable at this shared library so the dynamic linker will load it at process start.
One downside to this approach is that if a process knows it's being observed this way, it can reset the environment variable and execute itself again, and evade detection. Another I can think of is that as a security feature this environment variable is not honored if you're root.

Resources