Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
Bug 407707 - lxde-base/menu-cache-0.3.2 creates predictably named .menu-cached-* socket in /tmp
Summary: lxde-base/menu-cache-0.3.2 creates predictably named .menu-cached-* socket in...
Status: RESOLVED FIXED
Alias: None
Product: Gentoo Security
Classification: Unclassified
Component: Auditing (show other bugs)
Hardware: All Linux
: Normal normal (vote)
Assignee: Gentoo Security
URL: https://sourceforge.net/tracker/?func...
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2012-03-10 18:57 UTC by Maxim Kammerer
Modified: 2013-08-20 23:09 UTC (History)
0 users

See Also:
Package list:
Runtime testing required: ---


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Maxim Kammerer 2012-03-10 18:57:01 UTC
# grep -r '\.menu-cached' menu-cache-0.3.2
menu-cache-0.3.2/menu-cache-daemon/menu-cached.c:    g_snprintf( buf, len, "/tmp/.menu-cached-%s-%s", dpy ? dpy : ":0", g_get_user_name() );
menu-cache-0.3.2/libmenu-cache/menu-cache.c:    g_snprintf( buf, len, "/tmp/.menu-cached-%s-%s", dpy ? dpy : ":0", g_get_user_name() );

This can be easily fixed by using g_get_tmp_dir() instead of "/tmp".
Comment 1 Alex Legler (RETIRED) archtester gentoo-dev Security 2012-03-10 19:45:53 UTC
Documentation for g_get_tmp_dir(): "Gets the directory to use for temporary files. This is found from inspecting the environment variables TMPDIR, TMP, and TEMP in that order. If none of those are defined "/tmp" is returned on UNIX…"

That wouldn't change anything about the name being predictable.

The code also calls unlink() on the to-be-created socket before binding it, avoiding potential symlink issues.

So, can you elaborate on what you think is the issue here?
Comment 2 Maxim Kammerer 2012-03-10 20:01:11 UTC
(In reply to comment #1)
> That wouldn't change anything about the name being predictable.

No, but other users will not be able to create a file with the same name in the directory (e.g., pam_mktemp sets TMPDIR to /tmp/.private/${USER}).

> The code also calls unlink() on the to-be-created socket before binding it,
> avoiding potential symlink issues.

Not really -- there is a race condition there. The unlink() doesn't help the security issue anyway, since the client will connect to the socket regardless.

> So, can you elaborate on what you think is the issue here?

This is a classic Unix security vulnerability:
http://siber.cankaya.edu.tr/ozdogan/SystemsProgramming/ceng425/node201.html
Comment 3 Alex Legler (RETIRED) archtester gentoo-dev Security 2012-03-10 21:29:39 UTC
(In reply to comment #2)
> (In reply to comment #1)
> > That wouldn't change anything about the name being predictable.
> 
> No, but other users will not be able to create a file with the same name in
> the directory (e.g., pam_mktemp sets TMPDIR to /tmp/.private/${USER}).

That's nice-to-have, but nothing I'd call vulnerability.

> 
> > The code also calls unlink() on the to-be-created socket before binding it,
> > avoiding potential symlink issues.
> 
> Not really -- there is a race condition there. The unlink() doesn't help the
> security issue anyway, since the client will connect to the socket
> regardless.

Yes, there is a race between unlink() and the following bind() and the unlink is of course not a remedy (as I might have wrongly implied in my previous comment). But what happens? Either the daemon creates the socket and all goes well or the attacker does, doing what?
Contrary to the example you linked, this isn't a regular file that is written to. If the socket file exists, bind() fails (contrary to a default open()), and the daemon exits.

I think you should talk to upstream about this. Should they see the need to change anything here, make another comment here and we'll be assigning this bug to the maintainers. Thanks.
Comment 4 Maxim Kammerer 2012-03-10 21:35:42 UTC
(In reply to comment #3)
> Either the daemon creates the socket
> and all goes well or the attacker does, doing what?
> Contrary to the example you linked, this isn't a regular file that is
> written to. If the socket file exists, bind() fails (contrary to a default
> open()), and the daemon exits.

As I wrote: "The unlink() doesn't help the security issue anyway, since the client will connect to the socket regardless." bind() fails in the daemon, but the client application will connect to attacker's socket.

> I think you should talk to upstream about this.

I will file a bug, but the LXDE project is quite unresponsive.
Comment 6 Alex Legler (RETIRED) archtester gentoo-dev Security 2012-03-10 21:57:19 UTC
(In reply to comment #4)
> (In reply to comment #3)
> > Either the daemon creates the socket
> > and all goes well or the attacker does, doing what?
> > Contrary to the example you linked, this isn't a regular file that is
> > written to. If the socket file exists, bind() fails (contrary to a default
> > open()), and the daemon exits.
> 
> As I wrote: "The unlink() doesn't help the security issue anyway, since the
> client will connect to the socket regardless." bind() fails in the daemon,
> but the client application will connect to attacker's socket.

Ah, now we're on the same page. Yeah, the client could connect to such a socket, but it would require vulnerabilities in the protocol parsing to exploit it further. 
Your suggested g_get_tmp_dir change can indeed be used to improve security, this isn't a vulnerability on its own though.
Comment 7 Maxim Kammerer 2012-03-10 23:24:37 UTC
(In reply to comment #6)
> Your suggested g_get_tmp_dir change can indeed be used to improve security,
> this isn't a vulnerability on its own though.

Well, it's an easy local DoS, at least. Logging out of X, recreating the socket owned by another user and with no access permissions to the original user, and logging to X again, results in empty menu in lxpanel.

These are the messages:
** ERROR **: Couldn't remove previous socket file /tmp/.menu-cached-:0-anon
Unable to connect
unable to connect to menu-cached.
Comment 8 Maxim Kammerer 2012-03-10 23:48:26 UTC
FWIW, I don't see any obvious vulnerability with handling server data in menu-cache.c (on_server_io()). Although

    if(0 == memcmp(cache->md5, menu_cache_id, 32))
 
can potentially crash the client if menu_cache_id has insufficient length. But whoever wrote that code at least tried to handle arbitrary data correctly.
Comment 9 Maxim Kammerer 2013-01-01 23:02:50 UTC
(In reply to comment #5)
> Reported upstream:
> https://sourceforge.net/tracker/?func=detail&aid=3501347&group_id=180858&atid=894869

Should be fixed in menu-cache-0.4 according to upstream.