Hardening Information. Anchors do not affect the flow of data in the stream or any other properties of the stream other than to lock down its plumbing. Any process can place an anchor on a stream, but once placed, it can only be removed by a privileged process.
An anchor is a per-stream entity; that is, there is exactly one per stream, and the anchor is moved upstream or downstream as needed. When a stream is created, the anchor is conceptually at the driver and therefore has no effect on the stream. By issuing the I_ANCHOR ioctl on a stream, a process places the anchor at the STREAMS module directly below the stream head. This means that a process can move an existing anchor upstream by pushing additional STREAMS modules and calling I_ANCHOR again.
Although anchors conceptually exist at a specific location in the stream, they are not a data processing element and therefore do not physically exist in the stream (for example, you will not find them parsing q_next pointers.) This means that anchors will not appear in ioctls such as I_LOOK, and they are not included in the module count on the stream.
To remove an anchor, a process pops the module at which the anchor was placed. The anchor will only allow a privileged process to pop modules at or below it, which provides security. Once an anchor has been removed, the anchor is not reset to its previous location in the stream, but rather positioned at the STREAMS driver again. When an unprivileged process attempts to pop an anchored module, the ioctl returns with EPERM.
The I_ANCHOR ioctl is processed completely in the stream head, and is never sent downstream. If a module or driver sends an I_ANCHOR to the stream head, the anchor is silently discarded.