mirror of
https://git.openafs.org/openafs.git
synced 2025-01-31 05:27:44 +00:00
LINUX: Avoid symlink-y resolution limits
Implementing the d_automount or follow_link function pointers for our directories means that we can hit symlink resolution limits during lookup, since we look like a "symlink". We can hit these limits pretty easily if there are just too many directories in the lookup path. Our pseudo-symlink directories cannot contribute to an infinite resolution loop, since our destination is always an actual directory, not a symlink that will result in more redirection. So, decrement the total_link_count counter when our d_automount or follow_link code is reached, so we do not contribute to hitting the max resolution limit. Note that this is not related to recursive symlink lookup (link_count) but only to the iterative symlink limit (total_link_count). Our lookups are not recursive here, and we are not causing more recursive lookups like a normal text-based symlink would do. Change-Id: Id6d2edd614388ac0890eb7591caec25d375964ce Reviewed-on: http://gerrit.openafs.org/8009 Reviewed-by: Derrick Brashear <shadow@your-file-system.com> Tested-by: BuildBot <buildbot@rampaginggeek.com>
This commit is contained in:
parent
b9a10641dd
commit
238b88624a
@ -1257,6 +1257,10 @@ afs_dentry_automount(afs_linux_path_t *path)
|
|||||||
{
|
{
|
||||||
struct dentry *target;
|
struct dentry *target;
|
||||||
|
|
||||||
|
/* avoid symlink resolution limits when resolving; we cannot contribute to
|
||||||
|
* an infinite symlink loop */
|
||||||
|
current->total_link_count--;
|
||||||
|
|
||||||
target = canonical_dentry(path->dentry->d_inode);
|
target = canonical_dentry(path->dentry->d_inode);
|
||||||
|
|
||||||
if (target == path->dentry) {
|
if (target == path->dentry) {
|
||||||
@ -2721,6 +2725,17 @@ afs_linux_dir_follow_link(struct dentry *dentry, struct nameidata *nd)
|
|||||||
struct dentry **dpp;
|
struct dentry **dpp;
|
||||||
struct dentry *target;
|
struct dentry *target;
|
||||||
|
|
||||||
|
if (current->total_link_count > 0) {
|
||||||
|
/* avoid symlink resolution limits when resolving; we cannot contribute to
|
||||||
|
* an infinite symlink loop */
|
||||||
|
/* only do this for follow_link when total_link_count is positive to be
|
||||||
|
* on the safe side; there is at least one code path in the Linux
|
||||||
|
* kernel where it seems like it may be possible to get here without
|
||||||
|
* total_link_count getting incremented. it is not clear on how that
|
||||||
|
* path is actually reached, but guard against it just to be safe */
|
||||||
|
current->total_link_count--;
|
||||||
|
}
|
||||||
|
|
||||||
target = canonical_dentry(dentry->d_inode);
|
target = canonical_dentry(dentry->d_inode);
|
||||||
|
|
||||||
# ifdef STRUCT_NAMEIDATA_HAS_PATH
|
# ifdef STRUCT_NAMEIDATA_HAS_PATH
|
||||||
|
Loading…
x
Reference in New Issue
Block a user