11

The reason that I need to somehow become root without typing sudo is because

error while loading shared libraries: libc.so.6: 
    cannot open shared object file: No such file or directory

I used sudo to have sudo mv /lib64/libc.so.6 /lib64/libc.so.6.bak

Because I followed some instructions so that I can update the symbolic link to libc-12.4.so instead of the current libc-12.2.so by

LD_PRELOAD=./libc-2.14.so ln -s ./libc-2.14.so ./libc.so.6

But this doesn't work using sudo. Now I am afraid to logout or reboot to the death of the system. Because I need to get root permission to fix this.

I don't have a rescue disk. worse case, I have to mount the hard drive to another machine and fix it.

Please help.

$ sudo bash -c "LD_PRELOAD=./libc-2.14.so ln -s ./libc-2.14.so ./libc.so.6"
sudo: error while loading shared libraries: libc.so.6: cannot open shared object file: No such file or directory

$ LD_PRELOAD=./libc-2.14.so sudo LD_PRELOAD=./libc-2.14.so ln -s ./libc-2.14.so ./libc.so.6
sudo: error while loading shared libraries: libc.so.6: cannot open shared object file: No such file or directory

$ LD_PRELOAD=./libc-2.12.so sudo LD_PRELOAD=./libc-2.12.so ln -s ./libc-2.12.so ./libc.so.6
sudo: error while loading shared libraries: libc.so.6: cannot open shared object file: No such file or directory

$ LD_PRELOAD=./libc-2.12.so ln -s ./libc-2.12.so ./libc.so.6
ln: creating symbolic link `./libc.so.6': Permission denied
3
  • Use sudo bash -c "LD_PRELOAD=./libc-2.14.so ln -s ./libc-2.14.so ./libc.so.6", if on the same partition Apr 28, 2018 at 17:55
  • Did you try LD_PRELOAD=./libc-2.14.so sudo LD_PRELOAD=./libc-2.14.so ln -s ./libc-2.14.so ./libc.so.6 (with the preload var being set both for sudo and ln)?
    – Byte Commander
    Apr 28, 2018 at 17:55
  • thanks for reply. not working. I cannot do anything now, like simple command like ls without libc.so.6 moved back to where it was...
    – Hao
    Apr 28, 2018 at 18:09

4 Answers 4

8

You should just boot from a live USB (or CD/DVD) and rename libc.so.6 back.

LD_PRELOAD doesn't work with setuid executables. But, if you want, you can use /bin/busybox to do last-minute backups (that don't require running commands as root) before rebooting. It's possible to fix this without a live USB/CD/DVD, but you will still need to reboot, and I suggest using one.


LD_PRELOAD doesn't work with setuid commands.

Currently you are attempting to make sudo use the renamed shared library by setting LD_PRELOAD. This will not work. You cannot change what shared libraries sudo links to with LD_PRELOAD, and it doesn't work with any of the alternatives to sudo either. If you could do this, then it would be an extremely severe security bug.

The way sudo and pkexec (and su) work to allow you to elevate privileges is that those executables have the setuid bit set0, which causes them to run as the user who owns them, which for those executables is the root user, rather than the user that actually runs them. When they run, they very carefully validate what you are asking them to do. In this way, provided their developers were careful enough, they will only allow users to perform actions they are authorized to perform.

LD_PRELOAD has no effect for setuid executables run by users other than their owners. This is absolutely vital for security. Otherwise, anybody could make their own library and force a program like sudo to use it, and then anybody could gain root privileges. You can use LD_PRELOAD to run non-setuid programs, and root can use it to run just about anything. But as a non-root user, you cannot use it to run programs like sudo, pkexec, and su that are setuid root.

If you already had a root shell running then you wouldn't need to reboot. But even if you have the root account enabled--that is, even if you had a password set for it that you could use to log in as root with a command like su--you would still not be able to fix the problem without rebooting. For example su in Ubuntu also requires libc.so.6 and is also setuid root so LD_PRELOAD won't work with it either.1 (See also Peter Cordes's comments.)

The issue here is that the available mechanisms for performing actions as root require that you run setuid executables owned by root as yourself, but LD_PRELOAD has no effect in that situation. If it weren't for the need to perform actions as root--or if you already had a root shell open--then you would be able to rename it back easily without rebooting and also without using LD_PRELOAD. This is because Ubuntu systems have /bin/busybox, which is statically linked. It lets you run many of the common *nix tools, including the mv and cp commands. You can run /bin/busybox mv source destination or you can run just /bin/busybox sh to get a shell in which you can then run the commands. Run /bin/busybox with no arguments to get a list of supported commands. It even has a version of dpkg!

You can back up files (if you want) and reboot to a live environment.

I mention busybox chiefly because, although you will not be able to use it to gain root privileges and restore libc.so.6, you can use it to back up any files you're concerned about losing before you reboot into a live environment. I very much doubt you would lose anything, but since you're concerned, you may want to use busybox to copy any important files--like documents you've created or modified since your last backup--to another location.

Rebooting in the usual way may not get very far, because normal shutdowns actually involve running dynamically linked programs that depend on libc.so.6. You may want to use Alt+SysRq+REISUB to reboot safely. This is not an ideal way to shut down, but it is probably better than a mostly ineffectual attempt to reboot followed by a hard reset. Another option would be to attempt to reboot and then attempt to use the REISUB method to take it the rest of the way. (If you want to power off the machine rather than rebooting it, use REISUO instead of REISUB.)

When you do boot from a live environment, renaming the file will be easy. You don't need to chroot or do anything fancy. Just mount your root filesystem (which you can usually do with one click in the file browser, though you can use the mount command if you like). Then, in a terminal, use the mv or cp command to restore libc.so.6. You'll need sudo, but that works fine in a live environment.

I know you mentioned you don't have a rescue disk. It would be difficult, perhaps impossible, to create a bootable live USB on that system, where you cannot run most programs. (You can use busybox to copy and move files, and it even has a dd comand, but I wouldn't recommend trying to use it for that. Usually you would need to be able to run dd as root to create live media.) Perhaps someone will suggest a way. If you have another machine to put the hard disk in, hopefully you can create it with that machine. If not, your best bet may be to ask an acquaintance to make one.

There's a way without a live CD/DVD/USB, but you still must reboot.

However, there is an alternative to booting from external media.2 You will still have to reboot, but you don't need a live system. I don't especially recommend this, as it is cumbersome; using a live environment is easier. You can do it without one if you really want to, though.

As Zanna had previously pointed out in comments, rescue mode would not work because most programs need libc.6.so (for example, /bin/bash, which provides the shell, needs it). But you can boot the system with /bin/busybox sh as init by passing init=/bin/busybox sh as a boot option to the kernel in GRUB.3 This is essentially the same technique as the more common init=/bin/sh (or init=/bin/bash) to get a root shell, but with /bin/busybox sh instead of the regular /bin/sh, because /bin/sh is dynamically linked and requires libc.so.6.

If you want to do it this way, hold down the left Shift key while (re)booting so the GRUB boot menu appears. (If Shift doesn't work, use Esc.) With the arrow keys, select Advanced options for Ubuntu and press Enter. After this point you won't press Enter because that would boot normally rather than with custom boot options. Select any kernel and press e to edit its boot options temporarily. If there are multiple lines and your cursor is not on the line that starts with linux, move it there with the arrow keys. Add init=/bin/busybox sh to the end of that line and press F10 to boot it.

You should get a BusyBox shell prompt. You'll have to remount the root filesystem readwrite and rename libc.so.6 so it has the correct name that it used to have. To achieve this, run these commands in the BusyBox shell (where other readers who have libc.so.6 in a different location would have to adjust the directory name passed to the cd command):

mount -o remount,rw /
cd /lib64
mv libc.so.6.bak libc.so.6

Then I recommend you then sync any cached writes to the filesystem, remount it readonly, and reboot:

sync
mount -o remount,ro /
reboot -f

(Without -f, the reboot command does not work at all in this situation, as no proper init daemon is running.)


0 For those who are interested: when those programs (like sudo) actually run your command or create a shell as root or some other alternate user, both your real and effective user IDs are set to that of the target user. But when you run them, before they have done this, while they are determining if they should allow you to perform the action you have asked for, their effective user ID is that of root while their real user ID is still yours. I mention this to address a common misconception about the way real and effective user IDs work in programs like sudo; if you've never heard of real and effective user IDs, feel free to ignore this footnote.

1 As mentioned, busybox in Ubuntu is statically linked and does not rely on libc.so.6. You might think you could use this to avoid rebooting, because busybox offers a su command. However, this does not help any, because as it is installed, busybox is not setuid root. To actually work to allow a non-root user to become root, su must be setuid root. The useful function of busybox su is to allow root to impersonate other users, rather than to allow other users to impersonate root.

2 Zanna contributed greatly to this procedure and also did all the testing for it!

3 This succeeds at passing sh to busybox even though you might expect it to be interpreted as a subsequent kernel boot option. Including quotation marks prevents it from working. Note also that, in Ubuntu, the statically linked busybox executable is just called busybox, not busybox-static (though the package that provides it is called busybox-static). If you've uninstalled the statically linked BusyBox and installed the dynamically linked BusyBox, then this method won't work, but it's very unlikely that you have done that.

13
  • Thank you for the reply. It's just I know the root password so there should be a way to let me open a root shell but it seems I can't. I did exactly what you have answered to fix it via DVD.
    – Hao
    Apr 28, 2018 at 19:15
  • 3
    @Hao su also is setuid root, like sudo and pkexec, and subject to the same LD_PRELOAD limitations as they are. But it occurs to me that, without a CD/DVD/USB, while the best approach is probably still to get one, you could likely solve it by booting with init=/bin/busybox sh as a kernel option in GRUB. That does still require rebooting of course. I'll try to add something about that. If I've misunderstood what you've said and you haven't fixed it yet and want the info about booting to busybox sh now, please let me know, and I can try to add something about it before I go afk. Apr 28, 2018 at 19:23
  • 1
    @Hao: you can't use the root password because (by renaming libc) you broke all the "normal" ways that you can use it, including logging in on a getty on another text console. If you had a statically linked su or sudo, you could use LD_PRELOAD=whatever LD_LIBRARY_PATH=whatever static-su --preserve-environment to pass on this custom environment to a bash running as root. But if you don't, then you should just use your physical access to the machine to boot in recovery mode (in the normal GRUB menu), or from a DVD or USB stick. Apr 28, 2018 at 21:00
  • 2
    @PeterCordes Yes, / starts readonly, but busybox has mount and remounting rw works. It can be written, synced (busybox has sync), remounted ro if one wants, and though busybox's reboot builtin with no options doesn't work here as there's no proper init, reboot -f should. This is one of the reasons I'm taking so long to do my edit, btw. I'm talking to Zanna, who's testing this; I don't have a way to conveniently test at the moment but I'd like to get my answer expanded because otherwise I may not get to it for a while. The testing is mostly, but not totally, completed as of yet. Apr 28, 2018 at 22:25
  • 1
    Posted an answer. I didn't try to test this thoroughly; your answer should be the go-to for people that need a recipe. I only intended mine as a survey of some other things that are possible and interesting to be aware of. May 1, 2018 at 8:53
4

I know the root password so there should be a way to let me open a root shell but it seems I can't.

You can't use the root password because (by renaming libc) you broke all the "normal" ways that you can use it, including logging in on a getty on another text console. If you had a statically linked su or sudo, you could use that to run busybox mv, or (in the general case of getting a working root shell), use

LD_PRELOAD=whatever LD_LIBRARY_PATH=whatever static-su --preserve-environment to pass on this custom environment to a bash running as root

Setuid binaries themselves can't trust the environment supplied by a user running them, but (if they work) can pass on the environment if you requested that, and you know the right password to authenticate that operation.

But since you don't have a static setuid binary that can authenticate your request to pass a custom environment to a process running as root, you should just use your physical access to reboot into an environment that lets you modify the root FS. e.g. a DVD or USB stick, or boot your regular system with init=/bin/busybox sh (see @Eliah's answer).

If you don't have recovery media sitting around, create something bootable on another computer, using either an Ubuntu live image or one of several recovery-boot images that are suitable for repairing various OSes and running hardware diagnostics (here's a review of 5 different ones). (These are often smaller than a live Ubuntu, e.g. taking up only about 700MB on a USB stick.)

You can set up a USB stick to be bootable with one of these (or Ubuntu) while still being able to use it for normal file storage; you don't need to dedicate a whole USB stick to a bootable image. (The simplest ways of creating a live USB stick will blow away the previous contents and sometimes even not leave it usable for storing files, though.)


Another option is to get the initramfs to drop into a shell before doing pivot_root and execing the init= you passed on the kernel command line. This doesn't depend on any contents of the root FS itself. You might not have an editor at all, but you do have cat and redirection, as well as mv and ln. (cat > /mnt/root/etc/something). If the problem you need to fix is non-trivial, you should probably boot something more powerful!

This happens automatically in some boot-failure cases, e.g. if RAID detection fails or something so the root fs doesn't mount in the first place (even read only). (Ubuntu 15.10 - "BusyBox built-in shell (initramfs)" on every boot)

You can make it happen with break=bottom on the kernel command line to drop into the busybox shell in the initramfs, after doing most stuff (loading modules and mounting the root FS read only), but before execing the real init. break=premount stops earlier; see that link or /usr/share/initramfs-tools/init for more details.

0

I solved this issue on elementary OS, by making a bootable drive containing the elementary OS version I had and then booting into it live.

After booting the liveusb I copied the folder /lib to my faulty elementary OS /lib folder and merged by keeping the recent files.

That worked for me. Hope it does for you too.

1
  • Well, in this situation just renaming the file would be sufficient, but this is a good idea for solving more substantial problems.
    – Zanna
    Aug 11, 2020 at 10:12
0

I renamed "libc.so.6" to "libc.so.6_old" and faced the same issue so in that way we have few options. We can resolve this issue in 3 ways, (I'm on the cluster so I have a shared path i.e. home directory for all the users and other nodes as well)

(First 2 options worked only if you were already on root user, and did not signout or logoff)

  1. When it's changed we are already on the root user, and start facing the following error:

ls: error while loading shared libraries: libc.so.6: cannot open shared object file: No such file or directory

Then do not logoff from root user otherwise you can't switch the user, and then only 3rd option will be available. First, unset all the default set path

#unset LIBRARY_PATH

#unset LD_LIBRARY_PATH

#unset PATH

Then set only the following paths, and run the last command that will again create the softlink for libc.so.6.

#export PATH=/usr/bin:/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin

#export LIBRARY_PATH=/usr/lib

#export LD_LIBRARY_PATH=/usr/lib

#ldconfig

  1. Now in second option also you should be on root if not then it wont work. if you are on root and anyway "ldconfig" will not then try the following,

#unset LIBRARY_PATH

#unset LD_LIBRARY_PATH

#unset PATH

Then set only the following paths, copy all "lib64" in the temp directory, and change the same

#export PATH=/usr/bin:/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin

#export LIBRARY_PATH=/usr/lib

#export LD_LIBRARY_PATH=/usr/lib

#cp -prv /usr/lib64 /tmp/.

#mv /tmp/lib64/libc.so.6_old /tmp/lib64/libc.so.6 ---OR--- #ln -s /tmp/lib64/libc-2.XX.so /tmp/lib64/libc.so.6

#export LIBRARY_PATH=$LIBRARY_PATH:/tmp/lib64

#export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/tmp/lib64

#mv /usr/lib64/libc.so.6_old /user/lib64/libc.so.6 ---OR--- #ln -s /usr/lib64/libc-2.XX.so /usr/lib64/libc.so.6

  1. Now if none of the above options worked or are available or you already lost the connection then follow the below steps,
  • Power down the machine forcefully.
  • Create a live OS DISK/DRIVE/PEN-DRIVE with any live OS, i.e. Suse, Mint, Puppy, Kali
  • Boot from the live OS, and open the local disk. Which now shows as media or other storage devices.
  • Copy --OR-- rename the "libc.so.6" as mentioned in the second option final stage and reboot the machine (remove the live OS source/media and boot in normal mode).

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .