clock_gettime() doesn't work - linux

I read the following manual:
http://linux.die.net/man/3/clock_gettime
and I wrote the following code:
#include <time.h>
int main() {
struct timespec clk;
clock_gettime(CLOCK_REALTIME, &clk);
return 0;
}
Surprisingly, I get the following errors:
Symbol CLOCK_REALTIME could not be resolved
undefined reference to clock_gettime
I still don't understand what is the problem. I included the header, and these names show in this header.

maybe you should use#define _POSIX_TIMERS,#define _REENTRANT
besides, when you compile the code, make sure to link the real-time library which is cc filename.c -o filename -lrt
Update 1.0:
sometimes in windows or mac os, C ide may not include real-time library automatically, or we may not used the posix directly without _POSIX_TIMES, therefore you have to link the real-time library manually. In Linux, you can just type in cc filename.c -o filename -lrt to compile the c file.

Related

Why does dynamically loading of PIEs no longer work in glibc? [duplicate]

There is a large number of questions on SO about how to execute a library or dynamically load an executable. As far as I can tell, all the answers come down to: compile your executable as position-independent code and load it with dlopen. This worked great --- and still works great on macOS --- until a recent change in glibc, which explicitly disabled dlopening PIEs. This change is now in the current version of glibc (2.30) on ArchLinux, for example, and trying to dlopen a position-independent executable gives an error: "cannot dynamically load position-independent executable".
It's difficult to guess what prompted such a radical change that breaks so much code and useful use cases. (The explanations on Patchwork and Bugzilla don't make much sense to me.) But there is now a question: what to do if you want to create an executable that's also a dynamic library, or vice versa?
A solution was linked from one of the comments. Reproducing it here for posterity:
#include <stdio.h>
#include <unistd.h>
const char service_interp[] __attribute__((section(".interp"))) = "/lib/ld-linux-x86-64.so.2";
extern "C" {
void lib_entry(void)
{
printf("Entry point of the service library\n");
_exit(0);
}
}
Compiling with g++ -shared test-no-pie.cpp -o test-no-pie -Wl,-e,lib_entry produces a shared object (dynamic library) that can also be executed on Linux.
I have two questions:
What if I want to pass command-line arguments? How to modify this solution so it accepts arc,argv?
Are there other alternatives?
It's difficult to guess what prompted such a radical change
Not really: it never worked correctly.
that breaks so much code
That code was broken already in subtle ways. Now you get a clear indication that it will not work.
Are there other alternatives?
Don't do that?
What problem does dlopening an executable solve?
If it's a real problem, open a GLIBC bugzilla feature request, explaining that problem and requesting a supported mechanism to achieve desired result.
Update:
at least say why "it never worked correctly". Is it some triviality like potentially clashing globals between the executables, or something real?
Thread-local variables is an example that doesn't work correctly. Whether you think they are "real" or not I have no idea.
Here is the code:
// foo.c
#include <stdio.h>
__thread int var;
__attribute__((constructor))
static void init()
{
var = 42;
printf("foo.c init: %d %p\n", var, &var);
}
int bar() {
printf("foo.c bar: %d %p\n", var, &var);
return var;
}
int main()
{
printf("foo.c main: %d %p bar()=%d\n", var, &var, bar());
return 0;
}
gcc -g foo.c -o foo -Wl,-E -fpie -pie && ./foo
foo.c init: 42 0x7fb5dfd7d4fc
foo.c bar: 42 0x7fb5dfd7d4fc
foo.c main: 42 0x7fb5dfd7d4fc bar()=42
// main.c
// Error checking omitted for brevity
#include <dlfcn.h>
#include <stdio.h>
int main()
{
void *h1 = dlopen("./foo", RTLD_LOCAL|RTLD_LAZY);
int (*bar)(void) = dlsym(h1, "bar");
printf("main.c: %d\n", bar());
return 0;
}
gcc -g main.c -ldl && ./a.out
foo.c init: 42 0x7fb7305da73c
foo.c bar: 0 0x7fb7305da73c <<< what?
main.c: 0 <<< what?
This is using GNU C Library (Debian GLIBC 2.28-10) stable release version 2.28.
Bottom line: this was never designed to work, and you just happened to not step on many of the land-mines, so you thought it is working, when in fact you were exercising undefined behavior.
Please see this answer:
https://stackoverflow.com/a/68339111/14760867
The argc, argv question is not answered there, but when I found I needed one, I hacked something together to parse /proc/self/cmdline at runtime for pam_cap.so use.

Loading executable or executing a library

There is a large number of questions on SO about how to execute a library or dynamically load an executable. As far as I can tell, all the answers come down to: compile your executable as position-independent code and load it with dlopen. This worked great --- and still works great on macOS --- until a recent change in glibc, which explicitly disabled dlopening PIEs. This change is now in the current version of glibc (2.30) on ArchLinux, for example, and trying to dlopen a position-independent executable gives an error: "cannot dynamically load position-independent executable".
It's difficult to guess what prompted such a radical change that breaks so much code and useful use cases. (The explanations on Patchwork and Bugzilla don't make much sense to me.) But there is now a question: what to do if you want to create an executable that's also a dynamic library, or vice versa?
A solution was linked from one of the comments. Reproducing it here for posterity:
#include <stdio.h>
#include <unistd.h>
const char service_interp[] __attribute__((section(".interp"))) = "/lib/ld-linux-x86-64.so.2";
extern "C" {
void lib_entry(void)
{
printf("Entry point of the service library\n");
_exit(0);
}
}
Compiling with g++ -shared test-no-pie.cpp -o test-no-pie -Wl,-e,lib_entry produces a shared object (dynamic library) that can also be executed on Linux.
I have two questions:
What if I want to pass command-line arguments? How to modify this solution so it accepts arc,argv?
Are there other alternatives?
It's difficult to guess what prompted such a radical change
Not really: it never worked correctly.
that breaks so much code
That code was broken already in subtle ways. Now you get a clear indication that it will not work.
Are there other alternatives?
Don't do that?
What problem does dlopening an executable solve?
If it's a real problem, open a GLIBC bugzilla feature request, explaining that problem and requesting a supported mechanism to achieve desired result.
Update:
at least say why "it never worked correctly". Is it some triviality like potentially clashing globals between the executables, or something real?
Thread-local variables is an example that doesn't work correctly. Whether you think they are "real" or not I have no idea.
Here is the code:
// foo.c
#include <stdio.h>
__thread int var;
__attribute__((constructor))
static void init()
{
var = 42;
printf("foo.c init: %d %p\n", var, &var);
}
int bar() {
printf("foo.c bar: %d %p\n", var, &var);
return var;
}
int main()
{
printf("foo.c main: %d %p bar()=%d\n", var, &var, bar());
return 0;
}
gcc -g foo.c -o foo -Wl,-E -fpie -pie && ./foo
foo.c init: 42 0x7fb5dfd7d4fc
foo.c bar: 42 0x7fb5dfd7d4fc
foo.c main: 42 0x7fb5dfd7d4fc bar()=42
// main.c
// Error checking omitted for brevity
#include <dlfcn.h>
#include <stdio.h>
int main()
{
void *h1 = dlopen("./foo", RTLD_LOCAL|RTLD_LAZY);
int (*bar)(void) = dlsym(h1, "bar");
printf("main.c: %d\n", bar());
return 0;
}
gcc -g main.c -ldl && ./a.out
foo.c init: 42 0x7fb7305da73c
foo.c bar: 0 0x7fb7305da73c <<< what?
main.c: 0 <<< what?
This is using GNU C Library (Debian GLIBC 2.28-10) stable release version 2.28.
Bottom line: this was never designed to work, and you just happened to not step on many of the land-mines, so you thought it is working, when in fact you were exercising undefined behavior.
Please see this answer:
https://stackoverflow.com/a/68339111/14760867
The argc, argv question is not answered there, but when I found I needed one, I hacked something together to parse /proc/self/cmdline at runtime for pam_cap.so use.

How to hook without using dlsym in linux

I'm trying to hook some functions of glibc, like fopen, fread etc. But in the hook function, i have to use the same function as in glibc. Like this:
// this is my fopen
FILE *fopen(.....)
{
fopen(....);// this is glibc fopen
}
I have found one way to do this using dlsym, but in this way i have to replace all the glibc function calls with wrappers inside which call glibc function using dlsym.
I'm curious whether where is another way to do the same job without coding wrapper functions. I ever tryed this :
fopen.c
....fopen(..)
{
myfopen(..);
}
myfopen.c
myfopen(..)
{
fopen(...);// glibc version
}
main.c
int main()
{
fopen(...);
}
$ gcc -c *.c
$ gcc -shared -o libmyopen.so myopen.o
$ gcc -o test main.o fopen.o libmyopen.so
In my understanding, gcc will link from left to right as specified in the command line, so main.o will use fopen in fopen.o, fopen.o will use myfopen in libmyfopen.so, libmyfopen.so will use fopen in glibc. But when running, i got a segment fault, gdb shows there is a recusive call of fopen and myfopen. I'm a little confused. Can anyone explain why ?
my understanding, gcc will link from left to right as specified in the command line, so main.o will use fopen in fopen.o, fopen.o will use myfopen in libmyfopen.so, libmyfopen.so will use fopen in glibc
Your understanding is incorrect. The myfopen from libmyfopen.so will use the first definition of fopen available to it. In your setup, that definition will come from fopen.o linked into the test program, and you'll end up with infinite recursion, and a crash due to stack exhaustion.
You can observe this by running gdb ./test, running until crash, and using backtrace. You will see an unending sequence of fopen and myfopen calls.
the symbol fopen is not bond to that in libc when compiling
That is correct: in ELF format, the library records that it needs the symbol (fopen in this case) to be defined, but it doesn't "remember" or care which other module defines that symbol.
You can see this by running readelf -Wr libmyfopen.so | grep fopen.
That's different from windows DLL.
Yes.

Mixing PIC and non-PIC objects in a shared library

This question is related to this one as well as its answer.
I just discovered some ugliness in a build I'm working on. The situation looks somewhat like the following (written in gmake format); note, this specifically applies to a 32-bit memory model on sparc and x86 hardware:
OBJ_SET1 := some objects
OBJ_SET2 := some objects
# note: OBJ_SET2 doesn't get this flag
${OBJ_SET1} : CCFLAGS += -PIC
${OBJ_SET1} ${OBJ_SET2} : %.o : %.cc
${CCC} ${CCFLAGS} -m32 -o ${#} -c ${<}
obj1.o : ${OBJ_SET1}
obj2.o : ${OBJ_SET2}
sharedlib.so : obj1.o obj2.o
obj1.o obj2.o sharedlib.so :
${LINK} ${LDFLAGS} -m32 -PIC -o ${#} ${^}
Clearly it can work to mix objects compiled with and without PIC in a shared object (this has been in use for years). I don't know enough about PIC to know whether it's a good idea/smart, and my guess is in this case it's not needed but rather it's happening because someone didn't care enough to find out the right way to do it when tacking on new stuff to the build.
My question is:
Is this safe
Is it a good idea
What potential problems can occur as a result
If I switch everything to PIC, are there any non-obvious gotchas that I might want to watch out for.
Forgot I even wrote this question.
Some explanations are in order first:
Non-PIC code may be loaded by the OS into any position in memory in [most?] modern OSs. After everything is loaded, it goes through a phase that fixes up the text segment (where the executable stuff ends up) so it correctly addresses global variables; to pull this off, the text segment must be writable.
PIC executable data can be loaded once by the OS and shared across multiple users/processes. For the OS to do this, however, the text segment must be read-only -- which means no fix-ups. The code is compiled to use a Global Offset Table (GOT) so it can address globals relative to the GOT, alleviating the need for fix-ups.
If a shared object is built without PIC, although it is strongly encouraged it doesn't appear that it's strictly necessary; if the OS must fix-up the text segment then it's forced to load it into memory that's marked read-write ... which prevents sharing across processes/users.
If an executable binary is built /with/ PIC, I don't know what goes wrong under the hood but I've witnessed a few tools become unstable (mysterious crashes & the like).
The answers:
Mixing PIC/non-PIC, or using PIC in executables can cause hard to predict and track down instabilities. I don't have a technical explanation for why.
... to include segfaults, bus errors, stack corruption, and probably more besides.
Non-PIC in shared objects is probably not going to cause any serious problems, though it can result in more RAM used if the library is used many times across processes and/or users.
update (4/17)
I've since discovered the cause of some of the crashes I had seen previously. To illustrate:
/*header.h*/
#include <map>
typedef std::map<std::string,std::string> StringMap;
StringMap asdf;
/*file1.cc*/
#include "header.h"
/*file2.cc*/
#include "header.h"
int main( int argc, char** argv ) {
for( int ii = 0; ii < argc; ++ii ) {
asdf[argv[ii]] = argv[ii];
}
return 0;
}
... then:
$ g++ file1.cc -shared -PIC -o libblah1.so
$ g++ file1.cc -shared -PIC -o libblah2.so
$ g++ file1.cc -shared -PIC -o libblah3.so
$ g++ file1.cc -shared -PIC -o libblah4.so
$ g++ file1.cc -shared -PIC -o libblah5.so
$ g++ -zmuldefs file2.cc -Wl,-{L,R}$(pwd) -lblah{1..5} -o fdsa
# ^^^^^^^^^
# This is the evil that made it possible
$ args=(this is the song that never ends);
$ eval ./fdsa $(for i in {1..100}; do echo -n ${args[*]}; done)
That particular example may not end up crashing, but it's basically the situation that had existed in that group's code. If it does crash it'll likely be in the destructor, usually a double-free error.
Many years previous they added -zmuldefs to their build to get rid of multiply defined symbol errors. The compiler emits code for running constructors/destructors on global objects. -zmuldefs forces them to live at the same location in memory but it still runs the constructors/destructors once for the exe and each library that included the offending header -- hence the double-free.

Hook file saving in Linux

How can i hook file saving in Linux systems (to show my programm dialog, opearting with them then)?
Just use the inotify interface to get notification of file system changes. See: http://linux.die.net/man/7/inotify
You can try FILE_PRELOAD utility which generate C++ code with hooks, compile and LD_PRELOAD it. After short look at it you can feel how easy to hook linux. Start point is this tutorial.
For example, if you want to change 'open call' of file /tmp/some with /tmp/replace_with:
#: FILE_PRELOAD -C "A+f:/tmp/some:/tmp/replace_with" -- bash
#: echo "HaHa" >> /tmp/some
#: ll /tmp/some
ls: cannot access /tmp/some: No such file or directory
#: cat /tmp/replace_with
HaHa
If you want to see the source of generated code just add "-p" to options.
#: FILE_PRELOAD -p -C "A+f:/tmp/some:/tmp/replace_with" -- bash
In additional all generated.cpp files you can find in /tmp/$USER/FILE_PRELOAD/cpp.
Have a nice play with linux hooks)
Generated code looks like this:
#include <sys/types.h>
#include <dlfcn.h>
#include <stdio.h>
#include <map>
#include <string>
#define I int
#define C char
#define S string
#define P printf
#define R return
using std::map;
using std::string;
typedef map<S,S> MAP;
static I (*old_open)(const C *p, I flags, mode_t mode);
extern "C"
I open (const C *p, I flags, mode_t mode){
old_open = dlsym(RTLD_NEXT, "open");
P("open hook\n");
MAP files;
files[p]=p;
files["/tmp/some"]="/tmp/replace_with";
S newpath = files[S(p)];
R old_open(newpath.c_str(), flags, mode);
}
# &compile
gcc -w -fpermissive -fPIC -c -Wall file.cpp
gcc -shared file.o -ldl -lstdc++ -o wrap_loadfile.so
LD_PRELOAD=./wrap_loadfile.so bash
nm -D /lib/libc.so.6 | grep open # we hook this syscall
If you can compile them you can link first against a custom library that provides open().
There's a stock way of doing it.
If you can't compile it, this works most of the time:
Write function _open_posthook that does syscall(NR_OPEN, ...)
Provide shared library libopenhook that provides your new open. Rembember you renamed open to _open_posthook() here unless you want recursion. Don't forget to also provide creat().
Load this library with LD_PRELOAD.
EDIT: if you're trying for security this won't work. You might be able to get away with using strace() but unless you are very careful a determined programmer can overcome that too.

Resources