The LP daemon is susceptible to Denial of Service attacks.
29 Dec. 1998
Summary
The LP daemon (version 0.33-1 and older version 0.31-1, which is distributed by distributions such as RedHat), is a daemon which maintains and monitors printer queues to allow remote printing to UNIX based users.
The daemon is susceptible to a Denial of Service attack that renders it inoperable.
When the LP daemon receives a printing request it forks a filtering process with the printing user's name on the local machine (The machine where lpd is installed). If a user does not exist in the printer server's account list, the forked process will get stuck, causing all other print jobs to get tied up and new request to be rejected.
This Denial of Service can be avoided by installing the following patch:
81a82
> static char euser[32]; /* effective user */
368a370,383
> } else { /* not restricted */
> struct passwd *dude;
> dude = getpwnam(logname);
> if (dude == NULL || dude->pw_uid == 0) {
> /* if user doesn't exist will cause a DoS so set */
> /* effective user to lp, also we don't want to be */
> /* root either to prevent race condition and buffer */
> /* overrun and the like in poorly designed filters */
> /* don't change logname so mail & banner are right */
> strncpy(euser, "lp", 3);
> } else {
> /* since the user does exist run filter as user */
> strncpy(euser, logname, sizeof(logname));
> }
526c541
< if (getpwnam(logname) == (struct passwd *)0 || !*logname)
---
> if (getpwnam(euser) == (struct passwd *)0 || !*euser)
553c568
< if ((prchild=doforkuser(DORETURN,logname)) == 0) { /* child */
---
> if ((prchild=doforkuser(DORETURN,euser)) == 0) { /* child */
671c686
< if ((child = doforkuser(DORETURN,logname)) == 0) { /* child */
---
> if ((child = doforkuser(DORETURN,euser)) == 0) { /* child */
810a826
> logname[sizeof(logname) - 1] = '\0';
815a832,845
> } else { /* not restricted */
> struct passwd *dude;
> dude = getpwnam(logname);
> if (dude == NULL || dude->pw_uid == 0) {
> /* if user doesn't exist will cause a DoS so set */
> /* effective user to lp, also we don't want to be */
> /* root either to prevent race condition and buffer */
> /* overrun and the like in poorly designed filters */
> /* don't change logname so mail & banner are right */
> strncpy(euser, "lp", 3);
> } else {
> /* since the user does exist run filter as user */
> strncpy(euser, logname, sizeof(logname));
> }
851c881
< if ((ifchild = doforkuser(DORETURN,logname)) == 0) { /*child*/
---
> if ((ifchild = doforkuser(DORETURN,euser)) == 0) { /*child*/