 
 
 
 
 
pam_appl-5.htmlNext pam_appl-3.htmlPrevious pam_appl.html#toc4Contents 4. Security issues of Linux-PAM 
PAM, from the perspective of an application, is a convenient API for
authenticating users. PAM modules generally have no increased
privilege over that possessed by the application that is making use of
it. For this reason, the application must take ultimate responsibility
for protecting the environment in which PAM operates.
A poorly (or maliciously) written application can defeat any
Linux-PAM module's authentication mechanisms by simply ignoring
it's return values.  It is the applications task and responsibility to
grant privileges and access to services.  The 
Linux-PAM library
simply assumes the responsibility of 
authenticating the user;
ascertaining that the user 
is who they say they are.  Care should
be taken to anticipate all of the documented behavior of the
Linux-PAM library functions.  A failure to do this will most
certainly lead to a future security breach.
4.1 Care about standard library calls 
In general, writers of authorization-granting applications should
assume that each module is likely to call any or 
all `libc'
functions.  For `libc' functions that return pointers to
static/dynamically allocated structures (ie. the library allocates the
memory and the user is not expected to `
free()' it) any module
call to this function is likely to corrupt a pointer previously
obtained by the application.  The application programmer should either
re-call such a `libc' function after a call to the 
Linux-PAMlibrary, or copy the structure contents to some safe area of memory
before passing control to the 
Linux-PAM library.
Two important function classes that fall into this category are
getpwnam(3) and syslog(3).
4.2 Choice of a service name 
When picking the service-name that corresponds to the first entry
in the 
Linux-PAM configuration file, the application programmer
should 
avoid the temptation of choosing something related to
argv[0].  It is a trivial matter for any user to invoke any
application on a system under a different name and this should not be
permitted to cause a security breach.
In general, this is always the right advice if the program is setuid,
or otherwise more privileged than the user that invokes it. In some
cases, avoiding this advice is convenient, but as an author of such an
application, you should consider well the ways in which your program
will be installed and used. (Its often the case that programs are not
intended to be setuid, but end up being installed that way for
convenience. If your program falls into this category, don't fall into
the trap of making this mistake.)
To invoke some target application by another name, the user may
symbolically link the target application with the desired name.  To be
precise all the user need do is,
ln -s /target/application ./preferred_name
and then 
run ./preferred_nameBy studying the Linux-PAM configuration file(s), an attacker can
choose the 
preferred_name to be that of a service enjoying
minimal protection; for example a game which uses 
Linux-PAM to
restrict access to certain hours of the day.  If the service-name were
to be linked to the filename under which the service was invoked, it
is clear that the user is effectively in the position of dictating
which authentication scheme the service uses.  Needless to say, this
is not a secure situation.
The conclusion is that the application developer should carefully
define the service-name of an application. The safest thing is to make
it a single hard-wired name.
4.3 The conversation function 
Care should be taken to ensure that the conv() function is
robust. Such a function is provided in the library 
libpam_misc(see 
pam_appl-5.html#libpam-misc-sectionbelow ).
4.4 The identity of the user 
The Linux-PAM modules will need to determine the identity of the
user who requests a service, and the identity of the user who grants
the service.  These two users will seldom be the same.  Indeed there
is generally a third user identity to be considered, the new (assumed)
identity of the user once the service is granted.
The need for keeping tabs on these identities is clearly an issue of
security.  One convention that is actively used by some modules is
that the identity of the user requesting a service should be the
current 
uid (userid) of the running process; the identity of the
privilege granting user is the 
euid (effective userid) of the
running process; the identity of the user, under whose name the
service will be executed, is given by the contents of the
PAM_USER pam_get_item(3). Note, modules can change the
values of 
PAM_USER and PAM_RUSER during any of the
pam_*() library calls. For this reason, the application should
take care to use the 
pam_get_item() every time it wishes to
establish who the authenticated user is (or will currently be).
For network-serving databases and other applications that provide
their own security model (independent of the OS kernel) the above
scheme is insufficient to identify the requesting user.
A more portable solution to storing the identity of the requesting
user is to use the 
PAM_RUSER pam_get_item(3). The
application should supply this value before attempting to authenticate
the user with 
pam_authenticate(). How well this name can be
trusted will ultimately be at the discretion of the local
administrator (who configures PAM for your application) and a selected
module may attempt to override the value where it can obtain more
reliable data. If an application is unable to determine the identity
of the requesting entity/user, it should not call 
pam_set_item(3)to set 
PAM_RUSER.
In addition to the PAM_RUSER item, the application should supply
the 
PAM_RHOST (requesting host) item. As a general rule, the
following convention for its value can be assumed: 
<unset>= unknown; 
localhost = invoked directly from the local system;
other.place.xyz = some component of the user's connection
originates from this remote/requesting host. At present, PAM has no
established convention for indicating whether the application supports
a trusted path to communication from this host.
4.5 Sufficient resources 
Care should be taken to ensure that the proper execution of an
application is not compromised by a lack of system resources.  If an
application is unable to open sufficient files to perform its service,
it should fail gracefully, or request additional resources.
Specifically, the quantities manipulated by the 
setrlimit(2)family of commands should be taken into consideration.
This is also true of conversation prompts. The application should not
accept prompts of arbitrary length with out checking for resource
allocation failure and dealing with such extreme conditions gracefully
and in a mannor that preserves the PAM API. Such tolerance may be
especially important when attempting to track a malicious adversary.
pam_appl-5.htmlNext pam_appl-3.htmlPrevious pam_appl.html#toc4Contents 