boltblog

Using LD_PRELOAD to override a function

Posted on July 15, 2011

This was blatantly stolen from technovelty, kept here because I hate it when my bookmarks die.

For some reason, people seem to get this quite wrong a lot of the time. Certainly one should not be playing with symbols that start with __ unless you really know what you're doing with them.

ianw@lime:~/tmp/override$ cat override.c
#define _GNU_SOURCE 1
#include
#include
#include
#include
#include

pid_t getpid(void)
{
pid_t (*orig_getpid)(void) = dlsym(RTLD_NEXT, "getpid");
printf("Calling GETPID\n");

return orig_getpid();
}

ianw@lime:~/tmp/override$ cat test.c
#include
#include
#include

int main(void)
{
printf("%d\n", getpid());
}

ianw@lime:~/tmp/override$ gcc -shared -fPIC -o liboverride.so override.c -ldl
ianw@lime:~/tmp/override$ gcc -o test test.c
ianw@lime:~/tmp/override$ LD_PRELOAD=./liboverride.so ./test
Calling GETPID
15187

Filed under: Linux, Reference No Comments

How difficult is it to misuse the code you write?

Posted on July 15, 2011

I found these "misuse levels" over at technovelty, which they originally ripped from Rusty Russel's Bleeding Edge Page, which is a page you should definitely check out if you haven't.

Anyway, I found these "misuse levels" both hilarious to read and at the same time somewhat concerning, as I started thinking "Where does my code really go on this list?"

  1. Impossible to get wrong
  2. Compiler/linker won't let you get it wrong
  3. Compiler/linker warns if you get it wrong
  4. Simplest use is correct
  5. The name tells you how to use it
  6. Do it right or breaks at runtime
  7. Follow the convention and you will get it right
  8. Read the documentation and you will get it right
  9. Read the implementation and you will get it right
  10. Read the correct mailing list and you will get it right
  11. Read the documentation and you will get it wrong
  12. Follow the convention and you will get it wrong
  13. Do it right and it will break at runtime
  14. The name tells you how not to use it
  15. The obvious use is wrong
  16. Compiler/linker will warn you if you get it right
  17. Compiler/linker won't let you get it right
  18. Impossible to get right
Filed under: Rants No Comments

Debian and Ubuntu auto-login and Xorg without a display manager

Posted on July 15, 2011

If you have a harddrive password (most laptops do this) or full disk encryption, you might not feel the need for an additional login after your system boots.

On most Debian-based systems, TTY's 1 through 6 are available after boot, while TTY 7 is used for Xorg. Therefore, I like to put my auto-login TTY on TTY 8, so it's out of the way and leaves TTY 1 available for troubleshooting and similar.

Auto-login to Xorg requires two things: The actual auto-login and a script which loads Xorg.

First things first. The autologin.
In the olden days on a Debian system, this was done by adding a line similar to this one in /etc/inittab:
8:23:respawn:/bin/login -f bolt tty8 /dev/tty8 2>&1
This spawns a TTY 8 and logs in as "bolt" (change to suit your needs). It will do so on runlevels 2 and 3.

Now, however, the tool "rungetty" is generally used for this, as it's more flexible and performs the same functions with a cleaner syntax. First, "apt-get install rungetty" to make sure it's there, then add a line similar to the following:
8:3:respawn:/sbin/rungetty tty8 --autologin bolt
Note that on Debian Lenny and older, the version of rungetty has a specific check in code which only allows --autologin to work on tty1. If asked to autologin on another tty, rungetty would silently fail and spawn a normal login tty. This restriction has been removed from Squeeze and onwards.

On Ubuntu 10.10, the tty configuration is not in /etc/inittab. There, you have to add a file called "/etc/init.d/tty8.conf" with the following contents:
# tty8 - getty
#
# This service maintains a getty on tty8 from the point the system is
# started until it is shut down again.

start on runlevel [23]
stop on runlevel [!23]

respawn
exec /sbin/rungetty tty8 --autologin bolt

I basically copied tty6.conf and modified it to make that.

Autostarting Xorg
So by default when you login, both Debian and Ubuntu will leave you with a bash prompt, and very little graphical goodness. Thus, you want your login script to start Xorg, but only if Xorg is not already running, and we're on tty8. Otherwise, switching from Xorg to a console with, for example, ctrl+alt+f1, would cause another attempt to launch Xorg.

Thus I made this script, named ".bash_login", and put it in my home directory.
# ~/.bash_login: executed by bash(1) for login shells.

# include .profile if it exists
if [ -f "${HOME}/.profile" ] && [ -r "${HOME}/.profile" ]; then
source "${HOME}/.profile"
fi

# if we're not root and we're logged in on tty8, we assume a rungetty autologin and start xorg
if [ ! -z "${UID:-}" ] && [ "$UID" != "0" ] && [ -z "${DISPLAY}" ] && [ ! -z "${SHLVL:-}" ] && [ "$SHLVL" == "1" ]; then
if [ "$(tty)" == "/dev/tty8" ]; then
trap "chvt 1; logout" INT TERM EXIT
chvt 8
while true; do
echo "starting xorg"
startx
echo "sleeping 2 seconds"
sleep 2
done
fi
fi

This script will do a few sanity checks, then run Xorg. If Xorg exits, it will sleep 2 seconds and run it again. If the script is told to stop, it will change to tty1, then logout of tty8.

Filed under: Howto's, Linux No Comments