1

Is there a way to monitor and redirect file access of a thread or process?

For example a thread wants to read /etc/mysql/my.cnf and I want to change the access to ~/my.cnf or if I run touch /etc/test.config I want the file to be redirected to ~/somefolder/etc/test.config.

I am looking for a libary preferably for C, C++ which works for Linux/Unix.

Thanks in advance

gavv
  • 4,649
  • 1
  • 23
  • 40
Koogle
  • 401
  • 4
  • 9
  • Assuming the file handle is accessible from both threads, you could close the old handle, open a new handle and use `dup2()` – user590028 Feb 01 '15 at 11:14
  • `ln -s /etc/mysql/my.cnf ~/my.cnf`? – Mats Petersson Feb 01 '15 at 11:14
  • The problem is that I want to income other programs and do not know what they will access. Furthermore it is crucial that they do not get any information from they file they originally requested. It should be something like a sandbox. – Koogle Feb 01 '15 at 11:45
  • Try `chroot` http://linux.die.net/man/2/chroot – user590028 Feb 01 '15 at 11:47
  • Thank you seems like what I was looking for, but is there a way to catch all the file accesses which went wrong? Because otherwise I would have to mirror somehow my whole file system to watch the file access. – Koogle Feb 01 '15 at 11:55
  • Sounds like you are asking an XY question. What is the ACTUAL problem you are trying to solve? You want to divert a SQL server to use a different database? – Mats Petersson Feb 01 '15 at 13:05
  • I want to write a program which allows me to invoke other programs and process, which are then executed in some sort of sandbox where their file access is redirect to location I have set. – Koogle Feb 01 '15 at 13:10
  • Would a virtual machine not be a better place to do that sort of thing. What is your overall goal? Subverting something, checking what happens with bad data, testing something? – Mats Petersson Feb 01 '15 at 13:25
  • My motivation is exactly to avoid the overhead of a VM while keeping the invoked programs sandboxed. The use case is behavior watching like in a Virus Scanner and being able to install libraries without them polluting the underlying operating system (like pythons virtualenvironments). – Koogle Feb 01 '15 at 13:28

2 Answers2

1

You could write a shared object that gets pre-loaded when your program starts running. In the .so you'd redefine the libc function open(). When the caller (the program that's getting fooled) passes as argument the string /etc/mysql/my.cnf, you'd instead open ~/my.cnf and return the opened file descriptor. The caller wouldn't know the difference.

Your shared object would of course need to call the "real" open() to to open the file handle; you can get a pointer to the original libc function using dlsym().

This seems overly complicated, but in fact it isn't, it works like a charm. I've used it on several occasions where I had to fool a program that I didn't have the sources for; and it simply works like a clockwork.

If you want to see a proof of concept, check out my blog where I wrote it up. Happy coding!

Karel Kubat
  • 1,635
  • 11
  • 12
  • I will check this out, but in deed it seams like overly complicated. – Koogle Feb 01 '15 at 12:54
  • I should add that this works on all levels. For example, if you pre-load your standard Bash with this shared object, then all programs will inherit your redirection. So whether you do "cat /etc/my.cnf", or "vi /etc/my.cnf", or whether you start some other program that accesses /etc/my.cnf: all will be redirected to whatever file you have in mind. – Karel Kubat Feb 01 '15 at 16:57
  • Okay I will have deeper look at it so I can review your answer. – Koogle Feb 01 '15 at 17:06
  • Blog link now requires a login, which is too bad because this looks interesting – pmarreck Jan 08 '22 at 16:16
1

In linux, you can use bind mounts to map directory or file to another path, and per-process mount namespaces to do it for specific application.

See this question.

Example 1: use proot

$ proot -b ~/alternate_hosts:/etc/hosts
# echo '1.2.3.4 google.com' > /etc/hosts
# resolveip google.com
# IP address of google.com is 1.2.3.4

Example 2: use unshare(1)

$ unshare -m
# touch foo bar
# mount -o bind foo bar
# echo hello > foo
# cat bar
hello

Example 3: use unshare(2)

See this post: http://glandium.org/blog/?p=217.

Community
  • 1
  • 1
gavv
  • 4,649
  • 1
  • 23
  • 40