In the below program, I've used system library function to execute "pkill" command. Is there any system call available for pkill(Because PID is unknown). I don't want to use "system" library function. Please let me know how to do it
#include <stdio.h>
int main()
{
char test[1024] = "pkill -15 radio";
system(test);
return 0;
}
The system call for sending signals to processes is kill; however, you need the process id for. If you intend to launch the program to be killed from within your application, too, use fork together with one of the exec-functions and you have it. Otherwise, you will most likely have to iterate over the /proc/* subdirectories.
Related
I am trying to program a shell in C , and I found that each command is executed in a new process, my question is why do we make a new process to execute the command? can't we just execute the command in the current process?
It's because of how the UNIX system was designed, where the exec family of calls replace the current process. Therefore you need to create a new process for the exec call if you want the shell to continue afterward.
When you execute a command, one of the following happens:
You're executing a builtin command
You're executing an executable program
An executable program needs many things to work: different memory sections (stack, heap, code, ...), it is executed with a specific set of privileges, and many more things are happening.
If you run this new executable program in your current process, you're going to replace the current program (your shell) with the new one. It works perfectly fine but when the new executable program is done, you cannot go back to your shell since it's not in memory anymore. This is why we create a new process and run the executable program in this new process. The shell waits for this new process to be done, then it collects its exit status and prompts you again for a new command to execute.
can't we just execute the command in the current process?
Sure we can, but that would then replace the shell program with the program of the command called. But that's probably not something you want in this particular application. There are in fact, many situations in which replacing the process program via execve is a the most straightforward way to implement something. But in the case of a shell, that's likely not what you want.
You should not think processes to be something to be avoided or "feared". As a matter of fact, segregating different things into different processes is the foundation of reliability and security features. Processes are (mostly) isolated from each other, so if a process gets terminated for whatever reason (bug, crash, etc.) this in the first degree affects only that particular process.
Here's something to try out:
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
int segfault_crash()
{
fprintf(stderr, "I will SIGSEGV...\n");
fputs(NULL, stderr);
return 0;
}
int main(int argc, char *argv)
{
int status = -1;
pid_t const forked_pid = fork();
if( -1 == forked_pid ){
perror("fork: ");
return 1;
}
if( 0 == forked_pid ){
return segfault_crash();
}
waitpid(forked_pid, &status, 0);
if( WIFSIGNALED(status) ){
fprintf(stderr, "Child process %lld terminated by signal %d\n",
(long long)forked_pid,
(int)WTERMSIG(status) );
} else {
fprintf(stderr, "Child process %lld terminated normally\n",
(long long)forked_pid);
}
return 0;
}
This little program forks itself, then calls a function that deliberately performs undefined behavior, that on commonplace systems triggers some kind of memory protection fault (Access Violation on Windows, Segmentation Fault on *nix systems). But because this crash has been isolated into dedicated process, the parent process (and also siblings) are not crashing together with it.
Furthermore processes may drop their privileges, limit themselves to only a subset of system calls, and be moved into namespaces/containers, each of which prevents a bug in the process to damage the rest of the system. This is how modern browsers (for example) implement sandboxing, to improve security.
I am creating a child process and passing some arguments to it.
Now, the child process starts execution from the next line of code, but will I have to write another int main () separately for the child process, as below, or would it just use the already written code for int main() of the parent process?
createProcess(All required arguments);
if (pid == child_process)
{
int main ()
{
......
}
}
ENV: WinXP, VS2005
NOTE: The above code just describes the flow and may have syntax errors.
Are you confusing Windows CreateProcess with UNIX fork()? The two operating systems are different in the way that processes are created. With Windows you have to execute an exe file from the beginning, you can't continue as the child process after CreateProcess as you can with fork on UNIX. Your statement "the child process starts execution from the next line of code" is mistaken for Windows.
Mind you, your code would be illegal on UNIX as well, you can't have two functions called main, and you can't have nested functions in C.
Please read the documentation of CreateProcess() again.
The function takes the filename of the program to run in the new process. The nested function you're showing is not valid C.
On a Gnu system, I can write a C macro like dies_ok() that will fork a new process, run a piece of code, after which it can write to a shared piece of memory that it didn't exit, then in the parent process I can determine if it exited or not. This is useful for tests:
dies_ok({int x = 0/0;}, "can't divide by zero");
lives_ok({int x = 3/7;}, "this is a perfectly fine statement");
dies_ok({abort();}, "abort kills the program");
Is there any way to accomplish this on MSVC where there isn't a fork function?
EDIT: Heres the implementation that works on linux with gcc: http://github.com/zorgnax/libtap/blob/master/tap.h
CreateProcess is like fork()/exec()
The BOOST library has shared memory support for msvc. You can also use the Windows atom table which is native to Windows-
see msdn for
http://msdn.microsoft.com/en-us/library/ms649053(VS.85).aspx
Q: I don't get why in unix you have to write a string to shared memory. You can simply call exit(n) from the child process where n is an index into a predefined char *p[] list of error codes or success codes. You can have an array of 255 values, excluding 0 for EXIT_SUCCESS. Or read the sysexits.h header file for another set of ideas. wait() or waitpid() will return the exit code, or determine if the process did not exit
Does anyone tell me how to block some specific system calls within a program, please? I am building a system which takes a piece of C source code, compiles it with gcc and runs it. For security reasons, I need to prevent the compiled program from calling some system calls. Is there any way to do it, from the source code level (e.g. stripping the header files of gcc, detecting malicious external calls, ...) to the executable level?
Edited #1: Add details about malicious calls.
Edited #2: My system is a GNU/Linux one.
Edited #3:
I have tried some methods within a few days and here are the conclusions I've got so far:
Scanning the source code does not solve the main problem since one can always obsfucate his/her C source file quite well.
"Overriding C symbol" works well for libraries, but for system calls I have not achieved what I wanted. This idea is not dead, however, doing this would definitely cause me a lot of time hacking (gcc and/or ld).
Permission deescalation works like a charm. I could use fakeroot or a "guest" user to do it. This method is also the easiest to implement.
The other one is native client which I have not tried yet but I definitely would in near future due to the common between the project and my work.
As others have noted, it's impossible for a program to avoid making system calls, they permate the C library all over the place.
However you might be able to make some headway with careful use of the LD_PRELOAD mechanism, if your platform supports it (e.g. Linux): you write a shared library with the same symbol names as those in the C library, which are called instead of the intended libc functions. (For example, Electric Fence is built as a shared library on Debian-based systems and intercepts calls to malloc, free et al.)
I suspect you could use this mechanism to trap or argument-check calls to any libc functions you don't like, and perhaps to note those which you consider unconditionally safe. It might then be reasonable to scan the compiled executable for the code corresponding to INT 0x80 to trap out any attempts to make raw syscalls (0xcd 0x80 - though beware of false positives). However I have only give this a few moments of thought, I could easily have missed something or this might turn out to be impractical...
You could run the compiled program by forking it from a wrapper and use the Linux ptrace(2) facility to intercept and inspect all system calls invoked by the program.
The following example code shows a wrapper that runs the /usr/bin/w command, prints each system call invoked by the command, and terminates the command if it tries to invoke the write(2) system call.
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/ptrace.h>
#include <sys/wait.h>
#include <sys/syscall.h>
#include <sys/reg.h>
#define BAD_SYSCALL __NR_write
int main(int argc, char *argv)
{
pid_t child;
int status, syscall_nr;
child = fork();
if (child == 0) {
/* In child. */
ptrace(PTRACE_TRACEME, 0, NULL, NULL);
execl("/usr/bin/w", NULL, NULL);
// not reached
}
/* In parent. */
while (1) {
wait(&status);
/* Abort loop if child has exited. */
if (WIFEXITED(status) || WIFSIGNALED(status))
break;
/* Obtain syscall number from the child's process context. */
syscall_nr = ptrace(PTRACE_PEEKUSER, child, 4 * ORIG_EAX, NULL);
printf("Child wants to execute system call %d: ", syscall_nr);
if (syscall_nr != BAD_SYSCALL) {
/* Allow system call. */
printf("allowed.\n");
ptrace(PTRACE_SYSCALL, child, NULL, NULL);
} else {
/* Terminate child. */
printf("not allowed. Terminating child.\n");
ptrace(PTRACE_KILL, child, NULL, NULL);
}
}
exit(EXIT_SUCCESS);
}
You can do much more powerful things using ptrace, such as inspect and change a process' address space (e.g., to obtain and modify the parameters passed to a system call).
A good introduction can be found in this Linux Journal Article and its follow-up.
You can't.
Even this program:
#include <stdio.h>
int main()
{
printf("Hello, World\n");
return 0;
}
makes at least one system call (to send the string "Hello, World\n" to standard out). System calls are the only way for a program to interact with the outside World. Use the operating system's security model for security.
Edited for this comment:
I meant not all system calls but malicious system calls, e.g. execv() could be used to execute a BASH script which wipes out my data on the disk.
Your operating system already includes mechanisms to stop that sort of thing happening. For instance, in order for a bash script to wipe out your data, the process must already have write access to that data. That means it must have been started by you or root. Your only real option is not to install untrustworthy software.
By the way, depending on your platform, execv is not necessarily a system call. On Linux, it's a C library wrapper for the real system call (execve).
Just to illustrate that this is not possible, the following program:
int main() {
return 0;
}
makes over 20 system calls as reported using strace. The calls include open (twice) which is one of the calls you seem to want to block.
Well, if you just want to block specific calls, why not just do a grep through the source code before attempting to compile it ? And reject programs which use the insecure system calls.
Some project have similar idea you can take a look at nacl: http://code.google.com/p/nativeclient/
How do you run an external program and pass it command line parameters using C? If you have to use operating system API, include a solution for Windows, Mac, and Linux.
It really depends on what you're trying to do, exactly, as it's:
OS dependent
Not quite clear what you're trying to do.
Nevertheless, I'll try to provide some information for you to decide.
On UNIX, fork() creates a clone of your process from the place where you called fork. Meaning, if I have the following process:
#include <unistd.h>
#include <stdio.h>
int main()
{
printf( "hi 2 u\n" );
int mypid = fork();
if( 0 == mypid )
printf( "lol child\n" );
else
printf( "lol parent\n" );
return( 0 );
}
The output will look as follows:
hi 2 u
lol child
lol parent
When you fork() the pid returned in the child is 0, and the pid returned in the parent is the child's pid. Notice that "hi2u" is only printed once... by the parent.
execve() and its family of functions are almost always used with fork(). execve() and the like overwrite the current stackframe with the name of the application you pass to it. execve() is almost always used with fork() where you fork a child process and if you're the parent you do whatever you need to keep doing and if you're the child you exec a new process. execve() is also almost always used with waitpid() -- waitpid takes a pid of a child process and, quite literally, waits until the child terminates and returns the child's exit status to you.
Using this information, you should be able to write a very basic shell; one that takes process names on the command line and runs processes you tell it to. Of course, shells do more than that, like piping input and output, but you should be able to accomplish the basics using fork(), execve() and waitpid().
NOTE: This is *nix specific! This will NOT work on Windows.
Hope this helped.
If you want to perform more complicated operations, like reading the output of the external program, you may be better served by the popen system call. For example, to programmatically access a directory listing (this is a somewhat silly example, but useful as an example), you could write something like this:
#include <stdio.h>
int main()
{
int entry = 1;
char line[200];
FILE* output = popen("/usr/bin/ls -1 /usr/man", "r");
while ( fgets(line, 199, output) )
{
printf("%5d: %s", entry++, line);
}
}
to give output like this
1: cat1
2: cat1b
3: cat1c
4: cat1f
5: cat1m
6: cat1s
...
#include <stdlib.h>
int main()
{
system("echo HAI");
return 0;
}
I want to give a big warning to not use system and 100% never use system when you write a library. It was designed 30 years ago when multithreading was unknown to the toy operating system called Unix. And it is still not useable even when almost all programs are multithreaded today.
Use popen or do a fork+execvp, all else is will give you hard to find problems with signal handling, crashs in environment handling code etc. It's pure evil and a shame that the selected and most rated answer is promoting the use of "system". It's more healthy to promote the use of Cocain on the workplace.
On UNIX, I think you basically need to fork it if you want the spawned process to run detached from your the spawing one : For instance if you don't want your spawned process to be terminate when you quit your spawning process.
Here is a page that explains all the subtle differences between Fork, System, Exec.
If you work on Win,Mac and linux, I can recommend you the Qt Framework and its QProcess object, but I don't know if that's an option for you. The great advantages is that you will be able to compile the same code on windows linux and mac :
QString program = "./yourspawnedprogram";
QProcess * spawnedProcess = new QProcess(parent);
spawnedProcess->start(program);
// or spawnedProcess->startDetached(program);
And for extra, you can even kill the child process from the mother process,
and keep in communication with it through a stream.
One solution is the system function defined in stdlib.h
int system(const char *string);
system api example
If you need to check/read/parse the output of your external command, I would suggest to use popen() instead of system().
Speaking of platform-dependent recipes, on Windows use CreateProcess, on Posix (Linux, Mac) use fork + execvp. But system() should cover your basic needs and is part of standard library.