Performing the equivalent of chattr +i filename.txt from Linux application - c

Is there any interface in the Linux userspace API that will allow me to perform the action equivalent to
chattr +i myfile
chattr -i myfile
If possible I need to do this from within my application but I cannot find anything online that suggests how one would go about doing this from the Linux API. I would have thought there would be some kind of ioctl call available to do this but I simply cannot find any details about it.

have a look at:
http://www.danlj.org/lad/src/setflags.c.html
and if you do some strace on chattr, you could have found out that it calls stuff that looks like:
ioctl(fd, EXT2_IOC_SETFLAGS, flags)
(have a look at this thread)

Related

Intercepting file operations on Linux

I'm working on a cloud platform for rendering visual effects and animation. We accept various formats of scene descriptions render them, and return the image outputs to the user. The processing backend is Linux. Sometimes we receive scene descriptions generated on Windows so we get paths that look like 'C:\path\to\file.mb'. I've written a Linux shared library to intercept various filesystem calls and alter the paths to something Linux can understand '/C/path/to/file'. I use the LD_PRELOAD mechanism to insert my functions before the "real" ones and it works great... except when it doesn't.
For example this command:
LD_PRELOAD=/home/robert/path_fix.so Render -s 1 -e 1 C:\path\to\test_scene_03_vray.ma
Will not locate test_scene_03_vray.ma. This also doesn't work:
LD_PRELOAD=/home/robert/path_fix.so echo test > C:\path\to\test.txt
I've been using ltrace to figure out which functions are called with references to path names, but these examples don't show up in my traces:
ltrace -f -C -S -o ltrace.out Render C:\path\to\test_scene_03_vray.ma
Is there a tool other than ltrace that will let me see which function calls are invoked?
Here's the list of what I already have overrides for:
fopen
freopen
opendir
open
creat
openat
stat
lstat
fstatat
__lxstat
__xstat
mkdir
mkdirat
unlink
unlinkat
access
faccessat
rename
renameat
renameat2
chmod
fchmodat
chown
lchown
fchownat
link
linkat
name_to_handle_at
readlink
readlinkat
symlink
symlinkat
rmdir
chdir
Are there more functions that I'm missing here? I tried to implement everything that takes
const char *filepath
as an argument.
Side question: This seems like it might already be a solved problem... Is there a library or other approach that converts Windows paths to unix friendly paths? Keep in mind that the rendering applications are 3rd party proprietary binaries so I can't modify them.
Thanks for any suggestions!
Yes, there are other functions, such as the 64-bit functions open64(). There are also functions such as __open().
On a 64-bit Centos 7 server, for just open I get:
nm -D /lib64/libc.so.6 | grep open
0000000000033d70 T catopen
00000000003c0b80 B _dl_open_hook
000000000006b140 T fdopen
00000000000ba4c0 W fdopendir
00000000000755d0 T fmemopen
000000000006ba00 T fopen
000000000006ba00 W fopen64
000000000006bb60 T fopencookie
0000000000073700 T freopen
0000000000074b60 T freopen64
00000000000eb7a0 T fts_open
0000000000022220 T iconv_open
000000000006b140 T _IO_fdopen
0000000000077230 T _IO_file_fopen
0000000000077180 T _IO_file_open
000000000006ba00 T _IO_fopen
000000000006d1d0 T _IO_popen
000000000006cee0 T _IO_proc_open
0000000000131580 T __libc_dlopen_mode
00000000000e82a0 W open
00000000000e82a0 W __open
00000000000ed0f0 T __open_2
00000000000e82a0 W open64
00000000000e82a0 W __open64
00000000000ed110 T __open64_2
00000000000e8330 W openat
00000000000e8410 T __openat_2
00000000000e8330 W openat64
00000000000e8410 W __openat64_2
00000000000f7860 T open_by_handle_at
00000000000340b0 T __open_catalog
00000000000b9f70 W opendir
00000000000f12b0 T openlog
0000000000073ea0 T open_memstream
00000000000731c0 T open_wmemstream
000000000006d1d0 T popen
0000000000130630 W posix_openpt
00000000000e6ec0 T posix_spawn_file_actions_addopen
For example, on Linux this C code is quite likely to work just fine:
int fd = __open( path, O_RDONLY );
You're also not going to catch statically-linked processes, or those that issue a system call such as open directly.
You can technically use kprobes to intercept the calls but if thr numbrr of files arent too many or dynamicaly generated, i suggest creating symlinks. It is much safer and simpler.

Catching Mach system calls using dtruss

I ran dtruss on vmmap that is a process that read the virtual memory of another remote process.
I would expect that some of mach_port system calls would appear in the output of my command, but couldn't trace any (i.e. mach_vm_read, task_for_pid, etc ..)
The exact command i ran (notice that dtruss is a wrapper script of dtrace in OS-X) :
sudo dtruss vmmap <pid_of_sample_process>
The input argument for vmmap is just a pid of any running process, and the OS version i use is 10.10 (in 10.11 there's entitlement issue when running dtruss on apple products such as vmmap).
Perhaps someone can tell me how to identify the system call i'm looking for... Should I look for the explicit name in dtruss output, or just a general call number of my desired syscall (sadly, i haven't found any of them) :
./bsd/kern/trace.codes:0xff004b10 MSG_mach_vm_read
It looks to me like it's not using Mach APIs. It's using the libproc interface. I'm seeing many proc_info() syscalls, which is what's behind library calls like proc_pidinfo().
I used:
sudo dtrace -n 'pid$target::proc_*:entry {}' -c 'vmmap <some PID>'
to trace the various libproc functions being called. I see calls to proc_name(), proc_pidpath(), and proc_pidinfo() to get information about the target process and then calls to proc_regionfilename() to get information about the VM regions.
By the way, vmmap doesn't read the memory of the other process, it just reports information about the VM regions, not their contents. So, I wouldn't expect to see mach_vm_read() or the like.

List of serial ports

I am writing small C project to list available serial ports (actually on Linux). It should list usable ttyS, ttyUSB, pty and so on.
My problem is that I have no idea what is the proper way to do it. For example in my /dev directory I have devices from ttyS0 to ttyS31 but in fact no one is usable. I tried looking for drivers in /sys/class/tty/ttyS* but all devices seems to be real.
Actually I can only list pty's opened by 'socat pty pty', but in my opinion it's hack, because I just wrapped the command 'lsof -w -c socat | grep -o '/dev/pts/[0-9]*' | uniq -u' and I am looking for a better way.
My project: https://github.com/mdrost/serialportlist
I will be grateful for possible technical help and comments about functionality.

What is the most general way to list all the kernel tasks in a linux system?

I am trying to figure out the best way to write a cross platform kernel code/shell script to list all the kernel task {(pid/tid , name)} in a linux dis. machine. it should be the most general possible. I tried to use ps -T but it is seems to be inaccurate and some platform don't support it in their busybox. Any suggestions?
If you want to distinguish user processes from kernel tasks, then this is a previous discussion on the subject: Identifying kernel threads
My answer to that question does not require any tools, it simply reads the contents of /proc//stat, so it should work on any distribution.
You could try
ps -e -o pgrp= -o pid= -o cmd= | sed -ne 's/^ *0 *// p'
although it assumes all kernel tasks belong to process group 0.

Get used ports and states

How can I get used ports and their states on Linux? Basically, everything that netstat can do, but in C?
Running strace on a run of netstat will show you the system calls it makes and their arguments.
$ strace netstat
...
open("/proc/net/tcp6", O_RDONLY) = 3
open("/proc/net/udp", O_RDONLY) = 3
...
This is often a good way to find out what a program is doing or the calls it makes and can sometimes be easier than looking at the source if all you need is to find out which call to look up on a man page.
Well, for “everything that netstat can do,” you could start with netstat itself. The source code is here:
http://net-tools.git.sourceforge.net/git/gitweb.cgi?p=net-tools/net-tools;a=blob;f=netstat.c;h=f046f09162689f258f8920c1c2af27e01cdc77f2;hb=HEAD
It should be noted that most of what netstat does, it obtains from the /proc filesystem; it looks like the *_do_one routines hold most of the "interesting" guts.

Resources