e9ec1693c7
X session finishes, slim goes to restart X, but if the machine is being halted, slim gets a SIGTERM, and the signal handler tries to kill the X server without checking if is has been restarted yet. Boom. While here, fix xauth path.
184 lines
5.1 KiB
Plaintext
184 lines
5.1 KiB
Plaintext
$OpenBSD: patch-app_cpp,v 1.2 2009/11/05 19:05:12 landry Exp $
|
|
Slim used to spawn 'xauth add . <COOKIE>' via the system() call, so the
|
|
cookie itself was visible. On multi-user system one can poll for the
|
|
xauth processes via ps and gather cookies for X sessions.
|
|
fixes CVE-2009-1756
|
|
--- app.cpp.orig Fri Sep 26 02:54:15 2008
|
|
+++ app.cpp Wed Oct 28 19:31:08 2009
|
|
@@ -32,6 +32,62 @@
|
|
|
|
using namespace std;
|
|
|
|
+/* Code taken from http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=529306 */
|
|
+/* From: Eygene Ryabinkin <rea@shadow.codelabs.ru> */
|
|
+#include <time.h>
|
|
+#include <stdlib.h>
|
|
+
|
|
+/*
|
|
+ * Adds the given cookie to the specified Xauthority file.
|
|
+ * Returns true on success, false on fault.
|
|
+ */
|
|
+bool Util::add_mcookie(const std::string &mcookie, const char *display,
|
|
+ const std::string &xauth_cmd, const std::string &authfile)
|
|
+{
|
|
+ FILE *fp;
|
|
+ std::string cmd = xauth_cmd + " -f " + authfile + " -q";
|
|
+
|
|
+ fp = popen(cmd.c_str(), "w");
|
|
+ if (!fp)
|
|
+ return false;
|
|
+ fprintf(fp, "remove %s\n", display);
|
|
+ fprintf(fp, "add %s %s %s\n", display, ".", mcookie.c_str());
|
|
+ fprintf(fp, "exit\n");
|
|
+
|
|
+ pclose(fp);
|
|
+ return true;
|
|
+}
|
|
+/*
|
|
+ * Interface for random number generator. Just now it uses ordinary
|
|
+ * random/srandom routines and serves as a wrapper for them.
|
|
+ */
|
|
+void Util::srandom(unsigned long seed)
|
|
+{
|
|
+ ::srandom(seed);
|
|
+}
|
|
+
|
|
+long Util::random(void)
|
|
+{
|
|
+ return ::random();
|
|
+}
|
|
+
|
|
+/*
|
|
+ * Makes seed for the srandom() using "random" values obtained from
|
|
+ * getpid(), time(NULL) and others.
|
|
+ */
|
|
+long Util::makeseed(void)
|
|
+{
|
|
+ struct timespec ts;
|
|
+ long pid = getpid();
|
|
+ long tm = time(NULL);
|
|
+
|
|
+ if (clock_gettime(CLOCK_MONOTONIC, &ts) != 0) {
|
|
+ ts.tv_sec = ts.tv_nsec = 0;
|
|
+ }
|
|
+
|
|
+ return pid + tm + (ts.tv_sec ^ ts.tv_nsec);
|
|
+}
|
|
+
|
|
#ifdef USE_PAM
|
|
#include <string>
|
|
|
|
@@ -104,7 +160,8 @@ extern App* LoginApp;
|
|
|
|
void CatchSignal(int sig) {
|
|
cerr << APPNAME << ": unexpected signal " << sig << endl;
|
|
- LoginApp->StopServer();
|
|
+ if (LoginApp->serverStarted)
|
|
+ LoginApp->StopServer();
|
|
LoginApp->RemoveLock();
|
|
exit(ERR_EXIT);
|
|
}
|
|
@@ -131,12 +188,13 @@ void User1Signal(int sig) {
|
|
App::App(int argc, char** argv):
|
|
pam(conv, static_cast<void*>(&LoginPanel)){
|
|
#else
|
|
-App::App(int argc, char** argv){
|
|
+App::App(int argc, char** argv) : mcookiesize(32) {
|
|
#endif
|
|
int tmp;
|
|
ServerPID = -1;
|
|
+ serverStarted = false;
|
|
testing = false;
|
|
- mcookie = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
|
|
+ mcookie = string(App::mcookiesize, 'a');
|
|
daemonmode = false;
|
|
force_nodaemon = false;
|
|
firstlogin = true;
|
|
@@ -856,6 +914,8 @@ int App::StartServer() {
|
|
char* args = new char[argOption.length()+2]; // NULL plus vt
|
|
strcpy(args, argOption.c_str());
|
|
|
|
+ serverStarted = false;
|
|
+
|
|
int argc = 1;
|
|
int pos = 0;
|
|
bool hasVtSet = false;
|
|
@@ -935,7 +995,7 @@ int App::StartServer() {
|
|
}
|
|
|
|
delete args;
|
|
-
|
|
+ serverStarted = true;
|
|
return ServerPID;
|
|
}
|
|
|
|
@@ -1127,13 +1187,13 @@ string App::findValidRandomTheme(const string& set)
|
|
name = name.substr(0, name.length() - 1);
|
|
}
|
|
|
|
- srandom(getpid()+time(NULL));
|
|
+ Util::srandom(Util::makeseed());
|
|
|
|
vector<string> themes;
|
|
string themefile;
|
|
Cfg::split(themes, name, ',');
|
|
do {
|
|
- int sel = random() % themes.size();
|
|
+ int sel = Util::random() % themes.size();
|
|
|
|
name = Cfg::Trim(themes[sel]);
|
|
themefile = string(THEMESDIR) +"/" + name + THEMESFILE;
|
|
@@ -1159,34 +1219,32 @@ void App::replaceVariables(string& input,
|
|
}
|
|
}
|
|
|
|
-
|
|
+/*
|
|
+ * We rely on the fact that all bits generated by Util::random()
|
|
+ * are usable, so we are taking full words from its output.
|
|
+ */
|
|
void App::CreateServerAuth() {
|
|
/* create mit cookie */
|
|
- int i, r;
|
|
- int hexcount = 0;
|
|
- string authfile;
|
|
- string cmd;
|
|
+ uint16_t word;
|
|
+ uint8_t hi, lo;
|
|
+ int i;
|
|
+ string authfile;
|
|
const char *digits = "0123456789abcdef";
|
|
- srand( time(NULL) );
|
|
- for ( i = 0; i < 31; i++ ) {
|
|
- r = rand()%16;
|
|
- mcookie[i] = digits[r];
|
|
- if (r>9)
|
|
- hexcount++;
|
|
+ Util::srandom(Util::makeseed());
|
|
+ for (i = 0; i < App::mcookiesize; i+=4) {
|
|
+ word = Util::random() & 0xffff;
|
|
+ lo = word & 0xff;
|
|
+ hi = word >> 8;
|
|
+ mcookie[i] = digits[lo & 0x0f];
|
|
+ mcookie[i+1] = digits[lo >> 4];
|
|
+ mcookie[i+2] = digits[hi & 0x0f];
|
|
+ mcookie[i+3] = digits[hi >> 4];
|
|
}
|
|
- /* MIT-COOKIE: even occurrences of digits and hex digits */
|
|
- if ((hexcount%2) == 0) {
|
|
- r = rand()%10;
|
|
- } else {
|
|
- r = rand()%5+10;
|
|
- }
|
|
- mcookie[31] = digits[r];
|
|
/* reinitialize auth file */
|
|
authfile = cfg->getOption("authfile");
|
|
remove(authfile.c_str());
|
|
putenv(StrConcat("XAUTHORITY=", authfile.c_str()));
|
|
- cmd = cfg->getOption("xauth_path") + " -q -f " + authfile + " add :0 . " + mcookie;
|
|
- system(cmd.c_str());
|
|
+ Util::add_mcookie(mcookie, ":0", cfg->getOption("xauth_path"), authfile);
|
|
}
|
|
|
|
char* App::StrConcat(const char* str1, const char* str2) {
|