[scponly] Patch for chdir bug with version 4.0

David Ramsden david at hexstream.eu.org
Fri Dec 3 18:41:38 EST 2004


[Note: This is a repost of my previous message, just not signed with my
PGP key because the mailing list archive doesn't display it properly]

Hi,

Once again, version 4.0 suffers from a bug which prevents chdir's from
working if scponly puts the user in a chroot.

This also existed in scponly 3.11 for which I also created a patch for
(this was included in Debian unstable's scponly package).

Not only does it correct the problem but also fixes a security violation
- after you chroot() you should /always/ chdir() to lessen the chances
of being able to break out of the chroot. Please read chroot(2) for more
information, especially this part:
----
       Note that this call does not change  the  current  working
       directory,  so  that `.' can be outside the tree rooted at
       `/'.  In particular, the  super-user  can  escape  from  a
       `chroot jail' by doing `mkdir foo; chroot foo; cd ..'.
----

The mentioned patch for 4.0 is attached.

Regards,
David.
-- 
 .''`.     David Ramsden <david at hexstream.eu.org>
: :'  :    http://david.hexstream.eu.org/
`. `'`     PGP key ID: 507B379B on wwwkeys.pgp.net
  `-  Debian - when you have better things to do than to fix a system.
-------------- next part --------------
--- scponly.c.old	Fri Dec  3 23:19:04 2004
+++ scponly.c	Fri Dec  3 23:16:24 2004
@@ -180,12 +180,15 @@
 	if (chrooted)
 	{
 		char *root_dir = chrootdir;
+		char chdir_path[FILENAME_MAX];
 
+		strcpy(chdir_path, "/");
 		strcpy(chrootdir, homedir);
 		while((root_dir = strchr(root_dir, '/')) != NULL) 
 		{
 			if (strncmp(root_dir, "//", 2) == 0) 
 			{
+				snprintf(chdir_path, FILENAME_MAX, "%s", root_dir + 1);
 				*root_dir = '\0';
 				break;
 			}
@@ -200,6 +203,20 @@
 				syslog (LOG_ERR, "chroot: %m");
 			}
 			syslog (LOG_ERR, "couldn't chroot to %s [%s]", chrootdir, logstamp());
+			exit(EXIT_FAILURE);
+		}
+
+		if (debuglevel)
+		{
+			syslog (LOG_DEBUG, "chdiring to dir: \"%s\"", chdir_path);
+		}
+		if (-1==(chdir(chdir_path)))
+		{
+			if (debuglevel)
+			{
+				syslog (LOG_ERR, "chdir: %m");
+			}
+			syslog (LOG_ERR, "couldn't chdir to %s [%s]", chdir, logstamp());
 			exit(EXIT_FAILURE);
 		}
 	}


More information about the scponly mailing list