[Inform mntce] Glulx print_to_array patch

Andrew Plotkin erkyrath at eblong.com
Sat Nov 7 17:51:39 GMT 2009


I posted on RAIF yesterday about an annoying hole in the way 
print_to_array is implemented (at the veneer level).

Basically, in Z-code it took one argument (address). In Glulx, for safety, 
I implemented it with two arguments (address, length). But I still 
supported the old one-arg form, by allowing the array length to default to
0x7FFFFFFF.

The one-arg form works most of the time, as long as the game doesn't 
overflow the array. However:

- It's a security hole; a malicious game could overflow VM memory.
- It fails on some Glk libraries on some machines, due to 32-bit address
   math overflowing. See the "Rover's Day Out" thread.

I would like to shut this down, at the cost of some backwards 
compatibility. I figure that's better than flaky behavior. With the 
attached patch, calling string.print_to_array(a) on Glulx generates:

[** Programming error: tried to call Glulx print_to_array with only one 
argument **]

(Note that the two-argument form is legal in Z-code, although the length 
argument is ignored. So we'd want to tell people to always use two 
arguments.)

On the other end, I will also patch Glulxe to reject the case where the 
length overflows VM memory. (See 
<http://github.com/erkyrath/glulxe/tree/arraylimit>.) So the error will be 
caught by both the compiler and the interpreter.

What I don't know is how many existing games will be affected by this. 
Neither the I6 nor I7 libraries use string.print_to_array at all, so I 
expect the number is small. But obviously not zero; and I haven't looked 
at the I7 extension library.

--Z

-- 
"And Aholibamah bare Jeush, and Jaalam, and Korah: these were the borogoves..."
*
-------------- next part --------------
diff --git a/veneer.c b/veneer.c
index 745f70b..bfa44e3 100644
--- a/veneer.c
+++ b/veneer.c
@@ -1045,8 +1045,7 @@ static VeneerRoutine VRs_g[VENEER_ROUTINES] =
                  @copy sp len;\
                }\
                else {\
-                 @copy sp m;\
-                 len = $7FFFFFFF;\
+                 RT__Err(37); rfalse;\
                }\
                s2 = glk($0048);\
                s = glk($0043, m+4, len-4, 1, 0);",
@@ -1393,7 +1392,9 @@ static VeneerRoutine VRs_g[VENEER_ROUTINES] =
          if (crime == 35) \"tried to print (string) on something not a \",\
          \"string **]\";\
          if (crime == 36) \"tried to print (object) on something not an \",\
-         \"object or class **]\";",
+         \"object or class **]\";\
+         if (crime == 37) \"tried to call Glulx print_to_array with only \",\
+         \"one argument **]\";",
         "if (crime < 32) { print \"tried to \";\
          if (crime >= 28) { if (crime==28 or 29) print \"read from \";\
          else print \"write to \";\


More information about the Inform-maintenance mailing list