I am creating chroot jail in linux , but i do not have access to any system file like ls/cd/gcc/g++. What are the necessary libs/bin/systme files i need to copy to my chroot jail ?
To create a basic debian-based root file systems (not necessarily on debian-based host systems), you can use debootstrap or multistrap tool. I think there is also a febootstrap equivalent for fedora-based root file systems.
In debootstrap, you will have full control on which packages should be installed, over the base necessary packages, which are packages with "Priority: required" and "Priority: important" tag. In case of initial extra packages, you are responsible for package dependencies.
multistrap is a newer tool, which uses apt and can leverage multiple repositories, and so takes care of the dependency issue.
You can also do cross-bootstrapping which is creating a root fs for another architecture. This is useful when creating embedded or virtualized systems.
sample debootstrap command:
debootstrap wheezy rootfs/ http://ftp.us.debian.org/debian
then you can chroot into it and do whatever else is needed.
This is by far the easiest method to create chroots.
Executables like ls/cd/gcc/g++, they depend on shared library (unless you didn't build them to be statically). So, what you need to do is copy all those shared library dependencies to appropriate location into your chroot jail, also you need to find what are those shared dependencies are. To find out you need help from "ldd".
To see what shared dependencies gcc has, do the following:
ldd /usr/bin/gcc
On my system it shows the following output:
linux-vdso.so.1 => (0x00007fffd9bff000)
libc.so.6 => /lib64/libc.so.6 (0x00000030c9c00000)
/lib64/ld-linux-x86-64.so.2 (0x00000030c9800000)
So, gcc has the dependency of standard c library libc.so and it also needs ld (executable loader), place these shared libraries into appropriate place (i.e libc under /lib64) into your chroot jail, along with gcc. So gcc can load necessary stuffs while you call gcc.
Related
I have a compiled binary file.bin, which is dynamically linked to others.
$ ldd file.bin
linux-vdso.so.1 (0x00007ffc017c6000)
so.6 => /usr/lib/libm.so.6 (0x00007f3af51d7000)
so.2 => /usr/lib/libdl.so.2 (0x00007f3af51d1000)
so.6 => /usr/lib/libc.so.6 (0x00007f3af5008000)
ld-linux-x86-64.so.2 => /usr/lib64/ld-linux-x86-64.so.2 (0x00007f3af61a7000)
I need to be lib-independent, because my target system uses different version of those libraries. (executing file.bin on the target yields errors: /lib64/libm.so.6: version 'GLIBC_2.27' not found). I do not have the source code of file.bin.
My attempt is to add those dynamically linked files into that binary, I could not find any tools to do that. Is it even possible?
If that's helping: I can run the file.bin on a kernel 5.10.6-arch1-1 and the target is a kernel 3.10.0-1062.9.1.el7.x86_64
Without the source code for file.bin, you cannot build a static binary.
However, there are a number of tools such as Statifier and Ermine which can help you package the existing dynamic binary and its dependencies into a single binary.
Quoting from the Ermine website:
What can Ermine do for you?
Ermine packs a GNU/Linux application together with any needed shared libraries and data files into a single executable. This file can be copied to any GNU/Linux host and run without further modifications.
Basic functionality:
Only one file is installed
Escape from “dependency hell”
Independence from package management (RPM, DEB, TGZ, ...)
No version mismatch between the executable and its auxiliary files
No host-dependent side-effects: the application and the target host's software environment do not interfere with each other
My Machine is slackware linux 64 kernel 3.0.4.
For this machine I don't have root access and the administrator is not available.
I am trying to run a program that requires the library file libc version 2.14 and the one installed in /lib64 is libc-2.13.
I have an identical machine where I have root access. I tried copying the libc-2.14 file from this machine to the first one then place it into a $HOME/lib64 folder and adding this folder to LD_LIBRARY_PATH, then make a new symbolic link libc.so.6 to point to the libc-2.14 file but the program keeps reading the libc.so.6 file in the /lib64 which points to libc-2.13. I can't modify anything in the /lib64 because I am not root.
Is there anyway to get around this?
Thanks in advance
You need to copy other files from glibc, too. You will need the program interpreter /lib64/ld-linux-x86-64.so.2, and perhaps also libdl.so.2, libm.so.6, libpthread.so.0 and more of these helper libraries.
Once you have these, you can try to launch arbitrary programs with the other glibc using an explicit dynamic linker invocation. Assuming that you have copied the files into the current directory, you can try this:
./ld-linux-x86-64.so.2 --library-path . --inhibit-cache /bin/bash
Note that this only applies to the directly launched binaries (bash in the example). Child processes (commands launched from the shell) will again use the system glibc.
There could still be problems if you did not copy all the required glibc libraries, or if there have been incompatible changes in the locale format, so that the new glibc cannot use the system locales.
I have a directory with the following contents:
bin/busybox
lib/ld-linux.so.2
lib/libc.so.6
and when I invoke:
chroot . bin/busybox sh
it fails with the following:
/bin/busybox: error while loading shared libraries: libc.so.6: cannot open shared object file: No such file or directory
When I move lib/libc.so.6 to usr/lib, it works fine.
Why is libc required to be in /usr/lib? When I invoke:
objcdump -p bin/busybox | grep NEEDED
I get:
NEEDED libc.so.6
So I thought, as only the soname of the library is used without slashes etc. the loaded will be able to find it in the standard folders, which is /lib and /usr/lib. Apparently, this is not the case.
To make matters even more confusing, ld-linux.so.2 seems to have to be in /lib because when it is moved to /usr/lib, chroot fails with:
chroot: failed to run command '/bin/busybox': No such file or directory
which I learned is actually an error that the loader cannot be found, not the busybox binary.
Is the issue with libc.so.2 distro specific? If this is important, I'm using Arch Linux.
The location of the loader (typically something like /lib/ld-linux.so) is hard-coded in the binary. There's no search process for this component — if it cannot be found, the binary won't run at all.
(The exact path depends on what libc and architecture you're using. It's at /lib64/ld-linux-x86-64.so.2 for glibc on x86_64, for instance.)
The locations that will be searched for dynamic libraries are configurable in /etc/ld.so.conf. If you don't have that file in the chroot, though, some of the standard paths may not be configured!
I'm trying to install gcc4.9 on a SUSE system without an internet connection. I compiled gcc on an Ubuntu machine and installed it into a prefix, then copied the prefix folder to the SUSE machine. When I tried to run it gcc complained about not finding GLIBC_2_14, so I downloaded an rpm for libc6 online and included it into the prefix folders. my LD_LIBRARY_PATH includes prefix/lib and prefix/lib64. When I try to run any program now (ls, cp, cat, etc) I get the error error while loading shared libraries: /home/***/prefix/lib64/libc.so.6: unexpected reloc type 0x25.
Is there any way I can fix this so that I can get gcc4.9 up and running on this system?
As an alternative, is it possible to build gcc staticaly so that I don't have to worry about linking at all when I transfer it between computers?
my LD_LIBRARY_PATH includes prefix/lib and prefix/lib64
See this answer for explanation of why this can't work.
Is there any way I can fix this so that I can get gcc4.9 up and running on this system?
Your best bet is to install whatever GCC package comes with the SuSE system, then use that GCC to configure and install gcc-4.9 on it.
If for some reason you can't do that, this answer has some of the ways in which you can build gcc-4.9 on a newer system and have it still work on an older one.
is it possible to build gcc staticaly so that I don't have to worry about linking at all when I transfer it between computers?
Contrary to popular belief, fully-static binaries are generally less portable then dynamic ones on Linux.
I write some programs on linux with C
I want to run these programs on many remote computers, which are installed with fedora or ubuntu
I compiled the program with gcc on local machine, however the excutable file is not workable on remote machines.
for example: I use
gcc -o udp_server udp_server.c
on local machine to get a excutable binary file udp_server and then I copy it to a remote machine and run it there, the error is:
-bash: ./udp_server: /lib64/ld-linux-x86-64.so.2: bad ELF interpreter: No such file or directory
the local machine: fedora
Fedora release 16 (Verne)
Kernel \r on an \m (\l)
3.6.10-2.fc16.x86_64 GNU/Linux
the remote machine:
Fedora release 12 (Constantine)
Kernel \r on an \m (\l)
2.6.32-36.onelab.x86_64 GNU/Linux
on these remote machines, there are no gcc compiler
so I hope I can make some excutable files so that they can be executed on those remote machines
so what kind of excutable files should I make, and how to make them?
any recommenation tools or procedures?
thanks!
To run a program written in C, you must first compile it to produce an executable file. On Linux, the C compiler is typically the "Gnu C Compiler", or gcc.
If you compile a C program on Linux, it should usually run on any other Linux computer. However, a few conditions must be met for this to work:
A compiled executable is compiled for a specific processor architecture. For example, if you compile for x86-x64, the program will not run on x86 or PowerPC.
If the program uses shared libraries, these must be installed on the target system. The C library, "libc" is installed everywhere, other libraries may not be.
As to how to compile: For a simple program, you can invoke gcc directly. For more complex programs, some build tool is advisable. There are many to choose from; two popular choices are GNU make (the traditional solution), and CMake.
To distribute the program: If it is only a single executable, you can just copy this executable around. If the program consists of multiple files (images, data files, etc.), you should package it as a software package. This allows users to install it using a package manager such as RPM or dpkg. How to do this is explained in various packaging guides for the different Linux distributions.
Finally, a piece of advice: You seem to know very little about software development in general and in C in particular. Consider reading some tutorial on programmin in C - this will answer these (and many other) questions. There are countless books and online tutorials - I can recommend "The C book", by gbdirect.
The issue you see is you are missing a dynamic library on the target machine. To see which libraries you need you need to use "ldd" program. Example (I just execute it against standard program "test" which is in every single linux distribution):
$ ldd /usr/bin/test
linux-vdso.so.1 => (0x00007fff5fdfe000)
libc.so.6 => /lib64/libc.so.6 (0x00000032d0600000)
/lib64/ld-linux-x86-64.so.2 (0x00000032cfe00000)
On Fedora and RHEL you can find which RPM package you want to install using the following command
$ rpm -q --whatprovides /lib64/ld-linux-x86-64.so.2
glibc-2.16-28.fc18.x86_64
And then you need to install it:
$ yum -y install glibc-2.16-28.fc18.x86_64
I dont use Ubuntu / Debian, not sure how to do this. Please note that on 32bit systems libraries for 64bits are not avaiable, but on 64bit systems these libraries have usualla i686 tag and are installable.
Usually, you can execute your program on different machines as long as you keep the architecture. E.g. you cannot execute 64bit program on a 32bit machine, and also vice versa (you can workaround this by installing 32bit libs but thats maybe too difficult).
If you have different distributions, or different versions of same linux distribution, this might be problem - you need to make sure you have all the dependencies in the same major versions.
Or you can link libraries statically which is not usual in the linux world at all, but you can do this. Learn how to use GCC and then you will find out how to do that.