Fork me on GitHub
Jon Bringhurst

5 Apr 2011

Preventing delete of has_many children in Rails 3

If you’ve tried to use rails 3 validate on a destroy, you might notice that error messages which were set in the before_destroy don’t get passed back to the user.

It seems like many people out there have posted code that tries to tell you that you can set the record.errors in the model. Well, let me tell you that it doesn’t work for various reasons.

Here’s an example of a workaround I’m using where a building contains many rooms.

As you can see, an RecordInvalid is thrown from the model and caught in the controller. Then, in the controller, the flash is set to the error message.

3 Mar 2011

Space filling curves as interconnection topology

I haven’t been able to find much information on how space filling curves, like Hilbert curves, are used in network interconnection topology in supercomputers. So, this post is my attempt at putting the information in one place. We’ll start off with an introduction to gray encoding and how it relates to Hilbert curves.

So, gray codes are the concept of the day here. Gray codes are just another binary representation of integer counting (1, 2, 3, 4, 5, …). They were used back in the day for mechanical counting because of a key property — only one bit changes for every value that a gray code is incremented or decremented. This made it simple for a sensor to tell when the value had changed because only one bit would be flipped every time. This is in contrast to normal binary counting where it’s common for multiple bits to be flipped for every time the value is incremented or decremented which makes it difficult to tell if the bits have all completely flipped into their final state.

Gray codes also have another special property. Some people like to call gray codes “reflected binary codes”. This property makes the generation of gray codes feel very similar to the generation of a fractal. For example, start off with the one bit gray codes — you have 0 and 1. Now, to get two bit gray codes, you write it forwards and backwards (0, 1, 1, 0). Then, prepend 0s to the first half of the numbers and 1s to the second half of the numbers (00, 01, 11, 10) and you end up with the two bit gray codes. To get the n-bit gray codes, you repeat the process n times from the base case.

Now the cool stuff. Gray codes have yet another story to tell. You can use gray codes to reference a coordinate in a space filling curve known as a “Hilbert Curve”. Ignore the word “curve” for now — it’s just going to confuse you. If you’re like most people, you’re going to think of a curve as a smooth turn on a roller coaster or the shape of a hot air balloon. You’ll think of Hilbert curves like that eventually, but not now. Right now, you can safely think of Hilbert curves in appearance as similar to the maze puzzles on a paper placemat from a roadside greasy spoon that you solved with a wax crayon as a child.

So, how do you use gray codes to reference locations in Hilbert curves? Lets start off with the two bit gray codes. Just use each value like an x-y coordinate. So, we have the coordinates of (0, 0), (0, 1), (1, 1), (1, 0) as our first order Hilbert curve.


                     (0, 1)  *---------*  (1, 1)
                             |         |
                             |         |
                             |         |
                             |         |
                     (0, 0)  *         *  (1, 0)

Now, lets try to do the second order Hilbert curve using the four bit gray codes. To do this, we need to utilize the fractal properties of the Hilbert curve. Each coordinate in the first order Hilbert curve needs to be replaced by a new sub-curve that is the same shape as the first order curve. This new sub-curve will be translated and rotated to fit in with the design of the first order Hilbert curve. Once each of the coordinates has been replaced, we end up with a second order Hilbert curve.


                      *-------*       *-------*
                      |       |       |       |
                      |       |       |       |
                      |       |       |       |
                      *       *-------*       *
                      |                       |
                      |                       |
                      |                       |
                      *-------*       *-------*
                              |       |
                              |       | 
                              |       |
                      *-------*       *-------*

To address each of the coordinates in the second order Hilbert curve with gray codes, we need to reference the original location of the coordinate that was replaced by the sub-curve. So, for example, the lower-right corner in the second order Hilbert curve has a gray code with bits that start with “10…”. We can then get the rest of the gray code by again picturing the single order Hilbert curve and rotating the visualization and then referencing that same point after rotations in the lower order. So, the remaining part of the code is “00” — which makes the code for the lower-right corner “1000”. Using the same concept, you can use a gray code to find the location in a Hilbert curve.

Now, how does the conversion from gray codes to Hilbert graphs and back actually help us when it comes to network topology? Lets look at a third order Hilbert curve for some perspective.


                    *---*   *---*   *---*   *---*
                    |   |   |   |   |   |   |   |
                    *   *---*   *   *   *---*   *
                    |           |   |           |
                    *---*   *---*   *---*   *---*
                        |   |           |   |
                    *---*   *---*---*---*   *---*
                    |                           |
                    *   *---*---*   *---*---*   *
                    |   |       |   |       |   |
                    *---*   *---*   *---*   *---*
                       (3)  |  (7)      |
                (2) *---*   *---*   *---*   *---*
                    |   |       |   |       |   |
                (1) *   *---*---*   *---*---*   *
                       (4) (5) (6)

Start from the lower left corner of the curve and start ordering each coordinate as you go along. As you pass each coordinate, calculate a rough estimate of the physical difference in distance between each coordinate. You’ll find that as you go, coordinates that are close to each other tend to also be close to each other in their ordering. The number of each coordinate as you go along and give each a value is known as the “Hilbert integer”.

Now that we have a bit of a base, we can try to relate this to interconnection topology. First things first, we need to have a picture of a 3 dimensional Hilbert curve. So, instead of filling up a 2 dimensional space through each order of the curve, we fill up a 3 dimensional space by adding a rotation into the third dimension to each translate and rotation in 2 dimensional space.


                           *       *
                           |\      |
                           | \     |
                           |  *    |  *
                           |  |    |  |
                           *-------*  |
                              |       |
                              |       |
                              *-------*

Now that we have a topology that closely resembles the node structure in a 3D torus network structure, we can start thinking about how nodes are allocated.

Remember the concept of a Hilbert integer? That’s going to be the node ID of every node in the supercomputer. When the Hilbert integers of each node are generated, they’re stored by the central resource manager and stored for the duration of the resource manager’s lifecycle. After being sorted into a one dimensional array, the node IDs can then be effectively used by a scheduler to provide resources to jobs at a level of abstraction where the scheduler doesn’t need to worry about the actual node topology.

24 Jan 2011

A simple gluUnProject Port for Javascript WebGL Applications

I just created a new github project with a standalone version of my Javascript gluUnProject port. Everything that’s not owned by SGI is under a public domain license. There are no dependencies on Google Closure or Lanyard.

http://github.com/fintler/webgl-unproject

If you’re interested in an example, you can see it in action at http://github.com/fintler/lanyard in the lanyard.BasicOrbitView object.

20 Dec 2010

Star Trek Red Shirt Gingerbread Man Cookie Cutter

FoxTrot recently posted a comic that features a redshirt as a gingerbread cookie. I figure, what the heck — I’m going make some real ones.

The first step is making the cookie cutter. I took a trip to the local big box hardware store and ended up grabbing some aluminium roofing trim that I could easily slice up with a pair of old scissors. It cost $2 for 10 feet of it (I only ended up using like 2 feet).

The next step was to plan out what I wanted the cookies to look like. I whipped up a little image that I thought was appropriate.

Then, I got to work with the scissors and cut the aluminium into strips. I ended up using a pair of pliers for the tricky edges. With a little bit of effort (and taking care not to slice up my hands) the cutter starts to take shape.

After finishing that up, I added a few scrap pieces for support and put everything together with plain old clear packaging tape.

As I type this, I’m waiting for the gingerbread dough to chill in my fridge. I’ll make sure I post the results soon.

17 Nov 2010

Introducing a Completely Javascript 3D Map - Lanyard

GIS on the web is going to hit a new level of awesome soon. I’ve been working on an entirely-written-in-Javascript 3D map for a bit now. It’s based on Closure Tools and NASA’s Worldwind and uses WebGL for hardware acceleration.

A few minutes ago, I just managed to get the tiled blue marble layer working. Here’s a screenshot of the results:

Or, if you have a WebGL enabled browser, take a look at the live demo (It’s buggy, click-to-drag doesn’t work well. Try out the mouse-scroll-wheel-zoom for some nifty tile disappearing and reappearing action based on the zoom level.) :

http://github.bringhurst.org/lanyard-pre-demo-2

Lastly, if you’re a developer, take a look at the source on my github. I *heart* patches.

22 Sep 2010

WebGL Ignite Presentation

Here’s a copy of the presentation I’m doing for Ignite NM tonight. Enjoy.

30 Apr 2010

Java bug in Safari

Back in April of 2008, when I was still at Temple, I took a non-CS major class on security. In addition to creating a nifty little utility to bring an xnu kernel to its knees, I also did some work with fuzz testing web browsers. I ended up coming across a nice little bug in the width attribute of an applet tag. In the interest of full disclosure, I think it’s time to finally put this in public. This is the email I sent Apple:

Date: Sun, 4 May 2008 12:47:26 -0400
From: “Jonathan Bringhurst”
To: product-security@apple.com
Subject: integer overflow in safari, controlled null write to heap

Hey Apple Security People,

There’s a little problem with safari and java. Here an example…

“<META HTTP-EQUIV=”Refresh” content=”0;URL=blah.html”><APPLET WIDTH=”129999999” CODE=”aaaaaa.class”>”

This leads to a fault…

“Invalid memory access of location b254b000 eip=26730fb0

Program received signal EXC_BAD_ACCESS, Could not access memory.
Reason: KERN_INVALID_ADDRESS at address: 0xb254b000
[Switching to process 2677 thread 0x1d703]
0x26730fb0 in AnyIntSetRect ()”

It seems to be an integer overflow in this loop inside AnyIntSetRect()…

0x26730fb0 <AnyIntSetRect+64>: mov %edi,(%edx,%eax,4)
0x26730fb3 <AnyIntSetRect+67>: inc %eax
0x26730fb4 <AnyIntSetRect+68>: cmp %eax,%esi
0x26730fb6 <AnyIntSetRect+70>: ja 0x26730fb0 <AnyIntSetRect+64>

As you can see, eax gets blown up. Since it seems we can control the edx base, it’s trivial to do wild null writes into the heap. With some additional trickery, we’re able to control exactly where those nulls stop and get some priv escalation (think overwriting a euid, but instead modifying js privs).

Although it may seem like this is the java team’s fault, there really
should be a sanity check in safari for this.

Here’s their (relatively) quick response:

From: product-security@apple.com
To: jon@nospam-bringhurst.org
Subject: Re: integer overflow in safari, controlled null write to heap
Date: Tue, 6 May 2008 09:39:25 -0700 (PDT)

Please include the line below in follow-up emails for this request.

Follow-up: 47541419

Hello,

Thank you for forwarding this issue to us. We take any report of a potential security issue very seriously.

You should have already received our automated response message. This message is being sent to you by a security analyst who has reviewed your note. The issue is being investigated, and we appreciate the time you have taken to report it to us. If we need additional information, you will hear from us very soon.

Because of the potentially sensitive nature of security vulnerabilities, we ask that this information remain between you and Apple while we investigate it further.

You’ll notice a number at the top of this email. Including that number in any further emails you send to us on this issue will help us rapidly associate it with your original report.

We do not automatically provide status updates on issues as we work on them, but please feel free to request one if needed by replying to this message.

Best regards,

Apple Product Security team
http://www.apple.com/support/security/
PGP Key ID: 0xB8469E6D
Fingerprint: FD20 40DB F7BC 37B9 6E78 4C3B C800 A2AB B846 9E6D

Finally, only a few days ago, I received this email:

From: product-security@apple.com
To: jon@nospam-bringhurst.org
Subject: Re: integer overflow in safari, controlled null write to heap
Date: Wed, 14 Apr 2010 14:40:16 -0700 (PDT)

Please include the line below in follow-up emails for this request.

Follow-up: 47541419

Hello,

When we address an issue in a Security Update, we like to give credit to the person who reported the issue to us. The information is typically in the following format:

Credit to <Person> of <Company or School or Agency> for reporting this issue.

You can see examples of this at http://support.apple.com/kb/HT1222

Would you please let us know if you would like to be credited, and the information you would like us to use?

Thanks.
Mihaela

Apple Product Security team
http://www.apple.com/support/security/
PGP Key ID: 0xDB539AED
Fingerprint: 4B55 5F62 FAE8 BC41 BA9A 4D70 89B3 3F9F DB53 9AED

I take it that since they’re ready to release a patch (after two years of development that must be an AWESOME patch), it’s time to finally put all of this out there in public.

30 Apr 2010

Checking out multiple projects in one subversion repo

If you’ve ever had to deal with a subversion repository with multiple projects that all have separate “trunk”, “branches”, and “tags”, you may find this script quite useful.

To use it, you can specify multiple project names and the tag or branch that you want to check out for each of them. If no flags are specified, it’ll default to checking out from trunk.

I’ve been using this on a daily basis for a little while and I think I’ve weeded out most of the obvious bugs.