fd-util: skip to check mount ID if kernel is too old and /proc is not mounted
Now, dir_fd_is_root() is heavily used in chaseat(), which is used at various places. If the kernel is too old and /proc is not mounted, then there is no way to get the mount ID of a directory. In that case, let's silently skip the mount ID check. Fixes https://github.com/systemd/systemd/pull/27299#issuecomment-1511403680.
This commit is contained in:
+15
-7
@@ -911,10 +911,23 @@ int dir_fd_is_root(int dir_fd) {
|
||||
if (!statx_inode_same(&st.sx, &pst.sx))
|
||||
return false;
|
||||
|
||||
/* Even if the parent directory has the same inode, the fd may not point to the root directory "/",
|
||||
* and we also need to check that the mount ids are the same. Otherwise, a construct like the
|
||||
* following could be used to trick us:
|
||||
*
|
||||
* $ mkdir /tmp/x /tmp/x/y
|
||||
* $ mount --bind /tmp/x /tmp/x/y
|
||||
*
|
||||
* Note, statx() does not provide the mount ID and path_get_mnt_id_at() does not work when an old
|
||||
* kernel is used without /proc mounted. In that case, let's assume that we do not have such spurious
|
||||
* mount points in an early boot stage, and silently skip the following check. */
|
||||
|
||||
if (!FLAGS_SET(st.nsx.stx_mask, STATX_MNT_ID)) {
|
||||
int mntid;
|
||||
|
||||
r = path_get_mnt_id_at(dir_fd, "", &mntid);
|
||||
if (r == -ENOSYS)
|
||||
return true; /* skip the mount ID check */
|
||||
if (r < 0)
|
||||
return r;
|
||||
assert(mntid >= 0);
|
||||
@@ -927,6 +940,8 @@ int dir_fd_is_root(int dir_fd) {
|
||||
int mntid;
|
||||
|
||||
r = path_get_mnt_id_at(dir_fd, "..", &mntid);
|
||||
if (r == -ENOSYS)
|
||||
return true; /* skip the mount ID check */
|
||||
if (r < 0)
|
||||
return r;
|
||||
assert(mntid >= 0);
|
||||
@@ -935,13 +950,6 @@ int dir_fd_is_root(int dir_fd) {
|
||||
pst.nsx.stx_mask |= STATX_MNT_ID;
|
||||
}
|
||||
|
||||
/* Even if the parent directory has the same inode, the fd may not point to the root directory "/",
|
||||
* and we also need to check that the mount ids are the same. Otherwise, a construct like the
|
||||
* following could be used to trick us:
|
||||
*
|
||||
* $ mkdir /tmp/x /tmp/x/y
|
||||
* $ mount --bind /tmp/x /tmp/x/y
|
||||
*/
|
||||
return statx_mount_same(&st.nsx, &pst.nsx);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user