diff options
-rw-r--r-- | fs/namei.c | 10 | ||||
-rw-r--r-- | include/linux/namei.h | 1 |
2 files changed, 10 insertions, 1 deletions
diff --git a/fs/namei.c b/fs/namei.c index b638c9cd6d4c..7fd801af7e50 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -867,13 +867,21 @@ static int nd_jump_root(struct nameidata *nd) */ int nd_jump_link(struct path *path) { + int error = -ELOOP; struct nameidata *nd = current->nameidata; - path_put(&nd->path); + if (unlikely(nd->flags & LOOKUP_NO_MAGICLINKS)) + goto err; + + path_put(&nd->path); nd->path = *path; nd->inode = nd->path.dentry->d_inode; nd->flags |= LOOKUP_JUMPED; return 0; + +err: + path_put(path); + return error; } static inline void put_link(struct nameidata *nd) diff --git a/include/linux/namei.h b/include/linux/namei.h index c42a1924ad67..f8acec81cf03 100644 --- a/include/linux/namei.h +++ b/include/linux/namei.h @@ -41,6 +41,7 @@ enum {LAST_NORM, LAST_ROOT, LAST_DOT, LAST_DOTDOT, LAST_BIND}; /* Scoping flags for lookup. */ #define LOOKUP_NO_SYMLINKS 0x010000 /* No symlink crossing. */ +#define LOOKUP_NO_MAGICLINKS 0x020000 /* No nd_jump_link() crossing. */ extern int path_pts(struct path *path); |