delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp-workers/1999/03/15/20:28:02

Message-Id: <199903160126.BAA32330@out4.ibm.net>
From: "Mark E." <snowball3 AT usa DOT net>
To: djgpp-workers AT delorie DOT com
Date: Mon, 15 Mar 1999 20:26:22 -0500
MIME-Version: 1.0
Subject: chroot patches v5.1 (final?)
X-mailer: Pegasus Mail for Win32 (v3.01d)
Reply-To: djgpp-workers AT delorie DOT com

Aside from adding a comment to the docs about of what use 
Unix/restrictive mode has, these chroot are essentially the same. I 
believe I have taken care of everything, but I'd like to post the complete 
set of patches once more just to make sure.

*** include/libc/root.h.orig	Sun Feb 28 14:25:36 1999
--- include/libc/root.h	Wed Mar 10 12:35:28 1999
***************
*** 0 ****
--- 1,16 ----
+ /* Copyright (C) 1999 DJ Delorie, see COPYING.DJ for details */
+ #ifndef __djgpp_libc_root_h
+ #define __djgpp_libc_root_h
+ 
+ #define ROOT_ENV "ROOT"
+ #define CHROOT_ENV "CHROOT_UNIX"
+ 
+ extern char * __djgpp_root;
+ extern int __djgpp_root_len;
+ 
+ int chroot (const char *path);
+ 
+ char *__delete_root (char *path);
+ 
+ #endif
+ 
*** include/libc/stubs.h.orig	Wed Mar 10 19:14:58 1999
--- include/libc/stubs.h	Wed Mar 10 19:04:16 1999
***************
*** 1,3 ****
--- 1,4 ----
+ /* Copyright (C) 1999 DJ Delorie, see COPYING.DJ for details */
  /* Copyright (C) 1997 DJ Delorie, see COPYING.DJ for details */
  /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
  #ifndef __dj_include_libc_stubs_h__
***************
*** 33,38 ****
--- 34,40 ----
  
  /* DJGPP functions (for compiling POSIX or ANSI functions) */
  
+ #define chroot __chroot
  #define crlf2nl __crlf2nl
  #define dosmemget __dosmemget
  #define dosmemput __dosmemput
***************
*** 55,60 ****
--- 57,63 ----
  #define spawnve __spawnve
  #define spawnvpe __spawnvpe
  #define stricmp __stricmp
+ #define strnicmp __strnicmp
  #define sync __sync
  
  #endif /* !_POSIX_SOURCE */
*** src/libc/crt0/crt1.c.orig	Thu Sep 17 05:50:22 1998
--- src/libc/crt0/crt1.c	Fri Feb 26 17:51:42 1999
***************
*** 1,3 ****
--- 1,4 ----
+ /* Copyright (C) 1999 DJ Delorie, see COPYING.DJ for details */
  /* Copyright (C) 1998 DJ Delorie, see COPYING.DJ for details */
  /* Copyright (C) 1997 DJ Delorie, see COPYING.DJ for details */
  /* Copyright (C) 1996 DJ Delorie, see COPYING.DJ for details */
***************
*** 189,194 ****
--- 190,196 ----
    __crt0_setup_arguments();
    _npxsetup(__crt0_argv ? __crt0_argv[0] : __dos_argv0);
    _crt0_init_mcount();
+   __crt0_setup_chroot();
    __main();
    errno = 0;	/* ANSI says errno should be zero at program startup */
    exit(main(__crt0_argc, __crt0_argv, environ));
*** src/libc/crt0/c1root.c.orig	Sun Feb 28 14:08:22 1999
--- src/libc/crt0/c1root.c	Thu Mar  4 12:46:52 1999
***************
*** 0 ****
--- 1,69 ----
+ #include <libc/root.h>
+ #include <libc/bss.h>
+ #include <stdlib.h>
+ #include <stdio.h>
+ #include <unistd.h>
+ 
+ /* Here is we check for three environmental variables
+    that may result in a call to chroot():
+    ROOT        - the root path. Can be set manually or by chroot().
+    CHROOT_UNIX - Y if chroot is to emulate the restrictive
+                  behavior of the Unix implementations.
+ 		 Any other value to select the non-restrictive
+ 		 behavior implemented by Bash 1.147.
+    SYSROOT     - Bash 1.147 sets this variable to the directory to
+                  use when searching for path names beginning
+ 		 with '/' or '\'. If ROOT is set, this variable
+ 		 is ignored. If ROOT is not set and SYSROOT does
+ 		 contain a path, then chroot() emulates the
+ 		 non-restrictive behavior of Bash 1.147 regardless
+ 		 of the value of CHROOT_UNIX. This variable is checked
+ 		 to maintain backward compatibility with Bash 1.147.
+ 		 Someday, this variable will be completely ignored
+ 		 once a DJGPP port of Bash 2 has been released
+ 		 and is in wide use. */
+ 
+ 
+ static int __setup_root_bss_count = 0;
+ 
+ void
+ __crt0_setup_chroot()
+ {
+   char *root = getenv(ROOT_ENV);
+   char *sysroot = (root ? NULL : getenv("SYSROOT"));
+   char *unix_mode = (!sysroot ? getenv(CHROOT_ENV) : NULL);
+   int ret_code;
+ 
+   if (unix_mode)
+   {
+     if (*unix_mode == 'Y' || *unix_mode == 'y')
+       __chroot_flags = __CHROOT_UNIX_MODE_FLAG;
+     else
+       __chroot_flags = 0;
+   }
+   else if (sysroot)
+     __chroot_flags = 0;
+ 
+   if (sysroot)
+     root = sysroot;
+ 
+   if (root)
+   {
+     __setup_root_bss_count = __bss_count;
+     /* Aborts if call to chroot() fails. */
+     if (chroot(root) < 0)
+     {
+       fprintf(stderr, "Call to chroot('%s') failed in 
__crt0_setup_chroot()\n", root);
+       abort();
+     }
+   }
+   /* If restarting, and ROOT or SYSROOT was not defined,
+      then reset _djgpp_root to no root. */
+   else if (__setup_root_bss_count != __bss_count)
+   {
+     __djgpp_root[0] = '\0';
+     __djgpp_root_len = 0;
+     __setup_root_bss_count = __bss_count;
+   }
+ }
+ 
*** src/libc/compat/unistd/makefile.orig	Sun Jun 28 17:53:24 1998
--- src/libc/compat/unistd/makefile	Wed Mar 10 18:47:28 1999
***************
*** 3,9 ****
--- 3,11 ----
  TOP=../..
  
  SRC += basename.c
+ SRC += chroot.c
  SRC += dirname.c
+ SRC += fchroot.c
  SRC += fsync.c
  SRC += ftruncat.c
  SRC += getdtabl.c
*** src/libc/compat/unistd/chroot.c.orig	Sun Feb 28 14:25:18 1999
--- src/libc/compat/unistd/chroot.c	Wed Mar 10 19:07:06 1999
***************
*** 0 ****
--- 1,154 ----
+ #include <unistd.h>
+ #include <fcntl.h>
+ #include <limits.h>
+ #include <sys/stat.h>
+ #include <errno.h>
+ #include <stdlib.h>
+ #include <libc/bss.h>
+ #include <libc/root.h>
+ 
+ static int chroot_bss_count = -1;
+ 
+ unsigned int __chroot_flags = __CHROOT_UNIX_MODE_FLAG;
+ static unsigned int old_flags;
+ 
+ /* To keep the space used for the root path and the
+    root dir. environment string to a minimum,
+    we alias __djgpp_root to inside root_env. */
+ 
+ static char root_env[PATH_MAX + sizeof(ROOT_ENV) + 1] = 
ROOT_ENV "=";
+ 
+ char * __djgpp_root = root_env + sizeof(ROOT_ENV);
+ int __djgpp_root_len = 0;
+ 
+ static char mode_env[] = CHROOT_ENV "=Y";
+ 
+ int
+ __chroot (const char *path)
+ {
+   char buf[PATH_MAX+1];
+   char *to = __djgpp_root;
+   char *from = buf;
+   const int old_root_len = __djgpp_root_len;
+   int unix_emu;
+   int path_len;
+ 
+   if ((path_len = strlen(path)) > PATH_MAX)
+   {
+     errno = ENAMETOOLONG;
+     return -1;
+   }
+ 
+   if (chroot_bss_count != __bss_count)
+   {
+     chroot_bss_count = __bss_count;
+     old_flags = ~0;
+   }
+ 
+   unix_emu = __chroot_flags & __CHROOT_UNIX_MODE_FLAG;
+ 
+   /* When not emulating the Unix behavior of chroot,
+      allow a null root to delete the root path. */
+   if (path == NULL || *path == '\0')
+   {
+     if (unix_emu)
+     {
+       errno = ENOENT;
+       return -1;
+     }
+     __djgpp_root[0] = '\0';
+     __djgpp_root_len = 0;
+     putenv(root_env);
+     return 0;
+   }
+ 
+   /* When in Unix/restrictive mode, don't allow drive letters
+      in a new root directory after a root directory has been set.
+      Even if the new directory is relative to the root. */
+   if (*path && *(path+1) == ':')
+   {
+     if (unix_emu && __djgpp_root_len > 0)
+     {
+       errno = EACCES;
+       return -1;
+     }
+   }
+ 
+   _fixpath(path, buf);
+ 
+   if (unix_emu)
+   {
+     /* If a root directory already exists, the new root directory
+        must be relative to the existing root directory.
+        If not, then reject the path. */
+     if (__djgpp_root_len > 0 && *buf != '/')
+     {
+       errno = EACCES;
+       return -1;
+     }
+   }
+ 
+   /* Make sure the path is valid before
+      making it the new root path. */
+   if (access(buf, D_OK) < 0)
+     return -1;
+ 
+   /* Copy in the new root path. */
+   if (*buf != '/')
+     __djgpp_root_len = 0;
+   else  /* Append to the current root path. */
+   {
+     to += __djgpp_root_len;
+   }
+ 
+   while (*from)
+   {
+     *to = *from;
+     ++to;
+     ++from;
+     ++__djgpp_root_len;
+   }
+   *to = '\0';
+ 
+   /* Set up environmental variables to be used so child programs
+      created with DJGPP will inherit the root path and mode. */
+   if (__djgpp_root_len != old_root_len)
+   {
+     putenv (root_env);
+   }
+ 
+   if (old_flags != __chroot_flags)
+   {
+     mode_env[sizeof(CHROOT_ENV)] = (unix_emu ? 'Y' : 'N');
+     putenv(mode_env);
+     old_flags = __chroot_flags;
+   }
+ 
+   return 0;
+ }
+ 
+ 
+ /* Delete the root path from an input path.
+    The input path is assumed to have already been canonicalized. */
+ 
+ char *
+ __delete_root (char *path)
+ {
+   if (__djgpp_root_len > 0 && path[0] != '/')
+   {
+     if (strnicmp (__djgpp_root, path, __djgpp_root_len) == 0
+         && (path[__djgpp_root_len] == '/' || path[__djgpp_root_len] == 
'\0'))
+     {
+       if (path[__djgpp_root_len] == '/')
+         strcpy (path, path + __djgpp_root_len);
+       else
+       {
+         /* path is equal to the root path. */
+         path[0] = '/';
+         path[1] = '\0';
+       }
+     }
+   }
+   return path;
+ }
+ 
*** src/libc/compat/unistd/chroot.txh.orig	Sun Feb 28 14:25:02 1999
--- src/libc/compat/unistd/chroot.txh	Mon Mar 15 20:16:32 1999
***************
*** 0 ****
--- 1,106 ----
+ @node chroot, file system
+ @subheading Syntax
+ 
+ @example
+ #include <unistd.h>
+ 
+ extern unsigned int __chroot_flags;
+ 
+ int chroot(const char *new_root_directory);
+ @end example
+ 
+ @subheading Description
+ 
+ Causes @var{new_root_directory} to become the root directory, or
+ starting point, for path name searches beginning with @file{/} or
+ @file{\}.  The current working directory is unaffected. 
+ 
+ By default, @code{chroot} is set to Unix compatibility or restrictive
+ mode.  In this mode, @var{new_root_directory} can be any existing
+ directory.  In successive calls, @var{new_root_directory} must exist 
and
+ be relative to the current root directory, or else the call fails.  The
+ only way to reset the root directory is with a call to @code{fchroot}
+ (@pxref{fchroot}).  This mimics the behavior of Unix versions of
+ @code{chroot}.  This mode is useful for programs, like ftp servers,
+ that want to make accessible a limited set of directories
+ to other programs, like ftp clients.
+ 
+ The other available mode is Bash compatibility or permissive mode. 
In
+ this mode, @var{new_root_directory} must still exist, but it need not 
be
+ relative to the current root like in restrictive mode. This mimics the
+ behavior of the @code{SYSROOT} environment variable in the 
DJGPP port of
+ Bash 1.14.7 which uses @code{SYSROOT} to allow paths like 
@file{/bin/ls}
+ to work.
+ 
+ To allow a child program to inherit the root directory of its parent,
+ @code{chroot} sets the environment variables @code{ROOT} and
+ @code{CHROOT_UNIX}.  If set, @code{ROOT} will contain the root
+ directory.  If @var{CHROOT_UNIX} is not set or is set to @samp{Y},
+ @code{chroot} is set to enforce the restrictive Unix behavior.  If
+ @code{CHROOT_UNIX} is set to anything other than @samp{Y}, then
+ @code{chroot} is set to allow the permissive behavior.  
@code{SYSROOT},
+ an environment variable used by the DJGPP port of Bash 1.14.7, is
+ supported in the interest of backward compatibility but its use is
+ discouraged.  If @code{ROOT} is not set, but @code{SYSROOT} is, 
then
+ @code{SYSROOT} is used to set the root directory, and 
@code{chroot} is
+ set to permissive mode, and @code{CHROOT_UNIX} is ignored.
+ 
+ The global variable @code{__chroot_flags} can be set to include the
+ following values to control the operation of @code{chroot}:
+ 
+ @table @code
+ 
+ @item __CHROOT_UNIX_MODE_FLAG
+ 
+ If set, @code{chroot} is in Unix compatibility or restrictive mode.  If
+ not set, @code{chroot} is in Bash compatibility or permissive mode.  
See
+ the above description for how these two modes differ.
+ 
+ @end table
+ 
+ @subheading Return Value
+ 
+ Zero if successful, else nonzero and @code{errno} set if error.
+ 
+ @subheading Portability
+ 
+ @port-note The variable @code{__chroot_flags} is DJGPP specific.
+ @portability !ansi, !posix
+ 
+ @subheading Example
+ 
+ In our examples, assume 'c:/djgpp' and 'c:/djgpp/bin/gcc.exe' exist.
+ 
+ An example for Unix compatibility or restrictive mode:
+ 
+ @example
+ chroot("c:/djgpp");
+ 
+ /* This call will not succeed. Root will not be changed. */
+ chroot("c:/");
+ 
+ /* Checks 'c:/djgpp/bin/gcc.exe'. */
+ if (access("/bin/gcc.exe", R_OK) == 0)
+   printf("gcc.exe found");  
+ 
+ /* Now change to 'c:/djgpp/bin'. */
+ chroot("/bin");
+ @end example
+ 
+ An example for Bash compatibility or permissive mode:
+ 
+ @example
+ /* Disable Unix compatibility or restrictive mode. */
+ __chroot_flags = 0;
+ 
+ chroot("c:/djgpp");
+ 
+ /* This will succeed since directory need not be relative
+    to 'c:/djgpp' like in the first example. */
+ chroot("c:/");
+ 
+ /* You can change to any directory on any drive as long
+    as the directory exists. */
+ chroot("d:/windows");
+ @end example
+ 
*** src/libc/compat/unistd/fchroot.c.orig	Sun Feb 28 14:25:24 1999
--- src/libc/compat/unistd/fchroot.c	Wed Mar  3 17:34:36 1999
***************
*** 0 ****
--- 1,17 ----
+ #include <unistd.h>
+ #include <errno.h>
+ #include <libc/root.h>
+ 
+ int
+ fchroot (int fd)
+ {
+   unsigned int flags = __chroot_flags;
+ 
+   /* Use &= in case more flags are ever added. */
+   __chroot_flags &= ~__CHROOT_UNIX_MODE_FLAG;
+   chroot (NULL);
+   __chroot_flags = flags;
+ 
+   return 0;
+ }
+ 
*** src/libc/compat/unistd/fchroot.txh.orig	Sun Feb 28 14:24:58 1999
--- src/libc/compat/unistd/fchroot.txh	Mon Mar  8 19:04:08 1999
***************
*** 0 ****
--- 1,39 ----
+ @node fchroot, file system
+ @subheading Syntax
+ 
+ @example
+ #include <unistd.h>
+ 
+ int fchroot(int file_handle);
+ @end example
+ 
+ @subheading Description
+ 
+ Clears the root directory set by any previous calls to @xref{chroot}.
+ Because DOS does not allow you to obtain a file handle to a
+ directory, @var{file_handle} is ignored.  This does introduce an
+ incompatibility with Unix.  However, since @code{fchroot} in Unix
+ is guaranteed to succeed only when changing to the system root,
+ this function will be portable most of the time.
+ 
+ @subheading Return Value
+ 
+ Always returns zero for success.
+ 
+ @subheading Portability
+ 
+ @port-note @code{fchroot} can only clear the root directory. The 
value of @var{file_handle} is ignored.
+ @portability !ansi, !posix
+ 
+ @subheading Example
+ 
+ @example
+ chroot("c:/djgpp");
+ if (access("/bin/gcc.exe", R_OK) < 0)
+   fprintf(stderr, "gcc.exe not found");  
+ 
+ fchroot(1);
+ 
+ if (access("/bin/gcc.exe", R_OK) < 0)
+   fprintf(stderr, "gcc.exe not found");  
+ @end example
*** src/libc/dos/io/putpath.c.orig	Thu Oct 29 05:24:44 1998
--- src/libc/dos/io/putpath.c	Tue Mar  9 00:17:48 1999
***************
*** 3,12 ****
--- 3,21 ----
  #include <libc/stubs.h>
  #include <libc/dosio.h>
  #include <libc/farptrgs.h>
+ #include <libc/root.h>
  #include <go32.h>
  #include <stdlib.h>
  #include <string.h>
  #include <errno.h>
+ #include <unistd.h>
+ 
+ static int
+ __inline__
+ __is_dirsep (char ch)
+ {
+   return ((ch == '/') || (ch == '\\'));
+ }
  
  void
  _put_path(const char *path)
***************
*** 31,37 ****
  
    if (p[0] && p[1] == ':')
      p += 2;
!   if (strncmp(p, "/dev/", 5) == 0)
    {
      if (strcmp(p+5, "null") == 0)
        path = "nul";
--- 40,46 ----
  
    if (p[0] && p[1] == ':')
      p += 2;
!   if (__is_dirsep(*p) && (strncmp("dev", p+1, 3) == 0) && 
__is_dirsep(*(p+4)))
    {
      if (strcmp(p+5, "null") == 0)
        path = "nul";
***************
*** 49,54 ****
--- 58,78 ----
      }
      else if (p[5])
        path = p + 5;
+   }
+   else if ((__is_dirsep(*path) || (__chroot_flags & 
__CHROOT_UNIX_MODE_FLAG)) && __djgpp_root_len > 0 )
+   {
+     /* If the path is absolute and a root path is set,
+        then add the root path to the output. */
+     char *root = __djgpp_root;
+ 
+     while (*root)
+     {
+       _farnspokeb (o++, *root);
+       space -= 1;
+       ++root;
+     }
+     if (!__is_dirsep(*path))
+       _farnspokeb (o++, '/');
    }
  
    /* collapse multiple slashes to a single slash */
*** src/libc/posix/sys/stat/fixpath.c.orig	Sun Dec 13 08:09:46 1998
--- src/libc/posix/sys/stat/fixpath.c	Thu Feb 25 14:01:42 1999
***************
*** 13,18 ****
--- 13,19 ----
  #include <crt0.h>		/* For crt0 flags */
  #include <sys/stat.h>
  #include <libc/dosio.h>
+ #include <libc/root.h>
  
  static unsigned use_lfn;
  
***************
*** 73,78 ****
--- 74,80 ----
     5. Removing ".." entries in the path (and the directory above them)
     6. Adding a drive specification if one wasn't there
     7. Converting all slashes to '/'
+    8. Remove the portion of the path matching the root path
   */
  void
  _fixpath(const char *in, char *out)
***************
*** 227,232 ****
--- 229,240 ----
      }
      else if (*op == '\0')
        break;
+   }
+ 
+   /* Remove the portion of the path matching the root path */
+   if (__djgpp_root_len > 0 && out[0] != '/')
+   {
+     __delete_root(out);
    }
  }
  
*** src/libc/posix/unistd/getcwd.c.orig	Sat Aug 31 18:09:32 1996
--- src/libc/posix\unistd/getcwd.c	Wed Mar 10 19:01:22 1999
***************
*** 13,18 ****
--- 13,19 ----
  #include <crt0.h>
  #include <libc/farptrgs.h>
  #include <libc/dosio.h>
+ #include <libc/root.h>
  
  char *
  __getcwd(char *buf, size_t size)
***************
*** 107,112 ****
--- 108,119 ----
    __dpmi_int(0x21, &r);
  
    buf[0] = r.h.al + (r.h.al < 26 ? 'a' : 'A');
+ 
+ 	/* See if we need to strip the root path set by chroot */
+   if (__djgpp_root_len > '\0')
+   {
+     __delete_root(buf);
+   }
  
    return buf;
  }
*** src/libc/stubs/stub0038.s.orig	Wed Mar 10 18:35:28 1999
--- src/libc/stubs/stub0038.s	Wed Mar 10 19:23:34 1999
***************
*** 0 ****
--- 1,5 ----
+ /* Copyright (C) 1999 DJ Delorie, see COPYING.DJ for details */
+ 	.file "sync.stub"
+         .global _chroot
+ _sync:
+         jmp ___chroot
*** src/libc/stubs/stub0039.s.orig	Wed Mar 10 18:35:28 1999
--- src/libc/stubs/stub0039.s	Wed Mar 10 19:23:42 1999
***************
*** 0 ****
--- 1,5 ----
+ /* Copyright (C) 1999 DJ Delorie, see COPYING.DJ for details */
+ 	.file "sync.stub"
+         .global _strnicmp
+ _sync:
+         jmp ___strnicmp

--- 
Mark Elbrecht, snowball3 AT usa DOT net
http://snowball.digitalspace.net/

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019