Next: , Previous: Exchanging Port Rights, Up: Messaging Interface

4.2.4 Memory

A message body can contain the address of a region in the sender's address space which should be transferred as part of the message. The message carries a logical copy of the memory, but the kernel uses VM techniques to defer any actual page copies. Unless the sender or the receiver modifies the data, the physical pages remain shared.

An out-of-line transfer occurs when the data's type descriptor specifies msgt_inline as FALSE. The address of the memory region (a vm_offset_t or vm_address_t) should follow the type descriptor in the message body. The type descriptor and the address contribute to the message's size (send_size, msgh_size). The out-of-line data does not contribute to the message's size.

The name, size, and number fields in the type descriptor describe the type and length of the out-of-line data, not the in-line address. Out-of-line memory frequently requires long type descriptors (mach_msg_type_long_t), because the msgt_number field is too small to describe a page of 4K bytes.

Out-of-line memory arrives somewhere in the receiver's address space as new memory. It has the same inheritance and protection attributes as newly vm_allocate'd memory. The receiver has the responsibility of deallocating (with vm_deallocate) the memory when it is no longer needed. Security-conscious receivers should exercise caution when using out-of-line memory from untrustworthy sources, because the memory may be backed by an unreliable memory manager.

Null out-of-line memory is legal. If the out-of-line region size is zero (for example, because msgtl_number is zero), then the region's specified address is ignored. A received null out-of-line memory region always has a zero address.

Unaligned addresses and region sizes that are not page multiples are legal. A received message can also contain memory with unaligned addresses and funny sizes. In the general case, the first and last pages in the new memory region in the receiver do not contain only data from the sender, but are partly zero.1 The received address points to the start of the data in the first page. This possibility doesn't complicate deallocation, because vm_deallocate does the right thing, rounding the start address down and the end address up to deallocate all arrived pages.

Out-of-line memory has a deallocate option, controlled by the msgt_deallocate bit. If it is TRUE and the out-of-line memory region is not null, then the region is implicitly deallocated from the sender, as if by vm_deallocate. In particular, the start and end addresses are rounded so that every page overlapped by the memory region is deallocated. The use of msgt_deallocate effectively changes the memory copy into a memory movement. In a received message, msgt_deallocate is TRUE in type descriptors for out-of-line memory.

Out-of-line memory can carry port rights.


[1] Sending out-of-line memory with a non-page-aligned address, or a size which is not a page multiple, works but with a caveat. The extra bytes in the first and last page of the received memory are not zeroed, so the receiver can peek at more data than the sender intended to transfer. This might be a security problem for the sender.