5.2.4 Symlinks
A symlink key uses two mechanisms, and both are load-bearing.
The symlink flag on the key record marks the key's structural type.
It is set at creation by REG_OPTION_CREATE_LINK and is immutable
afterwards.
RSI_WRITE_KEY can update only the descriptor and the last write time,
so there is no operation that could change it.
The default value, of type REG_LINK, supplies the target
path.
It is an ordinary layered value, which means a higher-precedence layer
can redirect a symlink by writing a different REG_LINK default value,
and removing that layer restores the original target.
The flag marks identity; the value provides the target.
5.2.4.1 Resolution #
LCS follows symlinks during path resolution and the fd it returns refers to the resolved target — its GUID, its position in the tree, its ancestor chain — not to the link.
The target is resolved by issuing a separate RSI_QUERY_VALUES for the
key's default value (the empty name) and applying ordinary layer
resolution to the result, so the target participates in the layer
system exactly as any other value does.
If the effective default value is missing, or is not of type
REG_LINK, resolution fails with EINVAL.
LCS does not validate the type at write time: a layer that writes a
REG_SZ default value over a symlink's target breaks resolution at the
next open, and removing that layer fixes it.
The offending value stays in the registry; a failed resolution writes nothing.
5.2.4.2 The target path #
The REG_LINK payload is a length-delimited UTF-8 registry path. No
trailing null is required or permitted — the length delimits it, and a
null byte inside that length is rejected like any
other. Forward
slashes are handled as separators as everywhere else.
The target is validated with exactly the same rules as a syscall path: UTF-8, no null bytes, per-component and total length, no empty components, no trailing separator, maximum depth. The only difference is that a syscall path arrives null-terminated and has its terminator stripped first.
A target is always interpreted as absolute — its first component is routed as a hive name.
Resolution has no check that rejects a relative-looking target as
malformed. A target of Sub\Key is not an error; it is a request for a
hive named Sub, and it yields ENOENT unless such a hive happens to
be registered, in which case it resolves there.
Writing one is different. REG_IOC_SET_VALUE of a REG_LINK value
routes the target's first component at write time, with the writer's
scope GUIDs, and answers EINVAL if it names no registered hive. That
is what stops a dangling target being captured later by whoever
registers a private hive of that name: a target that cannot be written
cannot be captured, and the failure lands on whoever authored it. The
cost is that a symlink cannot forward-reference a hive registered after
it. A target that arrives in source data or a backup stream is not
gated, which is why resolution still has to treat the shape as a hive
request.
CurrentUser\ rewriting is not applied (§5.2.1), so a target beginning
with CurrentUser\ routes as a hive of that name and cannot be
registered, and therefore always fails. Ordinary hive routing does
apply, private hives included, for the resolving thread.
5.2.4.3 Depth #
Symlink resolution is bounded by SymlinkDepthLimit, default 16,
configurable from 1 to 64. Exceeding it is ELOOP.
5.2.4.4 Opening the link itself #
REG_OPEN_LINK on reg_open_key opens the symlink key rather than
following it, which is how a symlink is managed at all — deleted,
retargeted, inspected.
It applies to the final path component only. A symlink encountered part-way along a path is followed whether or not the flag is set.
The access check follows the same rule: with REG_OPEN_LINK the check
is against the link, otherwise against the target.
5.2.4.5 Creation #
Creating a symlink needs all of:
KEY_CREATE_SUB_KEYon the parent, as for any key;KEY_CREATE_LINKon the parent;- either an enabled
SeTcbPrivilegeor membership of Administrators.
The last is a genuine disjunction — either satisfies it — and the privilege branch marks the privilege used.