9

When in doubt, twiddle bytes in libc.so.5

 3 years ago
source link: http://rachelbythebay.com/w/2012/03/14/logs/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

When in doubt, twiddle bytes in libc.so.5

Back in the fall of 2000, there was a nasty little security advisory in the klogd/syslogd pair which ran on every one of my machines. It seemed that data supplied by a user could work its way directly into the second argument of a *printf call and thus take over its format string. From there, any number of bad things could happen.

Within a day or two, there was a patched Slackware package:

----------------------------
Mon Sep 18 11:13:56 PDT 2000
a1/sysklogd.tgz:  Upgraded to sysklogd-1.4.  This fixes the
   "klogd format bug" announced this morning on BugTraq.
   (* Security fix *)
----------------------------

This patch was great, but it opened up a new problem for me. Slackware itself had recently switched to being based around glibc 2.1, and I still had a number of systems which were entirely or partially based on the older libc5 versions. I was able to install the glibc packages and then upgraded sysklogd, but then other things broke on me.

Somewhere along the way, /dev/log had changed from a SOCK_STREAM style to SOCK_DGRAM. This was probably done to avoid a denial of service attack. That was also a good thing, but it meant that all of my older programs which were still linked against libc5 had a syslog() call which no longer functioned. This was unacceptable.

I figured it would be possible to write something which would create a stream listening socket and would then translate things to datagrams and sling them at syslogd. It didn't take too much work, and now I had something which would do the conversion. It was the usual thing: set up a listener, run select(), keep track of client connections and disconnections, read() on activity, and write it to upstream.

Still, there was a big problem: the old programs still opened /dev/log, and the new programs did it too! I couldn't have it both ways on the same socket. Ultimately, I wound up doing something really evil to fix this problem. I opened up libc.so.5 and changed /dev/log to /dev/LOG with a quick call to sed. Then I made my program listen on /dev/LOG and write to /dev/log, and restarted everything which needed to use this interface.

It worked. Granted, it just moved the denial-of-service possibility to my converter, but that was an acceptable situation during the transition. Later, once everything had been upgraded and/or recompiled around glibc, I shut it down and removed the lingering cruft.

This was just one of a bunch of crazy things I had to write over the years to keep my fleet of mismatched machines running properly.


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK