Bug 57486 (CVE-2004-0689)

Summary: VUL-0: CVE-2004-0689: KDE: problems with filename
Product: [Novell Products] SUSE Security Incidents Reporter: Thomas Biege <thomas>
Component: IncidentsAssignee: Thomas Biege <thomas>
Status: RESOLVED FIXED QA Contact: Security Team bot <security-team>
Severity: Normal    
Priority: P3 - Medium CC: patch-request, security-team
Version: unspecified   
Target Milestone: ---   
Hardware: All   
OS: Linux   
Whiteboard: CVE-2004-0689: CVSS v2 Base Score: 4.6 (AV:L/AC:L/Au:N/C:P/I:P/A:P)
Found By: --- Services Priority:
Business Priority: Blocker: ---
Marketing QA Status: --- IT Deployment: ---
Attachments: patch
patchinfo-box.kdelibs3
patchinfo.kdelibs3
arts patch
arts patch #2
kdelibs patch for 9.0
patchinfo-box.kdelibs3 (new)
patchinfo.kdelibs3 (new)
patchinfo-box.arts
patchinfo.arts
patchinfo.kdelibs3-4vulns
patchinfo-box.kdelibs3-4vulns
patchinfo.kdelibs3-3vulns
patchinfo-box.kdelibs3-3vulns

Description Thomas Biege 2004-06-25 21:15:21 UTC
Hello KDE-Maintainers. 
We got a private report about bugs in KDE. 
 
1.)	local denial of service 
	By creating files in /tmp/ like "kde-<user>" "kdecache-<user>" 
	"ksocket-<user>" and "mcop-<user>" that are not owned by <user> 
	the user <user> can not log in anymore 
 
	I don't consider this a serious problem and would suggest a 
	more comprehensive error message as solution. 
 
2.)	overwrite arbitrary files 
	By creating a directory "(/var)/tmp/kdecache-<user>" and 
	sym-linking "ksycocastamp" in it, it is possible to overwrite 
	files with the privileges of <user> 
 
Original report: 
Date: Wed, 23 Jun 2004 04:34:37 -0400 
From: Andrew Tuitt <andrew@tuitt.net> 
To: security@suse.de 
Subject: [security@suse.de] kde /tmp and /var/tmp DoS and possible file 
overwriting question 
 
I was wondering, does kde's usage of non-random /tmp dir names mean it poses a 
potential denial of service and possible file overwriting issue if someone 
else makes a dir with the same names? 
 
I tested this by creating a "kde-<user>" "kdecache-<user>" "ksocket-<user>" 
and "mcop-<user>" folder with the username that I wanted to deny the ability 
to login into the proper /tmp or /var/tmp folders and it effectively denies 
that user's ability to login to kde and pops up a dcop error when they try to 
login.  It only works if this is done before a user logs in for the first 
time or if it is done after their /tmp and /var/tmp folders were cleaned out 
before someone logs in again in kde.  This requires shell access to pull off 
and on a machine that someone also logs into kde with. 
 
Also, I tried testing a few file overwriting techniques using symlink attacks 
and one indeed did work.  If a malicious shell user 
makes /var/tmp/kdecache-<user>/ (or is it /tmp/kdecache-<user> ?) world 
accessible ( chmod 777) and makes a file in it named "ksycocastamp" really be 
a symlink to /home/<user>/file-to-erase, kde erases the contents of that file 
with what it would normally write into that file.  This only works if the 
user was able to create kde's non-random tmp dirs before someone logs in.  It 
quite potentially could be more of a problem for people who have their /tmp 
and /var/tmp erased at every boot, since that means anyone who logs in the 
shell before another user can then create whatever dirs necessary to deny 
them the ability to login or overwrite a target file. 
 
Also, this is not good if someone logs is as root to the system in kde.  KDE 
creates the standard "kde-root" , "ksocket-root", "kdecache-root", and 
"mcop-root" folders for the root user.  You could have "ksycocastamp" 
symlinked to /important-system-file and have it arbitrarily overwrite it when 
someone logs in as root in kde.
Comment 1 Thomas Biege 2004-06-25 21:15:21 UTC
<!-- SBZ_reproduce  -->
-
Comment 2 Waldo Bastian 2004-06-25 23:10:56 UTC
During login lnusertemp is supposed to catch these situations. 
 
For example, if I chown /tmp/kde-bastian to root I will get: 
 
> lnusertemp tmp 
Link points to "/tmp/kde-bastian" 
Error: "/tmp/kde-bastian" is owned by uid 0 instead of uid 500. 
Created link from "/home/bastian/.kde/tmp-linux" to "/tmp/kde-bastianquXkhT" 
 
lnusertemp is responsible for the "kde-<user>", "kdecache-<user>" and 
"ksocket-<user>" links. 
 
mcop seems to be handled differently though. 
 
 
Comment 3 Waldo Bastian 2004-06-25 23:19:03 UTC
There might be room for failure in the following two cases: 
 
* User doesn't use KDE but other window manager and starts KDE application 
* User runs KDE application as root without being logged in as root. 
Comment 4 Waldo Bastian 2004-06-26 22:48:03 UTC
Created attachment 21703 [details]
patch

Attached patch should solve the two issues I mentioned in #3. Coolo, please
review this patch.

The code that creates the mcop link already does santity checks, see 
arts/mcop/mcoputils.cpp: MCOPUtils::createFilePath

arts will fail if someone has messed with the mcop directory.
Comment 5 Stephan Kulow 2004-06-26 23:41:05 UTC
some comments might be useful here :) 
 
From what I can tell the patch looks correct, but I'm sure the security guys will some 
nitpicks. 
Comment 6 Thomas Biege 2004-06-28 14:55:19 UTC
Judging from the code snippet there is still a race condition in it (a gap 
between point-of-check and point-of-use). 
But as long as we operate on a +t directory like /tmp this will not harm us. 
 
 
Comment 7 Thomas Biege 2004-07-15 17:06:13 UTC
I have reviewd function/method 'createFilePath(string name)' as it exists in 
the 9.0 arts code. 
 
string MCOPUtils::createFilePath(string name) 
{ 
// changed to get logname from uid instead of environment variable 
// LOGNAME to avoid trouble when LOGNAME does not exist or 
// is wrong (such as in kdesu environment) 
// S. Voitzsch Sebastian.Voitzsch@web.de 
// 2002-12-03 
        struct passwd *pwd = NULL; 
        // XXX why is get_e_uid() used here, access control is done 
        // with getuid() later!!! 
        pwd = getpwuid(geteuid()); 
        if (pwd == NULL) 
                arts_fatal("could not get user name from user id"); 
 
        string logname = pwd->pw_name; 
 
        string tmpdir = "/tmp/mcop-"+uglify(logname); 
        // XXX the direc is allowed to exist 
        if(mkdir(tmpdir.c_str(),0700) != 0 && errno != EEXIST) 
                arts_fatal("can't create %s (%s)", 
tmpdir.c_str(),strerror(errno)); 
 
        /** check that /tmp/mcop-<username>/ is a secure temporary dir **/ 
        struct stat st; 
        if(lstat(tmpdir.c_str(),&st) != 0) 
                arts_fatal("can't stat %s (%s)", 
tmpdir.c_str(),strerror(errno)); 
 
        if (st.st_uid != getuid ()) 
                arts_fatal("%s is not owned by user", tmpdir.c_str()); 
 
        if(st.st_mode & 0077) 
                arts_fatal("%s is accessible owned by user", tmpdir.c_str()); 
 
        if(!S_ISDIR(st.st_mode)) 
                arts_fatal("%s is not a directory", tmpdir.c_str()); 
 
        // XXX the checks above allows links to user owned, mode 7700 
directories 
        // XXX we can pass this check by linking to an user owned direc and 
then 
        // remove the link afterwards 
 
        string::iterator si; 
        for(si = name.begin(); si != name.end(); si++) 
        { 
                unsigned char c = (unsigned char)*si; 
                if((c >= 'a' && c <= 'z') || 
                   (c >= 'A' && c <= 'Z') || 
                   (c >= '0' && c <= '9') || 
                   (c == '-')) 
                { 
                        // ok, these are fine for our filesystem ;) 
                } 
                else 
                { 
                        *si = '_'; 
                } 
        } 
        return tmpdir+"/"+name; // XXX at this point we may end up in a direc 
        // created by a local attacker with 'name' as a symbolic link 
} 
Comment 8 Thomas Biege 2004-07-15 17:07:47 UTC
... my comments in the above pasted code snippet are prefixed by 'XXX' 
Comment 9 Marcus Meissner 2004-07-15 17:09:14 UTC
lstat will not follow symlinks, which invalidates your comments I think. 
Comment 10 Thomas Biege 2004-07-15 17:30:13 UTC
arg, yes I missed it... too bad. Thanks Marcus. 
Comment 11 Thomas Biege 2004-07-15 17:43:37 UTC
Waldo can you build some update for testing please. 
 
Which packages are affected? kdelibs3 only? 
Comment 12 Thomas Biege 2004-07-15 17:50:35 UTC
Created attachment 22205 [details]
patchinfo-box.kdelibs3
Comment 13 Thomas Biege 2004-07-15 17:50:52 UTC
Created attachment 22206 [details]
patchinfo.kdelibs3
Comment 14 Thomas Biege 2004-07-15 19:10:03 UTC
Does the above usage of geteuid() instead of getuid() can cause problems when 
running a setuid KDE application? 
 
imagine the following scenario: 
	+ /tmp/mcop-root doesnt exist 
	+ user creates /tmp/mcop-root 
	+ user execs a setuid KDE app 
	+ createFilePath() uses geteuid() to determine the direc. 
	name, but getuid() to verify access permissions 
	+ the setuid KDE app will end up in a user-controled direc 
	which should only be accessible by root 
Comment 15 Waldo Bastian 2004-07-15 19:33:12 UTC
Re #11: No, I don't make packages, but maybe Adrian will. 
 
Re #14: setuid KDE apps are a very bad idea and we try hard not to allow that 
(e.g. by aborting when we detect geteuid != getuid)so I'm not sure if there 
are vulnerable applications around (and if there are, there sound would not be 
working because in the normal case because this access check would fail then), 
but I agree that for consistency geteuid() should be used to verify access 
permissions. 
Comment 16 Waldo Bastian 2004-07-15 19:38:18 UTC
Created attachment 22209 [details]
arts patch

Use same uid for obtaining name and doing owner check
Comment 17 Thomas Biege 2004-07-15 20:19:07 UTC
where and when does this euid!=uid detection happen? 
 
concerning the patch I would suggest to use "pid_t uid" instead of "int uid" 
to avoid casting problems. 
 
Comment 18 Waldo Bastian 2004-07-15 23:56:08 UTC
Created attachment 22219 [details]
arts patch #2

New patch that uses uid_t instead of int (or pid_t ;-)

KApplication::init checks for uid != euid (kdelibs/kdecore/kapplication.cpp)
Comment 19 Thomas Biege 2004-07-20 20:10:28 UTC
Hello Waldo, 
can you make a patch for 9.0 too please. The reporter of this bug likes to 
test it. I built 9.1 packages for kdelibs3 and arts but he uses 9.0. 
You patch does no apply to 9.0 kdelibs3. The code looks much different. 
Comment 20 Adrian Schröter 2004-07-21 13:46:17 UTC
the patch is for the arts package, not kdelibs 
Comment 21 Waldo Bastian 2004-07-21 16:27:38 UTC
Created attachment 22317 [details]
kdelibs patch for 9.0

Patch for SL9.0 (kdelibs, backport of 13703)
Comment 22 Thomas Biege 2004-07-21 16:53:28 UTC
Thanks a lot. 
Comment 23 Thomas Biege 2004-07-22 15:32:46 UTC
I did forward the packages to the reporter of the bug for testing...  
Comment 24 Thomas Biege 2004-07-23 15:08:22 UTC
Date: Thu, 22 Jul 2004 21:41:41 -0400 
From: Andrew Tuitt <andrew@tuitt.net> 
To: Thomas Biege <thomas@suse.de> 
Subject: Re: [security@suse.de] kde /tmp and /var/tmp DoS and possible file 
overwriting question 
 
Thomas Biege wrote: 
> hi, 
> all 9.0 packages are available. 
> 
> http://www.suse.de/~thomas/RPM/9.0/ 
> 
> Please let me know if the patches work. 
> 
> Bye, 
>      Thomas 
 
I tested the patch and it looks like it fixed it!  It now appears to use a 
randomly named temp folder if its normal temp folder 
is owned by another user and nothing gets overwritten when I put a bunch of 
symlinks in place of files that it normally creates 
in the old temp folder. 
Comment 25 Thomas Biege 2004-07-23 15:13:35 UTC
Ok, let's do an update. 
 
I'll propose 11th of august as release date. Is this time enough for 
backporting? (don't forget QA-testing) 
Comment 26 Thomas Biege 2004-07-23 15:22:40 UTC
Created attachment 22360 [details]
patchinfo-box.kdelibs3 (new)
Comment 27 Thomas Biege 2004-07-23 15:23:03 UTC
Created attachment 22361 [details]
patchinfo.kdelibs3 (new)
Comment 28 Thomas Biege 2004-07-23 15:29:59 UTC
Created attachment 22362 [details]
patchinfo-box.arts
Comment 29 Thomas Biege 2004-07-23 15:30:18 UTC
Created attachment 22363 [details]
patchinfo.arts
Comment 30 Adrian Schröter 2004-07-23 16:01:14 UTC
package building / backporting is in progress. 
 
wrt your patchinfo texts: The standard KDE user is not affected as Waldo 
mentioned. Only people who start the first time a KDE application outside of 
their KDE session, after the /tmp/ directory gets cleaned. 
 
Comment 31 Thomas Biege 2004-07-23 20:38:47 UTC
Date: Fri, 23 Jul 2004 08:36:34 +0100 (BST) 
From: Mark J Cox <mjc@redhat.com> 
To: Thomas Biege <thomas@suse.de> 
Cc: vendor-sec@lst.de 
Subject: Re: [vendor-sec] [security@suse.de] kde /tmp and /var/tmp DoS and 
possible file overwriting question (fwd) 
 
> What about 11th of August 16:00 MEST as release date? 
 
Fine with us, use CAN-2004-0689 for this. 
 
Mark 
 
Comment 32 Adrian Schröter 2004-07-26 17:09:00 UTC
packages got checked in. 
 
I leave it open for tracking. 
Comment 33 Thomas Biege 2004-07-26 19:59:18 UTC
thx 
Comment 34 Thomas Biege 2004-08-05 17:21:39 UTC
Created attachment 22566 [details]
patchinfo.kdelibs3-4vulns
Comment 35 Thomas Biege 2004-08-05 17:22:01 UTC
Created attachment 22567 [details]
patchinfo-box.kdelibs3-4vulns
Comment 36 Thomas Biege 2004-08-05 17:41:14 UTC
Created attachment 22575 [details]
patchinfo.kdelibs3-3vulns
Comment 37 Thomas Biege 2004-08-05 17:41:43 UTC
Created attachment 22576 [details]
patchinfo-box.kdelibs3-3vulns
Comment 38 Thomas Biege 2004-08-13 21:13:40 UTC
packages approved 
Comment 39 Thomas Biege 2009-10-13 20:27:24 UTC
CVE-2004-0689: CVSS v2 Base Score: 4.6 (AV:L/AC:L/Au:N/C:P/I:P/A:P)