lucy-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Nick Wellnhofer <wellnho...@aevum.de>
Subject Re: [lucy-dev] Trap exceptions from C
Date Mon, 16 Apr 2012 18:48:38 GMT
On 15/04/2012 20:50, Marvin Humphrey wrote:
> Here's the provisional API for the new feature Err#trap:
>
>      /** Run<code>routine</code>  within the host's exception handling
>       * environment, catching and returning any errors that occur.
>       *
>       * If an unrecognized host exception is trapped, it will be wrapped in an
>       * Err so that it can be handled by Clownfish code.
>       *
>       * @return an Err, or NULL if no exception occurs.
>       */
>      public inert incremented nullable Err*
>      trap(cfish_Err_attempt_t routine, void *context);
>
> Here's sample usage, where we use Err#trap to implement a "Safe_Do_Stuff"
> method which traps "MyError" exceptions which might be thrown by "Do_Stuff":
>
>      struct do_stuff_context {
>          Foo        *foo;
>          int64_t     number;
>          const char *string;
>          int64_t     result;
>      };
>
>      static void
>      S_run_do_stuff(void *context) {
>          struct do_stuff_context *args = (struct do_stuff_context*)context;
>          args.result = Foo_Do_Stuff(args->foo, args->number, args->string);
>      }
>
>      int64_t
>      Foo_safe_do_stuff(Foo *self, int64_t number, const char *string) {
>          struct do_stuff_context context;
>          context.foo    = self;
>          context.number = number;
>          context.string = string;
>
>          Err *error = Err_trap(S_run_do_stuff,&context);
>          if (error) {
>              if (Err_Is_A(error, MYERROR)) {
>                  Err_set_error(error);
>                  return -1;
>              }
>              else {
>                  RETHROW(error);
>              }
>          }
>          else {
>              return args.result;
>          }
>      }
>
> Thoughts?

I don't think there's an easier way to do this in C, so +1.

> The one thing I'm not settled about in the provisional implementation is the
> behavior of the XS helper function Err#run, which is where we extract an
> arbitrary C function pointer out of a scalar and run it blindly.
>
>      void
>      run(routine_sv, context_sv)
>          SV *routine_sv;
>          SV *context_sv;
>      PPCODE:
>          IV routine_iv = SvIV(routine_sv);
>          IV context_iv = SvIV(context_sv);
>          cfish_Err_attempt_t routine = INT2PTR(cfish_Err_attempt_t, routine_iv);
>          void *context               = INT2PTR(void*, context_iv);
>          routine(context);
>
> I'm concerned that there might be an attack vector where a malicious user gets
> shellcode into a scalar somewhere (easy), and then gets the first argument to
> Err#run to point at it (hard, I think).  I haven't yet figured out how to
> complete that attack, though.  Anybody see a problem?

Hmm, it seems that we can't we use the XCPT_* macros. But I think you 
can create an anonymous XSUB by passing NULL as name argument to newXS 
and using the return value.

Nick

Mime
View raw message