|Version 2 (modified by rme, 5 years ago)|
On the PPC, there are addressing modes that make it easy to deal with 16-bit constants and 16-bit absolute addresses. CCL exploits this: things like NIL and T are 16-bit constants (and the addresses of things that are mapped into low memory); conditional calls to runtime support routines can use "branch absolute" instructions to call those routines (which are also mapped into the low 16 bits of the address space). Apple uses a similar scheme to reference critical library routines in Mac OS X (since the addressing mode generally involved signed 16-bit addresses, Apple's scheme uses addresses in the high 16 bits of the address space). That sort of thing is what the addressing modes are for, after all.
The Linux kernel provides a feature that can prevent a process from mapping addresses below a certain base address. The idea, apparently, is that this will prevent exploitation of undiscovered null pointer dereference bugs in the kernel.
The parameter in question is called mmap_min_addr; one can cat the file /proc/sys/vm/mmap_min_addr to see what the current setting is.
Some recent Linux distributions (including Fedora 9 and Ubuntu 8) ship with this value set to 65536. This has the effect of preventing processes from accessing the low 64K of their address spaces. Whether this makes sense or not on other architectures is debatable; on the PPC, it means that applications that want to exploit 16-bit PPC addressing are prohibited from doing so. We don't know if anyone involved in this decision thought about this issue or what they concluded if so. It's a little hard to believe that much thought went into that decision.
Fortunately, there are a few workarounds.
Processes running as root are not subject to the restriction. However, it's not reasonable to require rootly powers just to run CCL.
The value of mmap_min_addr can be changed by writing a new value to the file /proc/sys/vm/mmap_min_addr like so:
# echo 4096 >/proc/sys/vm/mmap_min_addr
This will persist only until the system is rebooted.
It should be possible to make a permanent fix by adding the line
to the file /etc/sysctl.conf. (This change will take effect on the next and subsequent reboots.)
The 4K value mentioned above makes it impossible to dereference a NULL pointer, but still allows applications to use low-memory addresses.
On some newer systems (Ubuntu 8.10, for instance), the 4K value doesn't work, although
# echo 0 >/proc/sys/vm/mmap_min_addr
will permit the lisp to run. (Setting this value to 0 doesn't necessarily create an exploitable condition. It might make it possible or easier to exploit yet-to-be-discovered bugs in the Linux kernel.)
On the x86 platform, there's no architectural advantage to using 16-bit addresses (when it's even possible to do so). Version 1.1 of CCL/OpenMCL happened to use very similar/very low addresses (there was no reason not to); 1.2 and later use addresses above 64K (mostly because Windows restricts access to the low 64K for other reasons.)
It might be possible to rearchitect PPC CCL not to exploit this architectural feature, but the thought of doing so is not particularly attractive.