Using LD_PRELOAD on Fedora 25 causes Segmentation Fault - linux

I have found a strange behavior while I was trying to use a library that I wrote a long time ago. The main problem is, when the program is executed on Fedora 25 and linked to my library by using LD_PRELOAD, the system raises a Segmentation Fault. I've made a small sample of my old library to easily understand the problem.
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
extern void *__libc_malloc(size_t size);
void *malloc(size_t size)
{
void *ptr = __libc_malloc(size);
fprintf(stdout, "Malloc(%d)->(%p)\n", (int) size, ptr);
return ptr;
}
This code was compiled by using these parameters:
gcc -c -fPIC -O3 -Wall -o libtest.o libtest.c
gcc -shared -o libtest.so libtest.o
The program was executed as follows:
LD_PRELOAD=./libtest.so ./progtest
I found out that the "fprintf" line was causing the Segfault problem. So I've changed the "stdout" file descriptor to "stderr", and the problem was gone.
Then I tested the same code using the "stdout" file descriptor as output for "fprintf" on another machine running CentOS 7, and it worked fine in both cases using "stdout" and "stderr".
By observing these results, I wonder what I am missing and why this is happening.
GLibc and GCC versions installed on Fedora 25:
GNU ld version 2.26.1-1.fc25
gcc (GCC) 6.3.1 20161221 (Red Hat 6.3.1-1)
GLibc and GCC versions installed on CentOS 7:
GNU ld version 2.25.1-22.base.el7
gcc (GCC) 4.8.5 20150623 (Red Hat 4.8.5-11)

fprintf itself may need to use malloc under some circumstances. One possible reason is that stderr is unbuffered while stdout is line buffered. fprintf(stdout) might have a buffer already, or it may try to allocate one, ending up calling your malloc, which calls into fprintf again, but it is not re-entrant on the same FILE*.
You can prevent re-entrancy with a flag, such as (C11):
#include <stdbool.h>
#include <threads.h>
thread_local bool inside_malloc = false;
void *malloc(size_t size) {
void *ptr = __libc_malloc(size);
if (!inside_malloc) {
inside_malloc = true;
fprintf(stdout, "Malloc(%zd)->(%p)\n", size, ptr);
inside_malloc = false;
}
return ptr;
}

Related

Do I have to re-compile glibc 2.34 itself for full 64-bit time_t support for 32-bit hardware?

My CPU is of type armhf, so 32-bit. I run Linux Kernel 5.4 on it (so it supports 64-bit time_t for 32-bit system). I compile programs against glibc 2.34 (so time_t can be explicitely set to be 64-bit instead of 32-bit).
Now I am trying to get this simple piece of code working (test.c).
#include <stdio.h>
#include <sys/stat.h>
#include <string.h>
#include <errno.h>
int main()
{
int ret = 0;
ret = lchmod ("/tmp/testme.file", 0755);
printf("ret=%d; errno=%d, strerror=%s\n", ret, errno, strerror(errno));
return 0;
}
(Cross-)Compile it like so:
arm-linux-gnueabihf-gcc -D_FILE_OFFSET_BITS=64 -D_TIME_BITS=64 test.c -o test
To test the program I set my system date to 2084-01-01 (beyond year 2038 is important). Then I create a file by running touch /tmp/testme.file. This file gets a creation timestamp of 2084-01-01. Now when I run the above code ./test it gives me this error message:
ret=-1; errno=75, strerror=Value too large for defined data type
It seems Value too large for defined data type error happens because the function lchmod(...) cannot handle files with creation timestamps beyond year 2038.
Why is this? Is this a glibc bug or does the glibc 2.34 itself has to be re-compiled with additional CFLAGS -D_FILE_OFFSET_BITS=64 -D_TIME_BITS=64.
When I change lchmod(...) to chmod(...) it works.

How to CosmoNim (GCC) on Solus Linux? (segfault)

What methods or tools can I use to help figure out the below issue?
I'd like to use CosmoNim on Solus Linux. It works on other linux distributions, but produces executables that segfault when built on Solus Linux. CosmoNim works for me on Ubuntu just fine.
CosmoNim is a Nim wrapper to use Cosmopolitan
Cosmopolitan is a library and method to produce universal binaries built with GCC
Nim is a transpiler to C (auto compiling with GCC)
So CosmoNim should work out of the box on many linux distros (and does indeed work on Ubuntu)
However, CosmoNim fails to make a functioning executable on Solus (the executable segfaults when run) before doing the objcopy to make the full universal executable.
But! Cosmopolitan (directly using GCC) HelloWorld does work on Solus
So Nim is either missing some compile or link flags for GCC or it's doing something it shouldn't for this process
How can I make progress on figuring this out?
Upon using GDB, it reports the main() function for the segfault:
$ gdb hello.elf ...
Program received signal SIGSEGV, Segmentation fault.
0x0000000000413005 in NimMain ()
121 N_CDECL(void, NimMain)(void) {
This is starting at that line 121 in the source file:
N_CDECL(void, NimMain)(void) {
void (*volatile inner)(void);
PreMain();
inner = NimMainInner;
initStackBottomWith((void *)&inner);
(*inner)();
}
int main(int argc, char** args, char** env) {
cmdLine = args;
cmdCount = argc;
gEnv = env;
NimMain();
return nim_program_result;
}
$ (gdb) info functions
121: void NimMain(void);
117: void NimMainInner(void);
137: void NimMainModule(void);
108: void PreMain(void);
102: void PreMainInner(void);
129: int main(int, char **, char **);
Any GDB/compiler utils wizards out there know how to introspect this?

Symbols defined with defsym give incorrect address on Ubuntu 16.10

If I define a symbol address when linking a program on Ubuntu 16.10, this doesn't seem to produce the correct address when running the program. For example taking the following program
#include <stdio.h>
extern int mem_;
int main()
{
printf("%p\n", &mem_);
}
and compiling with
gcc example.c -o example -Xlinker --defsym=mem_=0x80
then running the program prints 0x80 on older Ubuntu systems, but a random number on Ubuntu 16.10. The 0x80 symbol seems to go into the executable, as shown by the nm program, however.
Any ideas what's causing this? I'm suspecting a security feature.
Under the GCC section of the ChangeLog (found here: https://wiki.ubuntu.com/YakketyYak/ReleaseNotes)
"We have modified GCC to by-default compile programs with position independent executable support, on the amd64 and ppc64el architectures, to improve the security benefits provided by Address Space Layout Randomization."
To disable this option, simply add -no-pie to GCC's flags.

timed_mutex won't compile under Cygwin 4.8.2 ('timed_mutex' in namespace 'std' does not name a type)

My file test8.cpp is
#include<thread>
#include<mutex>
#include<chrono>
std::mutex mutex;
std::timed_mutex timed_mutex;
When I compile this code
g++ -std=c++11 -pthread -c test8.cpp
it tells me
timed_mutex in namespace 'std' does not name a type
I compile under Cygwin64, gcc version 4.8.2
==================================================================
#Jonathan Wakely
The timed_mutex type is only defined if the platform supports it. The preprocessor conditions in GCC's <mutex> are:
#ifdef _GLIBCXX_USE_C99_STDINT_TR1
which is defined if the platform defines a usable <stdint.h> header, and
#if _GTHREAD_USE_MUTEX_TIMEDLOCK
which is defined if the macro _POSIX_TIMEOUTS is defined to a positive value by the <unistd.h> header.
If the first macro was not defined then you would not be able to use std::mutex either, so it seems that only the second macro is undefined, implying that Cygwin's Pthreads implementation doesn't support the Timeouts features.
The test used to check for the Timeouts feature is similar to:
#include <unistd.h>
// In case of POSIX threads check _POSIX_TIMEOUTS.
#if (defined(_PTHREADS) \
&& (!defined(_POSIX_TIMEOUTS) || _POSIX_TIMEOUTS <= 0))
#error
#endif
int main() { }
You could try compiling that on Cygwin, and checking for the macro yourself. If Cygwin does support the Timeouts features then please report a GCC bug so we can make timed_mutex work on Cygwin.
Edit: For GCC 6 I have added an alternative implementation of std::timed_mutex for platforms that don't define _POSIX_TIMEOUTS. I don't know if that will help on Cygwin or not.

g++4.6 std::thread error on Mac OS-X 10.5

I was trying to test thread library of gcc4.6 on mac OS-X 10.5.
I successfully compiled and installed gcc4.6 by macports.
But the simplest concurrent hello world program failed. The code is like:
#include <iostream>
#include <thread>
void sayhello() {std::cout << "Hello\n";}
int main(){
std::thread t(sayhello);
t.join();
}
I tried to compile and used g++ -Wall -std=c++0x test.cpp
I got the error:
'thread' is not a member of 'std'
Any idea what cause the problem and how can I fix it?
Thanks!
Unfortunately, pthreads implementation as of OSX 10.6.8 lacks some required features for C++0x threads. During configure, gcc detects this and disable support for them. More details at std::thread in MacPorts gcc4.5

Resources