Fwd: Re: Buffer Overflow with all versions of Internet Explorer and Javacript.

Koos Vriezen koos.vriezen at xs4all.nl
Sun Aug 4 22:09:41 BST 2002


On Wed, 5 Jun 2002, Koos Vriezen wrote:

> On Wed, 5 Jun 2002, Harri Porten wrote:
> > On Tue, 4 Jun 2002, Koos Vriezen wrote:
> > > On Tue, 4 Jun 2002, Koos Vriezen wrote:
> > > > On Tue, 4 Jun 2002, Harri Porten wrote:
> > > > > But I wouldn't know what to
> > > > > really do against infinite loops like while(1);. They can be by design and
> > > > > harmless but there is no way to abort them, yet. Easier with threading.
> > > >
> > > > Maybe use SIGALARM?
> > >
> > > Just a small hack that stops a 'while(true);' script after 5 seconds:
> >
> > SIGALARM is also the best solution I can think of. But it needs more
> > thinking as it has to be made more flexible. If the interpreter hangs in
> > a call to an interactive function (e.g. window.alert()) it's perfectly
> > acceptable to wait infinitely.
>
>
> Hmmm, just looked at the setitimer manpage. ITIMER_VIRTUAL seems a good
> option. It doesn't decrement with 'window.alert' alikes. We also get
> milli seconds resolution. Eg.
>   signal(SIGVTALRM, alarmHandler);
>   struct itimerval tv = { { 2, 0}, { 5, 0 } };
>   setitimer(ITIMER_VIRTUAL, &tv, 0L);
>   Completion comp = m_script->evaluate(code, thisNode);
>   struct itimerval tv2 = { { 0, 0}, { 0, 0 } };
>   setitimer(ITIMER_VIRTUAL, &tv2, 0L);
>
> seems to work. (Strange, without a interval value, the signal is not
> delivered.) However, this wouldn't fix the infinitely case ;)

Still had this small hack in my tree. Didn't see any problems with it,
so I de-hacked it a little. The attached patch does:
- prevents JS to hang khtml with scripts like 'while(1);',
- asks the user if a script should be terminated after it uses more than a
  predefined time (here 5 seconds), and repeats this question after
  another predefined time (here 2 seconds),
- it only measures CPU time consumed by khtml, so wait for user input or
  Java calls, can't trigger this alarm.

Changing a static bool in KJS::ExecState from a signal handler, is
pretty save imho.

Regards,

Koos Vriezen
-------------- next part --------------
Index: kjs/interpreter.cpp
===================================================================
RCS file: /home/kde/kdelibs/kjs/interpreter.cpp,v
retrieving revision 1.11
diff -u -3 -p -r1.11 interpreter.cpp
--- kjs/interpreter.cpp	2002/06/25 19:13:58	1.11
+++ kjs/interpreter.cpp	2002/08/04 20:48:21
@@ -355,6 +355,7 @@ void ExecState::setException(const Value
 
 void ExecState::clearException()
 {
+  terminate_request = false;
   rep->exception = Value();
 }
 
@@ -363,8 +364,12 @@ Value ExecState::exception() const
   return rep->exception;
 }
 
+bool ExecState::terminate_request = false;
+
 bool ExecState::hadException() const
 {
+  if (terminate_request)
+      rep->exception = Error::create((ExecState*)this);
   return !rep->exception.isNull();
 }
 
Index: kjs/interpreter.h
===================================================================
RCS file: /home/kde/kdelibs/kjs/interpreter.h,v
retrieving revision 1.10
diff -u -3 -p -r1.10 interpreter.h
--- kjs/interpreter.h	2002/06/19 08:21:00	1.10
+++ kjs/interpreter.h	2002/08/04 20:48:21
@@ -390,9 +390,14 @@ namespace KJS {
     Value exception() const;
     bool hadException() const;
 
+    /*
+     * request for ending execution with an exception
+     */
+    static void requestTerminate() { terminate_request = true; }
   private:
     ExecState(Interpreter *interp, ContextImp *con);
     ExecStateImp *rep;
+    static bool terminate_request;
   };
 
 }; // namespace
Index: khtml/ecma/kjs_proxy.cpp
===================================================================
RCS file: /home/kde/kdelibs/khtml/ecma/kjs_proxy.cpp,v
retrieving revision 1.80
diff -u -3 -p -r1.80 kjs_proxy.cpp
--- khtml/ecma/kjs_proxy.cpp	2002/07/28 01:20:32	1.80
+++ khtml/ecma/kjs_proxy.cpp	2002/08/04 20:48:41
@@ -27,6 +27,11 @@
 #include <khtml_part.h>
 #include <kprotocolmanager.h>
 #include <kdebug.h>
+#include <kmessagebox.h>
+#include <klocale.h>
+#include <unistd.h>
+#include <signal.h>
+#include <sys/time.h>
 #include <kjs/collector.h>
 #include <assert.h>
 
@@ -55,6 +60,11 @@ public:
   void applyUserAgent();
 
 private:
+  static void alarmHandler(int) {
+      kdDebug(6070) << "alarmhandler" << endl;
+      if (KMessageBox::warningYesNo(0L, i18n("A script takes a lot of time.\nTerminate it?"), "JavaScript", i18n("OK"), i18n("Cancel")) == KMessageBox::Yes)
+          ExecState::requestTerminate();
+  }
   KJS::ScriptInterpreter* m_script;
   bool m_debugEnabled;
 #ifndef NDEBUG
@@ -134,7 +144,16 @@ QVariant KJSProxyImpl::evaluate(QString 
   KJS::Value thisNode = n.isNull() ? Window::retrieve( m_part ) : getDOMNode(m_script->globalExec(),n);
 
   UString code( str );
+
+  void (*oldAlarmHandler)(int) = signal(SIGVTALRM, KJSProxyImpl::alarmHandler);
+  itimerval oldtv, tv = { { 2, 0 }, { 5, 0 } };
+  setitimer(ITIMER_VIRTUAL, &tv, &oldtv);
+
   Completion comp = m_script->evaluate(code, thisNode);
+
+  setitimer(ITIMER_VIRTUAL, &oldtv, 0L);
+  signal(SIGVTALRM, oldAlarmHandler);
+
   bool success = ( comp.complType() == Normal ) || ( comp.complType() == ReturnValue );
 
 #ifdef KJS_DEBUGGER


More information about the kfm-devel mailing list