COMMAND
Adobe Acrobat
SYSTEMS AFFECTED
Adobe Acrobat
PROBLEM
Even with umask as restrictive as 077, the Adobe binary explicitly
creates and changes the AdobeFnt.lst file in the HOME directory
to be world (and group) writable.
Darren Moffat notified Adobe of this on October 27th 1999 and
never got any reply, see attached. When starting the Acrobat
Reader 4.0 for the first time a new file called AdobeFnt.lst is
created in the users home directory. This file is created with
world writeable permissions (666).
Given that this file contains font mappings, this is a security
hole as it would allow someone else to replace your font
definitions thus making the documents appear different to what
the author intended.
Dumping non "." files in a users home directory is considered
very bad form in UNIX.
The AdobeFnt.lst file is actually comes from libCoolType.so.1 so
there is potential that other Adobe software that uses
libCoolType.so.1 would also be vulnerable to this bug. It appears
that the permissions are only set insecurely if the file didn't
already exist, so a very simple wrapper around AdobeFnt.lst that
created the file with good permissions first would probably
suffice.
SOLUTION
How about following workaround:
mkdir ~/.adobe
chmod 600 ~/.adobe
mv ~AdobeFnt.lst ~/.adobe/
ln -s ~/.adobe/AdobeFnt.lst ~
As the chmod will follow the symlink, it will change the
permissions of the file, not the link. This means that the file
itself still ends up as mode 0666, but as the directory it's in
is mode 0600, then nobody will be able to access it other than
the owner. Adding the above (with some checking that it hasn't
already been done, etc) to a script which start Acrobat would
handle the problem for all users.
Using truss on Solaris Darren J. Moffat discovered that the
creation of the AdobeFnt.lst file in the users home directory is
the only time that fchmod(fd, 0666) was called so his previous
LD_PRELOAD fix that circumvents Adobe's poor security can be
simplfied to just this (compiled and tested):
#include <limits.h>
#include <sys/types.h>
#include <dlfcn.h>
#include <stdio.h>
#include <stdlib.h>
int fchmod(int fildes, mode_t mode)
{
static int (*fptr)(int fildes, mode_t mode) = 0;
if (fptr == 0) {
fptr = (int (*)(int, mode_t))dlsym(RTLD_NEXT, "fchmod");
if (fptr == NULL) {
(void) printf("dlopen: %s\n", dlerror());
return NULL;
}
}
mode = 0600;
return ((fptr)(fildes, mode));
}