You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
change: Get mode before +x using open file descriptor, not path
This uses `fstat` rather than a method that delegates to `lstat`,
to get the current mode bits of the still-open file using the open
file descriptor (obtained from the `File` object) rather than
opening the path, which could be a different file in the case of
concurrent modification by code outside gitoxide.
This is half of the change to using the file descriptor rather than
the path for the operations that adjust the mode by adding
executable bitsi. (As before, they are added for whoever already
had read bits, and we remove setuid, setgid, and sticky bits, so
that +x does not cause a security problem or other potentially
unexpected effects.)
The other half of this change was already done, appearing in a
recent `change:` commit. It consisted of setting the mode using
`fchmod` instead of a method that delegated to `chmod`. With only
that change, the overall effect would be worse, since possible
race conditions could introduce even greater inconsistency. With
both changes, the effect is consistent. Race conditions can still
occur, but their effect is probably less severe than before either
of the changes were made.
One of the ways this may be less subject to race conditions is
that, because neither obtaining the old mode nor setting the new
one uses a path, but only the open file descriptor, an unexpected
typechange will not occur: having opened a regular file, the open
file will not turn into a directory, symlink, or anything else,
*as seen by* the open file descriptor. The file may be moved or
replaced, but the open file descriptor "follows" the move and does
not alias the separate file that now has the original path.
Because we only intend to add executable bits to regular files, it
is no longer necessary to handle this as a race condition and keep
going. Attempting to add +x to any other type of thing should now
only be possible if there is a bug in the caller. So the check for
that, and the associated Option<...> logic used to keep things
testable, is not needed.
This still does the check, but panics if the file descriptor does
not represent a regular file. The tests of this are mostly removed,
but two tests that it does panic for the kinds of non-regular files
we are most likely to encounter are added. (It may eventually make
sense check this and panic only in debug builds, or not at all.)
There are now two `fstat` calls: the one that is added to check the
`st_mode` to figure out what to pass to `fchmod`, and the
preexisting higher level invocation (that delegates to `fstat`)
done just before closing the file, to update `entry.stat`. Using
the same call for both and accounting for any effect of `fchmod`
might be more complicated, but more importantly, it does not seem
like it would be correct. If attempting to set the permissions
reports success but has an unexpected effect, perhaps due to
restrictions of the underlying filesystem or how it is mounted
(which we may not be guarnateed to have detected in a probe to
decide if +x is supported), we would want the real stat.
Because this no longer uses `Permissions` and `PermissionsExt`
facilities to check the mode before adding executable bits or to
add the executable bits, it also includes some refactoring that is
possible now that they are not being used.
0 commit comments