Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 28 May 1997 01:17:48 +0900
From:      Shigio Yamaguchi <shigio@wafu.netgate.net>
To:        freebsd-hackers@FreeBSD.ORG
Cc:        shigio@wafu.netgate.net
Subject:   Bug fix for realpath(3).
Message-ID:  <199705270820.IAA12141@wafu.netgate.net>

next in thread | raw e-mail | index | archive | help
Hello, hackers.
I fixed two bugs in realpath(3). Would you please check this?

1. Realpath goes into infinite loop.

	% ln -s a b
	% ln -s b a

	[user's code]

	char resolved[MAXPATHLEN];
	(void)realpath("a", resolved);	/* It will not return */

   It should break when over MAXSYMLINKS symbolic links are encountered,
   like other system calls.

2. Realpath has unsafe code.

	[user's code]

	char resolved[MAXPATHLEN];
	(void)realpath("xxx", resolved);

	[realpath's code]

	n = readlink(p, resolved, MAXPATHLEN);
	if (n < 0)
		goto err1;
	resolved[n] = '\0';		/* It's dangerous */

   The last statement may corrupt user's area.
   I understand it cannot occur in normal case, because the length of
   symbolic link's value is 1023 at most. But I think following code
   would be better.

	n = readlink(p, resolved, MAXPATHLEN - 1);


Here is a patch.

*** realpath.c.org	Wed May 21 22:27:22 1997
--- realpath.c	Wed May 28 00:34:47 1997
***************
*** 62,67 ****
--- 62,68 ----
  	struct stat sb;
  	int fd, n, rootd, serrno;
  	char *p, *q, wbuf[MAXPATHLEN];
+ 	int symlinks = 0;
  
  	/* Save the starting point. */
  	if ((fd = open(".", O_RDONLY)) < 0) {
***************
*** 100,106 ****
  	/* Deal with the last component. */
  	if (*p != '\0' && lstat(p, &sb) == 0) {
  		if (S_ISLNK(sb.st_mode)) {
! 			n = readlink(p, resolved, MAXPATHLEN);
  			if (n < 0)
  				goto err1;
  			resolved[n] = '\0';
--- 101,111 ----
  	/* Deal with the last component. */
  	if (*p != '\0' && lstat(p, &sb) == 0) {
  		if (S_ISLNK(sb.st_mode)) {
! 			if (++symlinks > MAXSYMLINKS) {
! 				errno = ELOOP;
! 				goto err1;
! 			}
! 			n = readlink(p, resolved, MAXPATHLEN - 1);
  			if (n < 0)
  				goto err1;
  			resolved[n] = '\0';
--
Shigio Yamaguchi	E-Mail: shigio@wafu.netgate.net
			Home Page: http://wafu.netgate.net/tama/



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199705270820.IAA12141>