zsh-workers
 help / color / mirror / code / Atom feed
From: Peter Stephenson <p.stephenson@samsung.com>
To: Zsh Hackers' List <zsh-workers@zsh.org>
Subject: PATCH: safe numeric import
Date: Mon, 29 Sep 2014 11:04:20 +0100	[thread overview]
Message-ID: <20140929110420.52cc66f8@pwslap01u.europe.root.pri> (raw)
In-Reply-To: <20140926210818.3ac1bf20@pws-pc.ntlworld.com>

On Fri, 26 Sep 2014 21:08:18 +0100
Peter Stephenson <p.w.stephenson@ntlworld.com> wrote:
> On Fri, 26 Sep 2014 16:03:14 +0200
> Oliver Kiddle <okiddle@yahoo.co.uk> wrote:
> > For specials of numeric type we appear to be doing math evaluation on
> > their values.
> >   OPTIND='3+4' zsh -c 'echo $OPTIND'
> > And if you think you can't do anything with math evaluation:
> >   x='`date >&2`' OPTIND='pipestatus[1${(e)x}]' zsh -c ':'
> > 
> > Other shells don't even import OPTIND.
> 
> This affects OPTIND, TRY_BLOCK_ERROR and SHLVL.  It makes no sense
> to import the first two at all; they reflect internal status and having
> them initialised to something from outside seems wrong.
> 
> SHLVL does need to be imported, but doesn't need to be evaluated on
> import --- if it's not a straight integer at this point something is
> screwy.  So this could be checked.

OK, how about this?  When we're doing the import, all numbers, integer
or floating point, are imported straight, without an evaluation.
Sticking numbers into the environment to be evaluated later doesn't
make a lot of sense.

If you want to try this out you'll need to use env, since if you do the
assignment within zsh it'll carry out the evaluation immediately,
before exporting.

Currently we suppress all errors from parameters at this stage, though
we could make a special case and output errors when we truncate a
numeric import because we ignored anything after an initial constant.

diff --git a/Src/params.c b/Src/params.c
index 0699ead..61edc5d 100644
--- a/Src/params.c
+++ b/Src/params.c
@@ -46,7 +46,7 @@
  
 /**/
 mod_export int locallevel;
- 
+
 /* Variables holding values of special parameters */
  
 /**/
@@ -325,9 +325,12 @@ IPDEF4("ZSH_SUBSHELL", &zsh_subshell),
 IPDEF5("COLUMNS", &zterm_columns, zlevar_gsu),
 IPDEF5("LINES", &zterm_lines, zlevar_gsu),
 IPDEF5U("ZLE_RPROMPT_INDENT", &rprompt_indent, zlevar_gsu),
-IPDEF5("OPTIND", &zoptind, varinteger_gsu),
 IPDEF5("SHLVL", &shlvl, varinteger_gsu),
-IPDEF5("TRY_BLOCK_ERROR", &try_errflag, varinteger_gsu),
+
+/* Don't import internal integer status variables. */
+#define IPDEF6(A,B,F) {{NULL,A,PM_INTEGER|PM_SPECIAL|PM_DONTIMPORT},BR((void *)B),GSU(F),10,0,NULL,NULL,NULL,0}
+IPDEF6("OPTIND", &zoptind, varinteger_gsu),
+IPDEF6("TRY_BLOCK_ERROR", &try_errflag, varinteger_gsu),
 
 #define IPDEF7(A,B) {{NULL,A,PM_SCALAR|PM_SPECIAL},BR((void *)B),GSU(varscalar_gsu),0,0,NULL,NULL,NULL,0}
 #define IPDEF7U(A,B) {{NULL,A,PM_SCALAR|PM_SPECIAL|PM_UNSET},BR((void *)B),GSU(varscalar_gsu),0,0,NULL,NULL,NULL,0}
@@ -742,7 +745,8 @@ createparamtable(void)
 	    if (!idigit(*iname) && isident(iname) && !strchr(iname, '[')) {
 		if ((!(pm = (Param) paramtab->getnode(paramtab, iname)) ||
 		     !(pm->node.flags & PM_DONTIMPORT || pm->node.flags & PM_EXPORTED)) &&
-		    (pm = setsparam(iname, metafy(ivalue, -1, META_DUP)))) {
+		    (pm = assignsparam(iname, metafy(ivalue, -1, META_DUP),
+				       ASSPM_ENV_IMPORT))) {
 		    pm->node.flags |= PM_EXPORTED;
 		    if (pm->node.flags & PM_SPECIAL)
 			pm->env = mkenvstr (pm->node.nam,
@@ -2271,6 +2275,13 @@ export_param(Param pm)
 mod_export void
 setstrvalue(Value v, char *val)
 {
+    assignstrvalue(v, val, 0);
+}
+
+/**/
+mod_export void
+assignstrvalue(Value v, char *val, int flags)
+{
     if (unset(EXECOPT))
 	return;
     if (v->pm->node.flags & PM_READONLY) {
@@ -2347,7 +2358,13 @@ setstrvalue(Value v, char *val)
 	break;
     case PM_INTEGER:
 	if (val) {
-	    v->pm->gsu.i->setfn(v->pm, mathevali(val));
+	    zlong ival;
+	    if (flags & ASSPM_ENV_IMPORT) {
+		char *ptr;
+		ival = zstrtol_underscore(val, &ptr, 0, 1);
+	    } else
+		ival = mathevali(val);
+	    v->pm->gsu.i->setfn(v->pm, ival);
 	    if ((v->pm->node.flags & (PM_LEFT | PM_RIGHT_B | PM_RIGHT_Z)) &&
 		!v->pm->width)
 		v->pm->width = strlen(val);
@@ -2359,7 +2376,13 @@ setstrvalue(Value v, char *val)
     case PM_EFLOAT:
     case PM_FFLOAT:
 	if (val) {
-	    mnumber mn = matheval(val);
+	    mnumber mn;
+	    if (flags & ASSPM_ENV_IMPORT) {
+		char *ptr;
+		mn.type = MN_FLOAT;
+		mn.u.d = strtod(val, &ptr);
+	    } else
+		mn = matheval(val);
 	    v->pm->gsu.f->setfn(v->pm, (mn.type & MN_FLOAT) ? mn.u.d :
 			       (double)mn.u.l);
 	    if ((v->pm->node.flags & (PM_LEFT | PM_RIGHT_B | PM_RIGHT_Z)) &&
@@ -2742,8 +2765,8 @@ assignsparam(char *s, char *val, int flags)
 	    }
 	}
     }
-    
-    setstrvalue(v, val);
+
+    assignstrvalue(v, val, flags);
     unqueue_signals();
     return v->pm;
 }
diff --git a/Src/zsh.h b/Src/zsh.h
index fa73961..8f56fa2 100644
--- a/Src/zsh.h
+++ b/Src/zsh.h
@@ -1820,7 +1820,8 @@ struct paramdef {
  */
 enum {
     ASSPM_AUGMENT = 1 << 0,
-    ASSPM_WARN_CREATE = 1 << 1
+    ASSPM_WARN_CREATE = 1 << 1,
+    ASSPM_ENV_IMPORT = 1 << 2
 };
 
 /* node for named directory hash table (nameddirtab) */

pws


  reply	other threads:[~2014-09-29 10:04 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-09-24 14:45 zsh seems to be vulnerable to CVE-2014-6271: remote code execution through bash İsmail Dönmez
2014-09-24 14:54 ` Frank Terbeck
2014-09-24 14:55   ` İsmail Dönmez
2014-09-24 15:01   ` Peter Stephenson
2014-09-24 15:08     ` Frank Terbeck
2014-09-24 15:13     ` Jérémie Roquet
2014-09-24 14:55 ` Jérémie Roquet
2014-09-24 14:59 ` Chet Ramey
2014-09-25 13:11 ` Peter Stephenson
2014-09-26 14:03   ` Oliver Kiddle
2014-09-26 20:08     ` Peter Stephenson
2014-09-29 10:04       ` Peter Stephenson [this message]
2014-09-29 15:24         ` PATCH: safe numeric import Bart Schaefer
2014-10-01 14:57         ` [Bulk] " Oliver Kiddle
2014-10-02 16:06         ` Peter Stephenson

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20140929110420.52cc66f8@pwslap01u.europe.root.pri \
    --to=p.stephenson@samsung.com \
    --cc=zsh-workers@zsh.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://git.vuxu.org/mirror/zsh/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).