Unable to apply patch with nested directories - linux

I am trying to create simple patch but file is in different directory.
My Directory structure is:
/-|hello_new.c
|-1/-|
|-2/-|
|-3/hello.c
//hello_new.c:
#include <stdio.h>
int main(int argc, char *argv[]) {
printf("Hello World\n");
}
//hello.c:
#include <stdio.h>
int main()
{
printf("Hello World\n");
}
I create the patch using:
diff -u 1/2/3/hello.c hello_new.c > hello.patch
My patch file is hello.patch:
--- 1/2/3/hello.c 2016-02-09 13:31:04.904763020 +0530
+++ hello_new.c 2016-02-08 18:35:47.299940190 +0530
## -1,6 +1,5 ##
#include <stdio.h>
-int main()
-{
+int main(int argc, char *argv[]) {
printf("Hello World\n");
}
Now I apply patch using:
patch < hello.patch
But I get patching file hello_new.c
Reversed patch detected.

You would solve this using the -p option of patch:
-p number
--strip=number
Set the file name strip count to number. See patch Directories.
If the before/after levels in your patch-file differ, keep in mind that patch gives precedence to the number of levels in the before part (the first line of the header). So you could do
patch -p3 < hello.patch
to avoid the reversed-patch issue for this instance.
This being GNU patch, you can preview the result by adding the --dry-run option (to avoid the nuisance of giving correct responses to the reversed-patch message):
$ patch -p3 --dry-run < hello.patch
patching file hello.c
Hunk #1 succeeded at 2 with fuzz 2 (offset 1 line).
When testing patches, e.g., if they did not match exactly (such as tab/space conversion, carriage-return line-endings), I preview patches, and may add a -l option to help patch make fewer rejects.

Related

ftrace: system crash when changing current_tracer from function_graph via echo

I have been playing with ftrace recently to monitor some behavior characteristics of my system. I've been handling switching the trace on/off via a small script. After running the script, my system would crash and reboot itself. Initially, I believed that there might be an error with the script itself, but I have since determined that the crash and reboot is a result of echoing some tracer to /sys/kernel/debug/tracing/current_tracer when current_tracer is set to function_graph.
That is, the following sequence of commands will produce the crash/reboot:
echo "function_graph" > /sys/kernel/debug/tracing/current_tracer
echo "function" > /sys/kernel/debug/tracing/current_tracer
Durning the reboot after the crash caused by the above echo statements, I see a lot of output that reads:
clearing orphaned inode <inode>
I tried to reproduce this problem by replacing the current_tracer value from function_graph to something else in a C program:
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
int openCurrentTracer()
{
int fd = open("/sys/kernel/debug/tracing/current_tracer", O_WRONLY);
if(fd < 0)
exit(1);
return fd;
}
int writeTracer(int fd, char* tracer)
{
if(write(fd, tracer, strlen(tracer)) != strlen(tracer)) {
printf("Failure writing %s\n", tracer);
return 0;
}
return 1;
}
int main(int argc, char* argv[])
{
int fd = openCurrentTracer();
char* blockTracer = "blk";
if(!writeTracer(fd, blockTracer))
return 1;
close(fd);
fd = openCurrentTracer();
char* graphTracer = "function_graph";
if(!writeTracer(fd, graphTracer))
return 1;
close(fd);
printf("Preparing to fail!\n");
fd = openCurrentTracer();
if(!writeTracer(fd, blockTracer))
return 1;
close(fd);
return 0;
}
Oddly enough, the C program does not crash my system.
I originally encountered this problem while using Ubuntu (Unity environment) 16.04 LTS and confirmed it to be an issue on the 4.4.0 and 4.5.5 kernels. I have also tested this issue on a machine running Ubuntu (Mate environment) 15.10, on the 4.2.0 and 4.5.5 kernels, but was unable to reproduce the issue. This has only confused me further.
Can anyone give me insight on what is happening? Specifically, why would I be able to write() but not echo to /sys/kernel/debug/tracing/current_tracer?
Update
As vielmetti pointed out, others have had a similar issue (as seen here).
The ftrace_disable_ftrace_graph_caller() modifies jmp instruction at
ftrace_graph_call assuming it's a 5 bytes near jmp (e9 ).
However it's a short jmp consisting of 2 bytes only (eb ). And
ftrace_stub() is located just below the ftrace_graph_caller so
modification above breaks the instruction resulting in kernel oops on
the ftrace_stub() with the invalid opcode like below:
The patch (shown below) solved the echo issue, but I still do not understand why echo was breaking previously when write() was not.
diff --git a/arch/x86/kernel/mcount_64.S b/arch/x86/kernel/mcount_64.S
index ed48a9f465f8..e13a695c3084 100644
--- a/arch/x86/kernel/mcount_64.S
+++ b/arch/x86/kernel/mcount_64.S
## -182,7 +182,8 ## GLOBAL(ftrace_graph_call)
jmp ftrace_stub
#endif
-GLOBAL(ftrace_stub)
+/* This is weak to keep gas from relaxing the jumps */
+WEAK(ftrace_stub)
retq
END(ftrace_caller)
via https://lkml.org/lkml/2016/5/16/493
Looks like you are not the only person to notice this behavior. I see
https://lkml.org/lkml/2016/5/13/327
as a report of the problem, and
https://lkml.org/lkml/2016/5/16/493
as a patch to the kernel that addresses it. Reading through that whole thread it appears that the issue is some compiler optimizations.

One file input to two program in script

Hi I have a script that run two program
#Script file
./prog1
./prog2
prog1 is a C program
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char **argv){
printf("prog1 running\n");
int tmp;
scanf("%d", &tmp);
printf("%d\n", tmp+10);
printf("prog1 ended\n");
return 0;
}
prog 2 is a C program as well
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char **argv){
printf("prog2 running\n");
int tmp;
scanf("%d\n", &tmp);
printf("%d\n", tmp+10);
printf("prog2 ended\n");
return 0;
}
I run the command
./script < file
where file is
123
456
The output is
prog1 running
133
prog1 ended
prog2 running
10
prog2 ended
It seems like prog2 did not get the input from file, what is happening under the hood?
Will it be possible that prog2 took "\n" instead of a number?
Your script should be this:
#!/bin/bash
exec 3<&1
tee >(./prog2 >&3) | ./prog1
This use the tee command to duplicate stdin and the recent >() bash feature to open a temporary filedescriptor. (the use of filedesriptor 3 is done to split the stdout without parallelism).
See this answer to read the whole story.
scanf reads buffered input. So when your first program reads from stdin, it speculatively reads ahead all the available input to make future reads from stdin faster (through avoiding having to make so many system calls). When the second program runs, there's no input left, and (since you failed to check the result of scanf()) you end up with 0 in tmp.
You should be able to modify the buffering strategy in your application (at the expense of speed) using the setvbuf() standard function.

Is there a way can view real process cmdline on linux?

Here is a simple code to fake process name and cmdline on linux:
#include <string.h>
#include <sys/prctl.h>
#include <stdio.h>
#include <unistd.h>
#define NewName "bash"
#define ProcNameMaxLen 16
int main(int argc, char **argv){
int oldlen = strlen(*argv);
char procname[ProcNameMaxLen];
memset(*argv, 0, oldlen);
memccpy(*argv, NewName, 0, oldlen); //modify cmdline
memccpy(procname, NewName, 0, ProcNameMaxLen);
prctl(PR_SET_NAME, procname); //modify procname
sleep(60);
return 0;
}
After run this code I can't view real name by ps,
but something can find in /proc/xxx/exe and /proc/xxx/environ, but so cumbersome.
is there a good way can view real information with all process?
I think this is a big security problem because i usually check process by ps on my server.
way 1: lsof -d txt
Wait more answer...
lsof will tell you the original executable name as it is one of the open files of the malicious process. You can inspect a number of processes using the -p option, or query a single user with the -u option.

Externally disabling signals for a Linux program

On Linux, is it possible to somehow disable signaling for programs externally... that is, without modifying their source code?
Context:
I'm calling a C (and also a Java) program from within a bash script on Linux. I don't want any interruptions for my bash script, and for the other programs that the script launches (as foreground processes).
While I can use a...
trap '' INT
... in my bash script to disable the Ctrl C signal, this works only when the program control happens to be in the bash code. That is, if I press Ctrl C while the C program is running, the C program gets interrupted and it exits! This C program is doing some critical operation because of which I don't want it be interrupted. I don't have access to the source code of this C program, so signal handling inside the C program is out of question.
#!/bin/bash
trap 'echo You pressed Ctrl C' INT
# A C program to emulate a real-world, long-running program,
# which I don't want to be interrupted, and for which I
# don't have the source code!
#
# File: y.c
# To build: gcc -o y y.c
#
# #include <stdio.h>
# int main(int argc, char *argv[]) {
# printf("Performing a critical operation...\n");
# for(;;); // Do nothing forever.
# printf("Performing a critical operation... done.\n");
# }
./y
Regards,
/HS
The process signal mask is inherited across exec, so you can simply write a small wrapper program that blocks SIGINT and executes the target:
#include <signal.h>
#include <unistd.h>
#include <stdio.h>
int main(int argc, char *argv[])
{
sigset_t sigs;
sigemptyset(&sigs);
sigaddset(&sigs, SIGINT);
sigprocmask(SIG_BLOCK, &sigs, 0);
if (argc > 1) {
execvp(argv[1], argv + 1);
perror("execv");
} else {
fprintf(stderr, "Usage: %s <command> [args...]\n", argv[0]);
}
return 1;
}
If you compile this program to noint, you would just execute ./noint ./y.
As ephemient notes in comments, the signal disposition is also inherited, so you can have the wrapper ignore the signal instead of blocking it:
#include <signal.h>
#include <unistd.h>
#include <stdio.h>
int main(int argc, char *argv[])
{
struct sigaction sa = { 0 };
sa.sa_handler = SIG_IGN;
sigaction(SIGINT, &sa, 0);
if (argc > 1) {
execvp(argv[1], argv + 1);
perror("execv");
} else {
fprintf(stderr, "Usage: %s <command> [args...]\n", argv[0]);
}
return 1;
}
(and of course for a belt-and-braces approach, you could do both).
The "trap" command is local to this process, never applies to children.
To really trap the signal, you have to hack it using a LD_PRELOAD hook. This is non-trival task (you have to compile a loadable with _init(), sigaction() inside), so I won't include the full code here. You can find an example for SIGSEGV on Phack Volume 0x0b, Issue 0x3a, Phile #0x03.
Alternativlly, try the nohup and tail trick.
nohup your_command &
tail -F nohup.out
I would suggest that your C (and Java) application needs rewriting so that it can handle an exception, what happens if it really does need to be interrupted, power fails, etc...
I that fails, J-16 is right on the money. Does the user need to interract with the process, or just see the output (do they even need to see the output?)
The solutions explained above are not working for me, even by chaining the both commands proposed by Caf.
However, I finally succeeded in getting the expected behavior this way :
#!/bin/zsh
setopt MONITOR
TRAPINT() { print AAA }
print 1
( ./child & ; wait)
print 2
If I press Ctrl-C while child is running, it will wait that it exits, then will print AAA and 2. child will not receive any signals.
The subshell is used to prevent the PID from being shown.
And sorry... this is for zsh though the question is for bash, but I do not know bash enough to provide an equivalent script.
This is example code of enabling signals like Ctrl+C for programs which block it.
fixControlC.c
#include <stdio.h>
#include <signal.h>
int sigaddset(sigset_t *set, int signo) {
printf("int sigaddset(sigset_t *set=%p, int signo=%d)\n", set, signo);
return 0;
}
Compile it:
gcc -fPIC -shared -o fixControlC.so fixControlC.c
Run it:
LD_LIBRARY_PATH=. LD_PRELOAD=fixControlC.so mysqld

How to turn a regular file into a symlink on Linux

I'm writing an (un)archiving tool and the way it is designed it first creates a regular file from the archive before it examines the special attributes and may decide that this item is a symlink, in fact.
Note: Before more people misunderstand me for wanting to make a symlink of a file. No, I write the symlink data, i.e. its path, into the file, and then I want to tell the file system that this is a symlink
I've been developing this on OS X, where it's possible to turn a regular file into a symlink by simply setting its Type and Creator codes accordingly.
Now I like to get this code working on Linux as well. So I like to find a similar way there.
I am aware that the normal way to create a symlink is to call the symlink() function, but I wonder if there is also a way to change a regular file into a symlink, just like it's possible in OSX's BSD system, so that I do not have to refactor my working code too much?
There is lstat(), which returns the file type in st_mode's upmost bits. Now I wonder if there's also an analogous setter function for this mode field.
I don't believe there is a way in Linux to do this as you describe. IIRC, the filesystem stores symlink information in the inode table and not in a regular file so there's no direct way of turning a file into a link.
If the symlink's path is stored inside the file, why not read out the path, delete the file, and create a symlink in its place?
Demonstrating what I wrote as a comment to bmarguiles's answer,
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
int main(int argc, char **argv) {
char *buffer = 0, *name = 0;
int i;
for (i = 1; i < argc; i++) {
struct stat st;
int fd = open(argv[i], O_RDONLY);
fstat(fd, &st);
buffer = realloc(buffer, st.st_size + 1);
read(fd, buffer, st.st_size);
close(fd);
buffer[st.st_size] = '\0';
name = realloc(name, strlen(argv[i]) + 2);
sprintf(name, "%s~", argv[i]);
symlink(buffer, name);
rename(name, argv[i]);
}
free(buffer);
free(name);
return 0;
}
$ vi f2s.c
...
$ cc -o f2s f2s.c
$ echo -n / > test
$ ./f2s test
$ ls -l test
lrwxrwxrwx 1 me me 1 Feb 24 23:17 test -> /
$ echo -n / > test2
$ strace ./f2s test2
open("test2", O_RDONLY) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=1, ...}) = 0
read(3, "/", 1) = 1
close(3) = 0
symlink("/", "test2~") = 0
rename("test2~", "test2") = 0
This is just a demonstration; it really needs more error-handling and maybe a better temporary filename.
No, you can't turn one into the other. You have to unlink to kill the file and then symlink to create a symlink as a replacement.

Resources