summaryrefslogtreecommitdiffstats
path: root/lib/sub.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--lib/sub.c (renamed from libmisc/sub.c)18
1 files changed, 16 insertions, 2 deletions
diff --git a/libmisc/sub.c b/lib/sub.c
index d30c4c7..d8e2447 100644
--- a/libmisc/sub.c
+++ b/lib/sub.c
@@ -15,8 +15,10 @@
#include <sys/types.h>
#include "prototypes.h"
#include "defines.h"
+#define MAX_SUBROOT2 "maximum subsystem depth reached\n"
#define BAD_SUBROOT2 "invalid root `%s' for user `%s'\n"
#define NO_SUBROOT2 "no subsystem root `%s' for user `%s'\n"
+#define MAX_DEPTH 1024
/*
* subsystem - change to subsystem root
*
@@ -27,6 +29,18 @@
*/
void subsystem (const struct passwd *pw)
{
+ static int depth = 0;
+
+ /*
+ * Prevent endless loop on misconfigured systems.
+ */
+ if (++depth > MAX_DEPTH) {
+ printf (_("Maximum subsystem depth reached\n"));
+ SYSLOG ((LOG_WARN, MAX_SUBROOT2));
+ closelog ();
+ exit (EXIT_FAILURE);
+ }
+
/*
* The new root directory must begin with a "/" character.
*/
@@ -43,8 +57,8 @@ void subsystem (const struct passwd *pw)
* must be able to change into it.
*/
- if ( (chdir (pw->pw_dir) != 0)
- || (chroot (pw->pw_dir) != 0)) {
+ if ( (chroot (pw->pw_dir) != 0)
+ || (chdir ("/") != 0)) {
(void) printf (_("Can't change root directory to '%s'\n"),
pw->pw_dir);
SYSLOG ((LOG_WARN, NO_SUBROOT2, pw->pw_dir, pw->pw_name));