pivot_root(new_root, put_old) moves old root directory of the calling process (which must be a root of a mount) onto put_old, and puts new_root in it's place. It then sets the current directory and root of every process that was set to the old root directory to new_root.
So after pivot_root(".", ".") the new root directory has old root directory mounted on top of it.
Whenever .. would otherwise resolve to directory that has another directory mounted on it, it actually resolves to the directory that is mounted on top. This match historic Unix and Linux behaviour where .., except at the root directory of a filesystem, had no special handling in path traversal and was implemented by a directory entry stored on the disk.
This is not a mount namespace escape.