Module Name: xsrc Committed By: mrg Date: Wed Apr 6 04:40:54 UTC 2011
Modified Files: xsrc/xfree/xc/programs/xrdb: xrdb.c Log Message: my port of the fixes for CVE-2011-0465 back to xfree xrdb. To generate a diff of this commit: cvs rdiff -u -r1.1.1.6 -r1.2 xsrc/xfree/xc/programs/xrdb/xrdb.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: xsrc/xfree/xc/programs/xrdb/xrdb.c diff -u xsrc/xfree/xc/programs/xrdb/xrdb.c:1.1.1.6 xsrc/xfree/xc/programs/xrdb/xrdb.c:1.2 --- xsrc/xfree/xc/programs/xrdb/xrdb.c:1.1.1.6 Fri Mar 5 14:27:27 2004 +++ xsrc/xfree/xc/programs/xrdb/xrdb.c Wed Apr 6 04:40:54 2011 @@ -135,6 +135,8 @@ static void fatal(char *, ...); static void addstring ( String *arg, const char *s ); +static void addescapedstring ( String *arg, const char *s ); +static void addtokstring ( String *arg, const char *s ); static void FormatEntries ( Buffer *buffer, Entries *entries ); static void StoreProperty ( Display *dpy, Window root, Atom res_prop ); static void Process ( int scrno, Bool doScreen, Bool execute ); @@ -398,14 +400,20 @@ addstring(buff, " -D"); } else addstring(buff, "-D"); - addstring(buff, title); + addtokstring(buff, title); if (value && (value[0] != '\0')) { addstring(buff, "="); - addstring(buff, value); + addescapedstring(buff, value); } } static void +AddSimpleDef(String *buff, char *title) +{ + AddDef(buff, title, (char *)NULL); +} + +static void AddDefQ(String *buff, char *title, char *value) { #ifdef PATHETICCPP @@ -414,8 +422,9 @@ else #endif if (value && (value[0] != '\0')) { - AddDef(buff, title, "\""); - addstring(buff, value); + AddSimpleDef(buff, title); + addstring(buff, "=\""); + addescapedstring(buff, value); addstring(buff, "\""); } else AddDef(buff, title, NULL); @@ -430,25 +439,29 @@ } static void -AddSimpleDef(String *buff, char *title) +AddDefTok(String *buff, char *prefix, char *title) { - AddDef(buff, title, (char *)NULL); + char name[512]; + + snprintf(name, sizeof(name), "%s%s", prefix, title); + AddSimpleDef(buff, name); } static void -AddDefTok(String *buff, char *prefix, char *title) +AddDefHostname(String *buff, char *title, char *value) { char *s; char name[512]; char c; - strcpy(name, prefix); - strcat(name, title); + strncpy (name, value, sizeof(name)-1); + name[sizeof(name)-1] = '\0'; for (s = name; (c = *s); s++) { if (!isalpha(c) && !isdigit(c) && c != '_') + if (!isalpha(c) && !isdigit(c) && c != '_' && c != '.' && c != ':' && c != '-') *s = '_'; } - AddSimpleDef(buff, name); + AddDef(buff, title, name); } static void @@ -468,7 +481,7 @@ addstring(buff, " -U"); } else addstring(buff, "-U"); - addstring(buff, title); + addtokstring(buff, title); } static void @@ -528,11 +541,11 @@ } if (!*server || !strcmp(server, "unix") || !strcmp(server, "localhost")) strcpy(server, client); - AddDef(defs, "HOST", server); /* R3 compatibility */ - AddDef(defs, "SERVERHOST", server); + AddDefHostname(defs, "HOST", server); /* R3 compatibility */ + AddDefHostname(defs, "SERVERHOST", server); AddDefTok(defs, "SRVR_", server); AddNum(defs, "DISPLAY_NUM", n); - AddDef(defs, "CLIENTHOST", client); + AddDefHostname(defs, "CLIENTHOST", client); AddDefTok(defs, "CLNT_", client); AddNum(defs, "VERSION", ProtocolVersion(display)); AddNum(defs, "REVISION", ProtocolRevision(display)); @@ -574,7 +587,7 @@ AddNum(defs, "Y_RESOLUTION", Resolution(screen->height,screen->mheight)); AddNum(defs, "PLANES", DisplayPlanes(display, scrno)); AddNum(defs, "BITS_PER_RGB", visual->bits_per_rgb); - AddDef(defs, "CLASS", ClassNames[visual->class]); + AddDefQ(defs, "CLASS", ClassNames[visual->class]); sprintf(name, "CLASS_%s", ClassNames[visual->class]); AddNum(defs, name, (int)visual->visualid); switch(visual->class) { @@ -767,6 +780,40 @@ arg->used += strlen(s); } +static void +addescapedstring(String *arg, const char *s) +{ + char copy[512], *c; + + for (c = copy; *s && c < ©[sizeof(copy)-1]; s++) { + switch (*s) { + case '"': case '\'': case '`': + case '$': case '\\': + *c++ = '_'; + break; + default: + *c++ = *s; + } + } + *c = 0; + addstring (arg, copy); +} + +static void +addtokstring(String *arg, const char *s) +{ + char copy[512], *c; + + for (c = copy; *s && c < ©[sizeof(copy)-1]; s++) { + if (!isalpha(*s) && !isdigit(*s) && *s != '_') + *c++ = '_'; + else + *c++ = *s; + } + *c = 0; + addstring (arg, copy); +} + int main(int argc, char *argv[]) @@ -862,7 +909,7 @@ continue; } else if (arg[1] == 'I') { addstring(&includes, " "); - addstring(&includes, arg); + addescapedstring(&includes, arg); continue; } else if (arg[1] == 'U' || arg[1] == 'D') { if (num_cmd_defines < MAX_CMD_DEFINES) {