You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@httpd.apache.org by Dean Gaudet <dg...@arctic.org> on 1997/04/28 10:34:05 UTC

[PATCH] create_argv again and again

Roy's patch encodes foo.cgi?+a, and foo.cgi?a++b differently than the
strtok() version -- strtok collapses adjacent + and removes leading and
trailing+.  The CGI spec is silent on which is right.  But our pre 1.2b3
behaviour agrees with what Roy has done.  Unfortunately Roy's patch has
one bug: foo.cgi?a+ results in only one arg.

Looking at the new-httpd mail for the change 1.30 to 1.31 in
util_script.c I do not see the need to switch to strtok, nor the need
for APACHE_ARG_MAX (which can be huge!  On linux/irix/solaris this causes
a 16k wastage of RAM).  I do understand the other changes made at the same
time, and am not breaking them here.

The following patch re-implements the 1.30 create_argv behaviour,
including dynamic sizing of argv, plus the changes Roy made recently. 

Dean

Index: util_script.c
===================================================================
RCS file: /export/home/cvs/apache/src/util_script.c,v
retrieving revision 1.54
diff -c -3 -r1.54 util_script.c
*** util_script.c	1997/04/28 01:40:58	1.54
--- util_script.c	1997/04/28 08:27:15
***************
*** 73,106 ****
  #define MALFORMED_HEADER_LENGTH_TO_SHOW 30
  
  static char **create_argv(pool *p, char *path, char *user, char *group,
!                           char *av0, const char *reqargs)
  {
      char **av;
!     char *t;
!     char *args = pstrdup(p, reqargs);
      int idx = 0;
-     char *strtok_arg = args;
  
!     av = (char **)palloc(p, APACHE_ARG_MAX * sizeof(char *));
!     
      if (path)
!         av[idx++] = path;
      if (user)
          av[idx++] = user;
      if (group)
          av[idx++] = group;
  
      av[idx++] = av0;
-     
-     while ((idx < APACHE_ARG_MAX) && ((t = strtok(strtok_arg, "+")) != NULL)) {
-         strtok_arg = NULL;
- 	unescape_url(t);
- 	av[idx++] = escape_shell_cmd(p, t);
-     }
  
      av[idx] = NULL;
      return av;
  }
  
  static char *http2env(pool *a, char *w)
  {
--- 73,107 ----
  #define MALFORMED_HEADER_LENGTH_TO_SHOW 30
  
  static char **create_argv(pool *p, char *path, char *user, char *group,
!                           char *av0, const char *args)
  {
+     int x, n;
      char **av;
!     char *w;
      int idx = 0;
  
!     for(x = 0, n = 2; args[x]; x++)
!         if(args[x] == '+') ++n;
! 
!     av = (char **)palloc(p, (n + 4) * sizeof(char *));
      if (path)
! 	av[idx++] = path;
      if (user)
          av[idx++] = user;
      if (group)
          av[idx++] = group;
  
      av[idx++] = av0;
  
+     for (x = 1; x < n; x++) {
+         w = getword_nulls(p, &args, '+');
+         unescape_url(w);
+         av[idx++] = escape_shell_cmd(p, w);
+     }
      av[idx] = NULL;
      return av;
  }
+ 
  
  static char *http2env(pool *a, char *w)
  {
Index: util_script.h
===================================================================
RCS file: /export/home/cvs/apache/src/util_script.h,v
retrieving revision 1.15
diff -c -3 -r1.15 util_script.h
*** util_script.h	1997/04/27 06:55:52	1.15
--- util_script.h	1997/04/28 08:27:15
***************
*** 50,61 ****
   *
   */
  
- #ifdef _POSIX_ARG_MAX
- #define APACHE_ARG_MAX _POSIX_ARG_MAX
- #else
- #define APACHE_ARG_MAX 512
- #endif
- 
  char **create_environment(pool *p, table *t);
  int find_path_info(char *uri, char *path_info);
  void add_cgi_vars(request_rec *r);
--- 50,55 ----


Re: [PATCH] create_argv again and again

Posted by Dean Gaudet <dg...@arctic.org>.
Now that is a good argument, and something I can put back in.  But I'm
not allocating ARG_MAX*sizeof(char*).

Dean

On Mon, 28 Apr 1997, Marc Slemko wrote:

> On Mon, 28 Apr 1997, Dean Gaudet wrote:
> 
> > The following patch re-implements the 1.30 create_argv behaviour,
> > including dynamic sizing of argv, plus the changes Roy made recently. 
> 
> As long as we are sure there are no systems that allow exploitable
> overruns when their ARG_MAX is violated.  
> 
> 


Re: [PATCH] create_argv again and again

Posted by Marc Slemko <ma...@worldgate.com>.
On Mon, 28 Apr 1997, Dean Gaudet wrote:

> The following patch re-implements the 1.30 create_argv behaviour,
> including dynamic sizing of argv, plus the changes Roy made recently. 

As long as we are sure there are no systems that allow exploitable
overruns when their ARG_MAX is violated.  


Re: [PATCH] create_argv again and again (and again)

Posted by Dean Gaudet <dg...@arctic.org>.
On Mon, 28 Apr 1997, Dean Gaudet wrote:

> Roy's patch encodes foo.cgi?+a, and foo.cgi?a++b differently than the
> strtok() version -- strtok collapses adjacent + and removes leading and
> trailing+.  The CGI spec is silent on which is right.  But our pre 1.2b3
> behaviour agrees with what Roy has done.  Unfortunately Roy's patch has
> one bug: foo.cgi?a+ results in only one arg.
> 
> Looking at the new-httpd mail for the change 1.30 to 1.31 in
> util_script.c I do not see the need to switch to strtok, nor the need
> for APACHE_ARG_MAX (which can be huge!  On linux/irix/solaris this causes
> a 16k wastage of RAM).  I do understand the other changes made at the same
> time, and am not breaking them here.
> 
> The following patch re-implements the 1.30 create_argv behaviour,
> including dynamic sizing of argv, plus the changes Roy made recently. 

And the following update of the above patch respects APACHE_ARG_MAX to
avoid the potential for causing an overflow within system libraries.

Dean

Index: util_script.c
===================================================================
RCS file: /export/home/cvs/apache/src/util_script.c,v
retrieving revision 1.54
diff -c -3 -r1.54 util_script.c
*** util_script.c	1997/04/28 01:40:58	1.54
--- util_script.c	1997/04/28 19:50:05
***************
*** 73,106 ****
  #define MALFORMED_HEADER_LENGTH_TO_SHOW 30
  
  static char **create_argv(pool *p, char *path, char *user, char *group,
!                           char *av0, const char *reqargs)
  {
      char **av;
!     char *t;
!     char *args = pstrdup(p, reqargs);
      int idx = 0;
-     char *strtok_arg = args;
  
!     av = (char **)palloc(p, APACHE_ARG_MAX * sizeof(char *));
!     
      if (path)
!         av[idx++] = path;
      if (user)
          av[idx++] = user;
      if (group)
          av[idx++] = group;
  
      av[idx++] = av0;
-     
-     while ((idx < APACHE_ARG_MAX) && ((t = strtok(strtok_arg, "+")) != NULL)) {
-         strtok_arg = NULL;
- 	unescape_url(t);
- 	av[idx++] = escape_shell_cmd(p, t);
-     }
  
      av[idx] = NULL;
      return av;
  }
  
  static char *http2env(pool *a, char *w)
  {
--- 73,111 ----
  #define MALFORMED_HEADER_LENGTH_TO_SHOW 30
  
  static char **create_argv(pool *p, char *path, char *user, char *group,
!                           char *av0, const char *args)
  {
+     int x, n;
      char **av;
!     char *w;
      int idx = 0;
  
!     for(x = 0, n = 2; args[x]; x++)
!         if(args[x] == '+') ++n;
! 
!     if (n > APACHE_ARG_MAX - 4) {
! 	/* XXX: it would be preferable to give a malformed request response */
! 	n = APACHE_ARG_MAX - 4;
!     }
!     av = (char **)palloc(p, (n + 4) * sizeof(char *));
      if (path)
! 	av[idx++] = path;
      if (user)
          av[idx++] = user;
      if (group)
          av[idx++] = group;
  
      av[idx++] = av0;
  
+     for (x = 1; x < n; x++) {
+         w = getword_nulls(p, &args, '+');
+         unescape_url(w);
+         av[idx++] = escape_shell_cmd(p, w);
+     }
      av[idx] = NULL;
      return av;
  }
+ 
  
  static char *http2env(pool *a, char *w)
  {
Index: util_script.h
===================================================================
RCS file: /export/home/cvs/apache/src/util_script.h,v
retrieving revision 1.15
diff -c -3 -r1.15 util_script.h
*** util_script.h	1997/04/27 06:55:52	1.15
--- util_script.h	1997/04/28 19:50:06
***************
*** 50,59 ****
--- 50,61 ----
   *
   */
  
+ #ifndef APACHE_ARG_MAX
  #ifdef _POSIX_ARG_MAX
  #define APACHE_ARG_MAX _POSIX_ARG_MAX
  #else
  #define APACHE_ARG_MAX 512
+ #endif
  #endif
  
  char **create_environment(pool *p, table *t);