The open opcode

Jonathan Leto jaleto at
Fri Apr 23 01:03:44 UTC 2010


> The deeper problem here is that monkeypatching File/FileHandle isn't really
> the right solution to secure I/O.

I totally agree with you, but I prefer to call it "duck punching." ;)

> Allison

I have attached a small patch that allows me to secure PL/Parrot
against the open opcode. It comes at the cost of a single
Parrot_PMC_typenum(interp,"FileHandle") lookup, per call of the open
opcode, which is an extremely tiny performance hit and unbreaks

If you compile Parrot with the attached patch, then run
intercept_io.pir, you will see that all IO calls are properly
intercepted. This script can easily be turned into a test to verify
that the "feature" I am adding works as expected and continues to
work, since PL/Parrot will depend on it.

I fully intend to continue working on improving the security of
Parrot, but this tiny step allows PL/Parrot to be considered for
deployment into production systems and gives Parrot an entirely new
niche to thrive in.

I would greatly appreciate the comments of my fellow Parrot hackers as
to whether this patch (with tests) can be applied.


Jonathan "Duke" Leto
jonathan at
-------------- next part --------------
Index: src/io/api.c
--- src/io/api.c	(revision 45823)
+++ src/io/api.c	(working copy)
@@ -122,25 +122,26 @@
     PMC *new_filehandle, *filehandle;
     INTVAL flags;
+    INTVAL typenum = Parrot_PMC_typenum(interp,"FileHandle");
     if (PMC_IS_NULL(pmc)) {
         /* TODO: We should look up the HLL mapped type, instead of always
            using FileHandle here */
-        new_filehandle = Parrot_pmc_new(interp, enum_class_FileHandle);
-        PARROT_ASSERT(new_filehandle->vtable->base_type == enum_class_FileHandle);
+        new_filehandle = Parrot_pmc_new(interp, typenum);
+        PARROT_ASSERT(new_filehandle->vtable->base_type == typenum);
         new_filehandle = pmc;
     flags = Parrot_io_parse_open_flags(interp, mode);
-    if (new_filehandle->vtable->base_type == enum_class_FileHandle) {
+    if (new_filehandle->vtable->base_type == typenum) {
         /* TODO: StringHandle may have a null path, but a filehandle really
            shouldn't allow that. */
-        PARROT_ASSERT(new_filehandle->vtable->base_type == enum_class_FileHandle);
+        PARROT_ASSERT(new_filehandle->vtable->base_type == typenum);
         filehandle = PIO_OPEN(interp, new_filehandle, path, flags);
         if (PMC_IS_NULL(filehandle))
             Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_PIO_ERROR,
                 "Unable to open filehandle from path '%S'", path);
-        PARROT_ASSERT(filehandle->vtable->base_type == enum_class_FileHandle);
+        PARROT_ASSERT(filehandle->vtable->base_type == typenum);
         SETATTR_FileHandle_flags(interp, new_filehandle, flags);
         SETATTR_FileHandle_filename(interp, new_filehandle, path);
         SETATTR_FileHandle_mode(interp, new_filehandle, mode);
-------------- next part --------------
A non-text attachment was scrubbed...
Name: intercept_io.pir
Type: application/octet-stream
Size: 1170 bytes
Desc: not available
URL: <>

More information about the parrot-dev mailing list