Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

Code Block
bgColor#ffcccc
/*  Code intended to run with elevated privileges   */

/* Temporarily drop privileges */
if (seteuid(getuid()) != 0) {
  /* Handle error */
}

/*  Code intended to run with lower privileges  */

if (need_more_privileges) {
  /* Restore privileges */
  if (seteuid(0) != 0) {
    /* Handle Error */
  }

  /*  Code intended to run with elevated privileges   */
}

/* ... */

/* Permanently drop privileges */
if (setuid(getuid()) != 0) {
  /* Handle Error */
}

/*  
 * Code intended to run with lower privileges,
 * but if privilege relinquishment failed,
 * attacker can regain elevated privileges! 
 */

...

Code Block
bgColor#ccccff
/*  Code intended to run with elevated privileges   */

/* Temporarily drop privileges */
if (seteuid(getuid()) != 0) {
  /* Handle error */
}

/*  Code intended to run with lower privileges  */

if (need_more_privileges) {
  /* Restore Privileges */
  if (seteuid(0) != 0) {
    /* Handle error */
  }

  /*  Code intended to run with elevated privileges   */
}

/* ... */

/* Permanently drop privileges */
if (setuid(getuid()) != 0) {
  /* Handle error */
}

if  (setuid(0) != -1) {
  /* Privileges can be restored, handle error */
}

/* 
 * Code intended to run with lower privileges;
 *   attacker cannot regain elevated privileges 
 */

Compliant Solution

A better solution is to ensure that proper privileges exist before attempting to carry out a permanent drop.

Code Block
bgColor#ccccff
/* Store the privileged ID for later verification */
uid_t privid = geteuid();

/*  Code intended to run with elevated privileges   */

/* Temporarily drop privileges */
if (seteuid(getuid()) != 0) {
  /* Handle error */
}

/*  Code intended to run with lower privileges  */

if (need_more_privileges) {
  /* Restore Privileges */
  if (seteuid(privid) != 0) {
    /* Handle error */
  }

  /*  Code intended to run with elevated privileges   */
}

/* ... */

/* Restore privileges if needed */
if (geteuid() != privid) {
  if (seteuid(privid) != 0) {
    /* Handle error */
  }
}

/* Permanently drop privileges */
if (setuid(getuid()) != 0) {
  /* Handle error */
}

if (setuid(0) != -1) {
  /* Privileges can be restored, handle error */
}

/*  
 * Code intended to run with lower privileges;
   * attacker cannot regain elevated privileges 
 */

Risk Assessment

If privilege relinquishment conditions are left unchecked, any flaw in the program may lead to unintended system compromise corresponding to the more privileged user or group account.

...