--- polkit-0.104.orig/src/polkitagent/polkitagenthelper-pam.c 2011-10-18 19:02:27.000000000 +0200 +++ polkit-0.104/src/polkitagent/polkitagenthelper-pam.c 2013-01-07 13:08:30.337532301 +0100 @@ -69,9 +69,11 @@ struct pam_conv pam_conversation; pam_handle_t *pam_h; const void *authed_user; + uid_t saved_credentials[3]; rc = 0; pam_h = NULL; + getresuid(saved_credentials, saved_credentials+1, saved_credentials+2); /* clear the entire environment to avoid attacks using with libraries honoring environment variables */ if (_polkit_clearenv () != 0) @@ -123,7 +125,7 @@ #endif /* PAH_DEBUG */ pam_conversation.conv = conversation_function; - pam_conversation.appdata_ptr = NULL; + pam_conversation.appdata_ptr = saved_credentials; /* start the pam stack */ rc = pam_start ("polkit-1", @@ -144,6 +146,13 @@ goto error; } + /* Force real, effective and saved uids to be root (O) in order + * to prevent any permanent rights revocation by any PAM module + * during PAM verifications. + * This operation is allowed as we are setuid root. + */ + setuid(0); + /* is user really user? */ rc = pam_authenticate (pam_h, 0); if (rc != PAM_SUCCESS) @@ -164,6 +173,9 @@ goto error; } + /* restore saved credentials */ + setresuid(saved_credentials[0], saved_credentials[1], saved_credentials[2]); + /* did we auth the right user? */ rc = pam_get_item (pam_h, PAM_USER, &authed_user); if (rc != PAM_SUCCESS) @@ -215,6 +227,9 @@ if (pam_h != NULL) pam_end (pam_h, rc); + /* restore saved credentials */ + setresuid(saved_credentials[0], saved_credentials[1], saved_credentials[2]); + fprintf (stdout, "FAILURE\n"); flush_and_wait(); return 1; @@ -226,9 +241,9 @@ struct pam_response *aresp; char buf[PAM_MAX_RESP_SIZE]; int i; + uid_t* saved_credentials = (uid_t*)data; gchar *escaped = NULL; - data = data; if (n <= 0 || n > PAM_MAX_NUM_MSG) return PAM_CONV_ERR; @@ -272,8 +287,11 @@ #endif /* PAH_DEBUG */ fflush (stdout); + setresuid(saved_credentials[0], saved_credentials[1], saved_credentials[2]); if (fgets (buf, sizeof buf, stdin) == NULL) goto error; + else + setuid(0); if (strlen (buf) > 0 && buf[strlen (buf) - 1] == '\n') @@ -316,6 +334,7 @@ } } memset (aresp, 0, n * sizeof *aresp); + free(aresp); *resp = NULL; return PAM_CONV_ERR; }