How to monitor the change of a process's working directory? - linux

I want to monitor the current working directory of an arbitrary process with a given PID under Linux.
My idea is to use inotify on the procfs. Every process has its own directory under /proc/PID and there is a symlink pointing to the actual working directory /proc/PID/cwd
I want to get notified when this symlink changes, but if I put a watch on the symlink it will start watching the directory the symlink points to.
Any ideas?

You may as well use strace and watch it for making chdir() system calls - as those really are the only way to change the current working directory.
This is really a debugger-style requirement, and you're going to need to use debug interfaces to achieve it.

Are you looking for this? From man page:
The following further bits can be specified in mask when calling
inotify_add_watch(2):
IN_DONT_FOLLOW (since Linux 2.6.15)
Don't dereference pathname if it is a symbolic link.

I don't think that you can. procfs is not a real file system, it is only generated on demand when you read from it.

Related

Fuse symbolic link resolution under chroot

I am creating a fuse-based filesystem very similar to the example passthrough_fh. Where I log some statistics in my handlers before calling the underlying system call.
I use this with a debian Wheezy chroot image from debboostrap. The idea is to mirror wheezy/ into my mountpoint, then a process will chroot into the mountpoint and all activities will be recorded through my fuse fs.
The OS seems to handle path resolution with chroot nicely. That is, if the chrooted process does stat("/bin/ls"), from my fuse process I see stat("wheezy/bin/ls").
However I'm not sure how to handle symlinks. For example the file
wheezy/lib64/ld-linux-x86-64.so.2
points to
/lib/x86_64-linux-gnu/ld-2.13.so
So when I call stat("wheezy/lib64/ld-linux-x86-64.so.2") it won't just work, since the OS will try to dereference the symlink /lib/x86_64-linux-gnu/ld-2.13.so instead of the correct wheezy/lib/x86_64-linux-gnu/ld-2.13.so.
This is a simplified example, I can't just prepend wheezy/ to all paths, I want to also support applications which do not chroot, or chroot multiple times.
I can think of some less than ideals ways to do this, e.g. check /proc/pid/root/ to get the root of the process in case of chroot, but then I have to always check if a file is a symbolic link.
Is there a better way or general way fuse based file systems handle this problem?
After contacting the fuse-devel mailing list, I received the following response:
If you are performing this stat(2) for GETATTR or LOOKUP, you should
be using lstat(2) instead. This will tell the kernel that you found a
symlink and it should keep managing path resolution correctly for you.
That is, use lstat(2) when handling LOOKUP or GETATTR, use the results of lstat to fill the fuse struct. From there, the kernel will automatically handle the name resolution (even for symbolic links, and processes running inside a chroot).

How to kill programs in the same directory in linux?

I want to kill all programs running in the same directory as I do.
I need to find which programs are running right now and kill them (and to be careful to not kill myself).
I am running my program in Ubuntu(Linux).
I need to use this command:
int kill(pid_t pid, int sig);
How I can do it?
*The programs live in the same directory .
Stricto sensu, your question does not make sense. By the time you are getting the directory of a process, it could have called chdir(2) before you kill it (and then you should not have killed it).
On Linux, to get information about processes, use proc(5). So use readdir(3) after opendir(3) on /proc/ (filter only the numerical directories, like /proc/1234/ which corresponds to process of pid 1234). For each process there, use readlink(2) on  /proc/1234/cwd to get its directory (and on /proc/1234/exe to get its executable, if it matters). Use getcwd(2) and getpid(2) to get current directory and current process.
BTW, your kill(2) is a syscall (listed in syscalls(2)), not a command. The command is kill(1) to be usually run from a shell.
You should read Advanced Linux Programming.
At last, your desired behavior to kill every process running in your directory is extremely user unfriendly. So at least document it, and perhaps give some way to disable that behavior. A more gentle way would be to make some temporary directory (using mkdtemp(3)) then chdir(2) into it (then perhaps unlink(2) or rmdir(2) it).
See also pkill(1) and pgrep

How to tell if a given process opened files with O_DIRECT?

I would like to tell if a process has opened any files using O_DIRECT, but I can only examine it after the process was launched (i.e. strace is not an option). I tried looking in /proc/$pid/fd/ to see if there was anything useful, but there wasn't. My goal is to track down if any of several hundred users on a system have opened files with O_DIRECT. Is this possible?
Since kernel 2.6.22, /proc/$pid/fdinfo/$fd contains a flags field, in octal. See http://www.kernel.org/doc/man-pages/online/pages/man5/proc.5.html
I don't think it's visible in /proc or elsewhere in user space.
With kernel code, it's possible:
1. Get the process's task_struct (use find_task_by_pid).
2. Go over files - use task->files->count and task->files->fd_array.
3. Look for file->f_flags & O_DIRECT.

trigger alert when a specified command executes in linux

I have 3 samba shares mounted in my system, but suddenly, one of them gets umounted without my permision. Maybe one of houndreds of scripts which run in my crontab, but i dont know which one.
I've reviewed all /var/log directory looking for umount word without success, then i want to log when command umount is executed and which process is running it.
Maybe with syslog, maybe with another log, maybe a mail to my box....
Thanks a lot.
I have this software:
mount: mount-2.12q
mount.cifs version: 1.14-3.5.4
Unmounting does not only happen by calling the umount binary, many programs might do it. See the manual page (man syscalls) and search for umount. This said, you would have to hook the corresponding syscall and see who invokes it. I'm not sure, but most probably it's possible to disconnect inside the kernel by calling the corresponding method directly, so functionality might bypass the syscall interface which is mainly required for userspace interaction. In this case you would have to use some debugging technique on the kernel itself, which maybe is a little much for finding your problem!
You may have success using strace on an already running process (man strace), for example smbd, and see if this process invokes umount, which is quite possible.
Anyways, if you can recompile your kernel from source, you might add some printk message inside the function that is used to unmount a device to see which process did it (this would be my approach for cases where nothing else, including strace, helps).
Since the mount is a change in the filesystem, maybe the inode-observer incron is a solution for you. Another option might be the auditd.

monitor which process modified a file under FreeBSD/Linux

From time to time, a file that I'm interested in is modified by some process. I need to find out which process is modifying this file. Using lsof will not work, nor does kqueue. Is this possible under FreeBSD and Linux?
On Linux, there's a kernel patch floating around for inotify. However, some have said this is rarely useful and that it can be a security risk. In any case, here's the patch.
Apart from that, I'm not sure there's any way to get the PID, either with inotify or dnotify. You could investigate further (e.g. search for pid dnotify or pid inotify), but I believe it isn't likely.
On FreeBSD, perhaps it should be best if you check its auditing features.
Linux has an audit daemon http://www.cyberciti.biz/tips/linux-audit-files-to-see-who-made-changes-to-a-file.html
See also auditd homepage
You can see which processes opened a file just installing and using lsof (LiSt Open Files) command.

Resources