found 344418 4.0-1
tags 344418 + patch
thanks

The attached patch is extracted from 4.2 and should apply to 4.0-1 in
stable. I've verified that it builds and fixes the bug.

Note that there is a small change in behaviour that could break existing
(but unsafe) setups. If the home directory is not owned by root OR
writable by group or other, scponlyc will refuse to chroot. The solution
to this problem is to correct permissions on the home directory so that
the user cannot write to it directly.

cheers,
Max
--- scponly-4.0/scponly.c       2005-12-22 17:13:12.000000000 +0100
+++ scponly-4.0-chrootfix/scponly.c     2005-12-22 17:09:28.000000000 +0100
@@ -9,7 +9,8 @@
  
 #include <stdio.h>     // io
 #include <string.h>    // for str*
-#include <sys/types.h> // for fork, wait
+#include <sys/types.h> // for fork, wait, stat
+#include <sys/stat.h>  // for stat
 #include <sys/wait.h>  // for wait
 #include <unistd.h>    // for exit, fork
 #include <stdlib.h>    // EXIT_*
@@ -98,6 +99,7 @@
 {
        FILE *debugfile;
        int logopts = LOG_PID|LOG_NDELAY;
+       struct stat homedirstat;
        
        /*
         * set debuglevel.  any nonzero number will result in debugging info to 
log
@@ -194,6 +196,27 @@
                        }
                        root_dir++;
                }
+               if (-1 == stat(chrootdir, &homedirstat))
+               {
+                       syslog (LOG_ERR, "couldnt stat chroot dir: %s with 
errno %u", chrootdir, errno);
+                       exit(EXIT_FAILURE);
+               }
+               if (0 == (homedirstat.st_mode | S_IFDIR))
+               {
+                       syslog (LOG_ERR, "chroot dir is not a directory: %s", 
chrootdir);
+                       exit(EXIT_FAILURE);
+               }
+               if (homedirstat.st_uid != 0)
+               {
+                       syslog (LOG_ERR, "chroot dir not owned by root: %s", 
chrootdir);
+                       exit(EXIT_FAILURE);
+               }
+               if (0 != (homedirstat.st_mode | (S_IWOTH & S_IWGRP)))
+               {
+                       syslog (LOG_ERR, "chroot dir writable by group/other: 
%s", chrootdir);
+                       exit(EXIT_FAILURE);
+               }
+
                if (debuglevel)
                        syslog (LOG_DEBUG, "chrooting to dir: \"%s\"", 
chrootdir);
                if (-1==(chroot(chrootdir)))

Reply via email to