openwrt/staging/blogic.git
9 years agoenable passing fast relative symlinks without dropping out of RCU mode
Al Viro [Sat, 9 May 2015 22:15:21 +0000 (18:15 -0400)]
enable passing fast relative symlinks without dropping out of RCU mode

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
9 years agoVFS/namei: make the use of touch_atime() in get_link() RCU-safe.
NeilBrown [Mon, 23 Mar 2015 02:37:40 +0000 (13:37 +1100)]
VFS/namei: make the use of touch_atime() in get_link() RCU-safe.

touch_atime is not RCU-safe, and so cannot be called on an RCU walk.
However, in situations where RCU-walk makes a difference, the symlink
will likely to accessed much more often than it is useful to update
the atime.

So split out the test of "Does the atime actually need to be updated"
into  atime_needs_update(), and have get_link() unlazy if it finds that
it will need to do that update.

Signed-off-by: NeilBrown <neilb@suse.de>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
9 years agonamei: don't unlazy until get_link()
Al Viro [Sat, 9 May 2015 17:04:24 +0000 (13:04 -0400)]
namei: don't unlazy until get_link()

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
9 years agonamei: make unlazy_walk and terminate_walk handle nd->stack, add unlazy_link
Al Viro [Sat, 9 May 2015 16:55:43 +0000 (12:55 -0400)]
namei: make unlazy_walk and terminate_walk handle nd->stack, add unlazy_link

We are almost done - primitives for leaving RCU mode are aware of nd->stack
now, a new primitive for going to non-RCU mode when we have a symlink on hands
added.

The thing we are heavily relying upon is that *any* unlazy failure will be
shortly followed by terminate_walk(), with no access to nameidata in between.
So it's enough to leave the things in a state terminate_walk() would cope with.

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
9 years agonamei: store seq numbers in nd->stack[]
Al Viro [Fri, 8 May 2015 17:23:53 +0000 (13:23 -0400)]
namei: store seq numbers in nd->stack[]

we'll need them for unlazy_walk()

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
9 years agonew helper: __legitimize_mnt()
Al Viro [Fri, 8 May 2015 15:43:53 +0000 (11:43 -0400)]
new helper: __legitimize_mnt()

same as legitimize_mnt(), except that it does *not* drop and regain
rcu_read_lock; return values are
0  =>  grabbed a reference, we are fine
1  =>  failed, just go away
-1 =>  failed, go away and mntput(bastard) when outside of rcu_read_lock

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
9 years agonamei: make may_follow_link() safe in RCU mode
Al Viro [Fri, 8 May 2015 00:37:40 +0000 (20:37 -0400)]
namei: make may_follow_link() safe in RCU mode

We *can't* call that audit garbage in RCU mode - it's doing a weird
mix of allocations (GFP_NOFS, immediately followed by GFP_KERNEL)
and I'm not touching that... thing again.

So if this security sclero^Whardening feature gets triggered when
we are in RCU mode, tough - we'll fail with -ECHILD and have
everything restarted in non-RCU mode.  Only to hit the same test
and fail, this time with EACCES and with (oh, rapture) an audit spew
produced.

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
9 years agonamei: make put_link() RCU-safe
Al Viro [Fri, 8 May 2015 00:32:22 +0000 (20:32 -0400)]
namei: make put_link() RCU-safe

very simple - just make path_put() conditional on !RCU.
Note that right now it doesn't get called in RCU mode -
we leave it before getting anything into stack.

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
9 years agonew helper: free_page_put_link()
Al Viro [Thu, 7 May 2015 15:19:14 +0000 (11:19 -0400)]
new helper: free_page_put_link()

similar to kfree_put_link()

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
9 years agoswitch ->put_link() from dentry to inode
Al Viro [Thu, 7 May 2015 15:14:26 +0000 (11:14 -0400)]
switch ->put_link() from dentry to inode

only one instance looks at that argument at all; that sole
exception wants inode rather than dentry.

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
9 years agosecurity: make inode_follow_link RCU-walk aware
NeilBrown [Mon, 23 Mar 2015 02:37:39 +0000 (13:37 +1100)]
security: make inode_follow_link RCU-walk aware

inode_follow_link now takes an inode and rcu flag as well as the
dentry.

inode is used in preference to d_backing_inode(dentry), particularly
in RCU-walk mode.

selinux_inode_follow_link() gets dentry_has_perm() and
inode_has_perm() open-coded into it so that it can call
avc_has_perm_flags() in way that is safe if LOOKUP_RCU is set.

Calling avc_has_perm_flags() with rcu_read_lock() held means
that when avc_has_perm_noaudit calls avc_compute_av(), the attempt
to rcu_read_unlock() before calling security_compute_av() will not
actually drop the RCU read-lock.

However as security_compute_av() is completely in a read_lock()ed
region, it should be safe with the RCU read-lock held.

Signed-off-by: NeilBrown <neilb@suse.de>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
9 years agosecurity/selinux: pass 'flags' arg to avc_audit() and avc_has_perm_flags()
NeilBrown [Mon, 23 Mar 2015 02:37:39 +0000 (13:37 +1100)]
security/selinux: pass 'flags' arg to avc_audit() and avc_has_perm_flags()

This allows MAY_NOT_BLOCK to be passed, in RCU-walk mode, through
the new avc_has_perm_flags() to avc_audit() and thence the slow_avc_audit.

Signed-off-by: NeilBrown <neilb@suse.de>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
9 years agonamei: pick_link() callers already have inode
Al Viro [Thu, 7 May 2015 23:54:34 +0000 (19:54 -0400)]
namei: pick_link() callers already have inode

no need to refetch (and once we move unlazy out of there, recheck ->d_seq).

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
9 years agoVFS: Handle lower layer dentry/inode in pathwalk
David Howells [Wed, 6 May 2015 14:59:00 +0000 (15:59 +0100)]
VFS: Handle lower layer dentry/inode in pathwalk

Make use of d_backing_inode() in pathwalk to gain access to an
inode or dentry that's on a lower layer.

Signed-off-by: David Howells <dhowells@redhat.com>
9 years agonamei: store inode in nd->stack[]
Al Viro [Thu, 7 May 2015 13:21:14 +0000 (09:21 -0400)]
namei: store inode in nd->stack[]

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
9 years agonamei: don't mangle nd->seq in lookup_fast()
Al Viro [Tue, 5 May 2015 13:40:46 +0000 (09:40 -0400)]
namei: don't mangle nd->seq in lookup_fast()

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
9 years agonamei: explicitly pass seq number to unlazy_walk() when dentry != NULL
Al Viro [Tue, 5 May 2015 13:26:05 +0000 (09:26 -0400)]
namei: explicitly pass seq number to unlazy_walk() when dentry != NULL

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
9 years agolink_path_walk: use explicit returns for failure exits
Al Viro [Sat, 9 May 2015 20:54:45 +0000 (16:54 -0400)]
link_path_walk: use explicit returns for failure exits

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
9 years agonamei: lift terminate_walk() all the way up
Al Viro [Fri, 8 May 2015 22:05:21 +0000 (18:05 -0400)]
namei: lift terminate_walk() all the way up

Lift it from link_path_walk(), trailing_symlink(), lookup_last(),
mountpoint_last(), complete_walk() and do_last().  A _lot_ of
those suckers merge.

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
9 years agonamei: lift link_path_walk() call out of trailing_symlink()
Al Viro [Fri, 8 May 2015 21:37:07 +0000 (17:37 -0400)]
namei: lift link_path_walk() call out of trailing_symlink()

Make trailing_symlink() return the pathname to traverse or ERR_PTR(-E...).
A subtle point is that for "magic" symlinks it returns "" now - that
leads to link_path_walk("", nd), which is immediately returning 0 and
we are back to the treatment of the last component, at whereever the
damn thing has left us.

Reduces the stack footprint - link_path_walk() called on more shallow
stack now.

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
9 years agonamei: path_init() calling conventions change
Al Viro [Fri, 8 May 2015 21:19:59 +0000 (17:19 -0400)]
namei: path_init() calling conventions change

* lift link_path_walk() into callers; moving it down into path_init()
had been a mistake.  Stack footprint, among other things...
* do _not_ call path_cleanup() after path_init() failure; on all failure
exits out of it we have nothing for path_cleanup() to do
* have path_init() return pathname or ERR_PTR(-E...)

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
9 years agonamei: get rid of nameidata->base
Al Viro [Mon, 11 May 2015 12:05:05 +0000 (08:05 -0400)]
namei: get rid of nameidata->base

we can do fdput() under rcu_read_lock() just fine; all we need to take
care of is fetching nd->inode value first.

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
9 years agonamei: split off filename_lookupat() with LOOKUP_PARENT
Al Viro [Fri, 8 May 2015 20:59:20 +0000 (16:59 -0400)]
namei: split off filename_lookupat() with LOOKUP_PARENT

new functions: filename_parentat() and path_parentat() resp.

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
9 years agonamei: may_follow_link() - lift terminate_walk() on failures into caller
Al Viro [Fri, 8 May 2015 20:38:31 +0000 (16:38 -0400)]
namei: may_follow_link() - lift terminate_walk() on failures into caller

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
9 years agonamei: take increment of nd->depth into pick_link()
Al Viro [Sun, 10 May 2015 15:50:01 +0000 (11:50 -0400)]
namei: take increment of nd->depth into pick_link()

Makes the situation much more regular - we avoid a strange state
when the element just after the top of stack is used to store
struct path of symlink, but isn't counted in nd->depth.  This
is much more regular, so the normal failure exits, etc., work
fine.

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
9 years agonamei: kill nd->link
Al Viro [Wed, 6 May 2015 20:01:56 +0000 (16:01 -0400)]
namei: kill nd->link

Just store it in nd->stack[nd->depth].link right in pick_link().
Now that we make sure of stack expansion in pick_link(), we can
do so...

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
9 years agomay_follow_link(): trim arguments
Al Viro [Wed, 6 May 2015 19:58:18 +0000 (15:58 -0400)]
may_follow_link(): trim arguments

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
9 years agonamei: move bumping the refcount of link->mnt into pick_link()
Al Viro [Tue, 5 May 2015 14:52:35 +0000 (10:52 -0400)]
namei: move bumping the refcount of link->mnt into pick_link()

update the failure cleanup in may_follow_link() to match that.

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
9 years agonamei: fold put_link() into the failure case of complete_walk()
Al Viro [Fri, 8 May 2015 20:28:42 +0000 (16:28 -0400)]
namei: fold put_link() into the failure case of complete_walk()

... and don't open-code unlazy_walk() in there - the only reason
for that is to avoid verfication of cached nd->root, which is
trivially avoided by discarding said cached nd->root first.

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
9 years agonamei: take the treatment of absolute symlinks to get_link()
Al Viro [Sun, 10 May 2015 15:01:00 +0000 (11:01 -0400)]
namei: take the treatment of absolute symlinks to get_link()

rather than letting the callers handle the jump-to-root part of
semantics, do it right in get_link() and return the rest of the
body for the caller to deal with - at that point it's treated
the same way as relative symlinks would be.  And return NULL
when there's no "rest of the body" - those are treated the same
as pure jump symlink would be.

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
9 years agonamei: simpler treatment of symlinks with nothing other that / in the body
Al Viro [Sun, 10 May 2015 14:50:41 +0000 (10:50 -0400)]
namei: simpler treatment of symlinks with nothing other that / in the body

Instead of saving name and branching to OK:, where we'll immediately restore
it, and call walk_component() with WALK_PUT|WALK_GET and nd->last_type being
LAST_BIND, which is equivalent to put_link(nd), err = 0, we can just treat
that the same way we'd treat procfs-style "jump" symlinks - do put_link(nd)
and move on.

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
9 years agonamei: simplify failure exits in get_link()
Al Viro [Sun, 10 May 2015 14:43:46 +0000 (10:43 -0400)]
namei: simplify failure exits in get_link()

when cookie is NULL, put_link() is equivalent to path_put(), so
as soon as we'd set last->cookie to NULL, we can bump nd->depth and
let the normal logics in terminate_walk() to take care of cleanups.

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
9 years agodon't pass nameidata to ->follow_link()
Al Viro [Sat, 2 May 2015 17:37:52 +0000 (13:37 -0400)]
don't pass nameidata to ->follow_link()

its only use is getting passed to nd_jump_link(), which can obtain
it from current->nameidata

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
9 years agonamei: simplify the callers of follow_managed()
Al Viro [Wed, 22 Apr 2015 14:30:08 +0000 (10:30 -0400)]
namei: simplify the callers of follow_managed()

now that it gets nameidata, no reason to have setting LOOKUP_JUMPED on
mountpoint crossing and calling path_put_conditional() on failures
done in every caller.

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
9 years agoVFS: replace {, total_}link_count in task_struct with pointer to nameidata
NeilBrown [Mon, 23 Mar 2015 02:37:38 +0000 (13:37 +1100)]
VFS: replace {, total_}link_count in task_struct with pointer to nameidata

task_struct currently contains two ad-hoc members for use by the VFS:
link_count and total_link_count.  These are only interesting to fs/namei.c,
so exposing them explicitly is poor layering.  Incidentally, link_count
isn't used anymore, so it can just die.

This patches replaces those with a single pointer to 'struct nameidata'.
This structure represents the current filename lookup of which
there can only be one per process, and is a natural place to
store total_link_count.

This will allow the current "nameidata" argument to all
follow_link operations to be removed as current->nameidata
can be used instead in the _very_ few instances that care about
it at all.

As there are occasional circumstances where pathname lookup can
recurse, such as through kern_path_locked, we always save and old
current->nameidata (if there is one) when setting a new value, and
make sure any active link_counts are preserved.

follow_mount and follow_automount now get a 'struct nameidata *'
rather than 'int flags' so that they can directly access
total_link_count, rather than going through 'current'.

Suggested-by: Al Viro <viro@ZenIV.linux.org.uk>
Signed-off-by: NeilBrown <neilb@suse.de>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
9 years agolustre: rip the private symlink nesting limit out
Al Viro [Sat, 18 Apr 2015 03:02:40 +0000 (23:02 -0400)]
lustre: rip the private symlink nesting limit out

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
9 years agonamei: move link count check and stack allocation into pick_link()
Al Viro [Mon, 4 May 2015 22:26:59 +0000 (18:26 -0400)]
namei: move link count check and stack allocation into pick_link()

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
9 years agonamei: make should_follow_link() store the link in nd->link
Al Viro [Mon, 4 May 2015 22:13:23 +0000 (18:13 -0400)]
namei: make should_follow_link() store the link in nd->link

... if it decides to follow, that is.

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
9 years agonamei: new calling conventions for walk_component()
Al Viro [Mon, 4 May 2015 21:47:11 +0000 (17:47 -0400)]
namei: new calling conventions for walk_component()

instead of a single flag (!= 0 => we want to follow symlinks) pass
two bits - WALK_GET (want to follow symlinks) and WALK_PUT (put_link()
once we are done looking at the name).  The latter matters only for
success exits - on failure the caller will discard everything anyway.

Suggestions for better variant are welcome; what this thing aims for
is making sure that pending put_link() is done *before* walk_component()
decides to pick a symlink up, rather than between picking it up and
acting upon it.  See the next commit for payoff.

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
9 years agolink_path_walk: move the OK: inside the loop
Al Viro [Mon, 4 May 2015 12:58:35 +0000 (08:58 -0400)]
link_path_walk: move the OK: inside the loop

fewer labels that way; in particular, resuming after the end of
nested symlink is straight-line.

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
9 years agonamei: have terminate_walk() do put_link() on everything left
Al Viro [Mon, 4 May 2015 12:34:59 +0000 (08:34 -0400)]
namei: have terminate_walk() do put_link() on everything left

All callers of terminate_walk() are followed by more or less
open-coded eqiuvalent of "do put_link() on everything left
in nd->stack".  Better done in terminate_walk() itself, and
when we go for RCU symlink traversal we'll have to do it
there anyway.

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
9 years agonamei: take put_link() into {lookup,mountpoint,do}_last()
Al Viro [Mon, 4 May 2015 12:26:45 +0000 (08:26 -0400)]
namei: take put_link() into {lookup,mountpoint,do}_last()

rationale: we'll need to have terminate_walk() do put_link() on
everything, which will mean that in some cases ..._last() will do
put_link() anyway.  Easier to have them do it in all cases.

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
9 years agonamei: lift (open-coded) terminate_walk() into callers of get_link()
Al Viro [Mon, 4 May 2015 12:15:36 +0000 (08:15 -0400)]
namei: lift (open-coded) terminate_walk() into callers of get_link()

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
9 years agolift terminate_walk() into callers of walk_component()
Al Viro [Mon, 4 May 2015 11:59:30 +0000 (07:59 -0400)]
lift terminate_walk() into callers of walk_component()

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
9 years agonamei: lift (open-coded) terminate_walk() in follow_dotdot_rcu() into callers
Al Viro [Mon, 4 May 2015 11:53:00 +0000 (07:53 -0400)]
namei: lift (open-coded) terminate_walk() in follow_dotdot_rcu() into callers

follow_dotdot_rcu() does an equivalent of terminate_walk() on failure;
shifting it into callers makes for simpler rules and those callers
already have terminate_walk() on other failure exits.

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
9 years agonamei: we never need more than MAXSYMLINKS entries in nd->stack
Al Viro [Mon, 4 May 2015 01:30:27 +0000 (21:30 -0400)]
namei: we never need more than MAXSYMLINKS entries in nd->stack

The only reason why we needed one more was that purely nested
MAXSYMLINKS symlinks could lead to path_init() using that many
entries in addition to nd->stack[0] which it left unused.

That can't happen now - path_init() starts with entry 0 (and
trailing_symlink() is called only when we'd already encountered
one symlink, so no more than MAXSYMLINKS-1 are left).

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
9 years agolink_path_walk: end of nd->depth massage
Al Viro [Mon, 4 May 2015 01:27:36 +0000 (21:27 -0400)]
link_path_walk: end of nd->depth massage

get rid of orig_depth - we only use it on error exit to tell whether
to stop doing put_link() when depth reaches 0 (call from path_init())
or when it reaches 1 (call from trailing_symlink()).  However, in
the latter case the caller would immediately follow with one more
put_link().  Just keep doing it until the depth reaches zero (and
simplify trailing_symlink() as the result).

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
9 years agolink_path_walk: nd->depth massage, part 10
Al Viro [Mon, 4 May 2015 01:21:44 +0000 (21:21 -0400)]
link_path_walk: nd->depth massage, part 10

Get rid of orig_depth checks in OK: logics.  If nd->depth is
zero, we had been called from path_init() and we are done.
If it is greater than 1, we are not done, whether we'd been
called from path_init() or trailing_symlink().  And in
case when it's 1, we might have been called from path_init()
and reached the end of nested symlink (in which case
nd->stack[0].name will point to the rest of pathname and
we are not done) or from trailing_symlink(), in which case
we are done.

Just have trailing_symlink() leave NULL in nd->stack[0].name
and use that to discriminate between those cases.

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
9 years agolink_path_walk: nd->depth massage, part 9
Al Viro [Mon, 4 May 2015 01:16:35 +0000 (21:16 -0400)]
link_path_walk: nd->depth massage, part 9

Make link_path_walk() work with any value of nd->depth on entry -
memorize it and use it in tests instead of comparing with 1.
Don't bother with increment/decrement in path_init().

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
9 years agoput_link: nd->depth massage, part 8
Al Viro [Mon, 4 May 2015 01:06:24 +0000 (21:06 -0400)]
put_link: nd->depth massage, part 8

all calls are preceded by decrement of nd->depth; move it into
put_link() itself.

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
9 years agotrailing_symlink: nd->depth massage, part 7
Al Viro [Mon, 4 May 2015 01:04:07 +0000 (21:04 -0400)]
trailing_symlink: nd->depth massage, part 7

move decrement of nd->depth on successful returns into the callers.

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
9 years agoget_link: nd->depth massage, part 6
Al Viro [Mon, 4 May 2015 01:02:40 +0000 (21:02 -0400)]
get_link: nd->depth massage, part 6

make get_link() increment nd->depth on successful exit

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
9 years agotrailing_symlink: nd->depth massage, part 5
Al Viro [Mon, 4 May 2015 00:59:58 +0000 (20:59 -0400)]
trailing_symlink: nd->depth massage, part 5

move increment of ->depth to the point where we'd discovered
that get_link() has not returned an error, adjust exits
accordingly.

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
9 years agolink_path_walk: nd->depth massage, part 4
Al Viro [Mon, 4 May 2015 00:54:27 +0000 (20:54 -0400)]
link_path_walk: nd->depth massage, part 4

lift increment/decrement into link_path_walk() callers.

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
9 years agolink_path_walk: nd->depth massage, part 3
Al Viro [Mon, 4 May 2015 00:52:15 +0000 (20:52 -0400)]
link_path_walk: nd->depth massage, part 3

remove decrement/increment surrounding nd_alloc_stack(), adjust the
test in it.

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
9 years agolink_path_walk: nd->depth massage, part 2
Al Viro [Mon, 4 May 2015 00:46:54 +0000 (20:46 -0400)]
link_path_walk: nd->depth massage, part 2

collapse adjacent increment/decrement pairs.

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
9 years agolink_path_walk: nd->depth massage, part 1
Al Viro [Mon, 4 May 2015 00:01:27 +0000 (20:01 -0400)]
link_path_walk: nd->depth massage, part 1

nd->stack[0] is unused until the handling of trailing symlinks and
we want to get rid of that.  Having fucked that transformation up
several times, I went for bloody pedantic series of provably equivalent
transformations.  Sorry.

Step 1: keep nd->depth higher by one in link_path_walk() - increment upon
entry, decrement on exits, adjust the arithmetics inside and surround the
calls of functions that care about nd->depth value (nd_alloc_stack(),
get_link(), put_link()) with decrement/increment pairs.

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
9 years agonamei: remove restrictions on nesting depth
Al Viro [Sat, 2 May 2015 11:16:16 +0000 (07:16 -0400)]
namei: remove restrictions on nesting depth

The only restriction is that on the total amount of symlinks
crossed; how they are nested does not matter

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
9 years agonamei: trim the arguments of get_link()
Al Viro [Sun, 19 Apr 2015 04:53:50 +0000 (00:53 -0400)]
namei: trim the arguments of get_link()

same story as the previous commit

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
9 years agonamei: trim redundant arguments of fs/namei.c:put_link()
Al Viro [Sun, 3 May 2015 00:19:23 +0000 (20:19 -0400)]
namei: trim redundant arguments of fs/namei.c:put_link()

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
9 years agonamei: trim redundant arguments of trailing_symlink()
Al Viro [Sat, 2 May 2015 23:48:56 +0000 (19:48 -0400)]
namei: trim redundant arguments of trailing_symlink()

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
9 years agonamei: move link/cookie pairs into nameidata
Al Viro [Sat, 2 May 2015 23:38:35 +0000 (19:38 -0400)]
namei: move link/cookie pairs into nameidata

Array of MAX_NESTED_LINKS + 1 elements put into nameidata;
what used to be a local array in link_path_walk() occupies
entries 1 .. MAX_NESTED_LINKS in it, link and cookie from
the trailing symlink handling loops - entry 0.

This is _not_ the final arrangement; just an easily verified
incremental step.

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
9 years agolink_path_walk: cleanup - turn goto start; into continue;
Al Viro [Sun, 19 Apr 2015 00:44:34 +0000 (20:44 -0400)]
link_path_walk: cleanup - turn goto start; into continue;

Deal with skipping leading slashes before what used to be the
recursive call.  That way we can get rid of that goto completely.

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
9 years agolink_path_walk: split "return from recursive call" path
Al Viro [Sun, 19 Apr 2015 00:40:04 +0000 (20:40 -0400)]
link_path_walk: split "return from recursive call" path

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
9 years agolink_path_walk: kill the recursion
Al Viro [Sun, 19 Apr 2015 00:30:49 +0000 (20:30 -0400)]
link_path_walk: kill the recursion

absolutely straightforward now - the only variables we need to preserve
across the recursive call are name, link and cookie, and recursion depth
is limited (and can is equal to nd->depth).  So arrange an array of
triples to hold instances of those and be done with that.

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
9 years agolink_path_walk: final preparations to killing recursion
Al Viro [Sun, 19 Apr 2015 00:21:40 +0000 (20:21 -0400)]
link_path_walk: final preparations to killing recursion

reduce the number of returns in there - turn all places
where it returns zero into goto OK and places where it
returns non-zero into goto Err.  The only non-trivial
detail is that all breaks in the loop are guaranteed
to be with non-zero err.

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
9 years agolink_path_walk: get rid of duplication
Al Viro [Sun, 19 Apr 2015 00:14:20 +0000 (20:14 -0400)]
link_path_walk: get rid of duplication

What we do after the second walk_component() + put_link() + depth
decrement in there is exactly equivalent to what's done right
after the first walk_component().  Easy to verify and not at all
surprising, seeing that there we have just walked the last
component of nested symlink.

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
9 years agolink_path_walk: massage a bit more
Al Viro [Sun, 19 Apr 2015 00:09:08 +0000 (20:09 -0400)]
link_path_walk: massage a bit more

Pull the block after the if-else in the end of what used to be do-while
body into all branches there.  We are almost done with the massage...

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
9 years agolink_path_walk: turn inner loop into explicit goto
Al Viro [Sun, 19 Apr 2015 00:03:03 +0000 (20:03 -0400)]
link_path_walk: turn inner loop into explicit goto

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
9 years agolink_path_walk: don't bother with walk_component() after jumping link
Al Viro [Sat, 18 Apr 2015 23:19:01 +0000 (19:19 -0400)]
link_path_walk: don't bother with walk_component() after jumping link

... it does nothing if nd->last_type is LAST_BIND.

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
9 years agolink_path_walk: handle get_link() returning ERR_PTR() immediately
Al Viro [Sat, 18 Apr 2015 23:10:36 +0000 (19:10 -0400)]
link_path_walk: handle get_link() returning ERR_PTR() immediately

If we get ERR_PTR() from get_link(), we are guaranteed to get err != 0
when we break out of do-while, so we are going to hit if (err) return err;
shortly after it.  Pull that into the if (IS_ERR(s)) body.

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
9 years agonamei: rename follow_link to trailing_symlink, move it down
Al Viro [Wed, 22 Apr 2015 17:46:57 +0000 (13:46 -0400)]
namei: rename follow_link to trailing_symlink, move it down

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
9 years agonamei: move the calls of may_follow_link() into follow_link()
Al Viro [Sun, 19 Apr 2015 04:16:37 +0000 (00:16 -0400)]
namei: move the calls of may_follow_link() into follow_link()

All remaining callers of the former are preceded by the latter

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
9 years agonamei: expand the call of follow_link() in link_path_walk()
Al Viro [Sat, 18 Apr 2015 22:45:16 +0000 (18:45 -0400)]
namei: expand the call of follow_link() in link_path_walk()

... and strip __always_inline from follow_link() - remaining callers
don't need that.

Now link_path_walk() recursion is a direct one.

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
9 years agonamei: expand nested_symlink() in its only caller
Al Viro [Sat, 18 Apr 2015 03:44:45 +0000 (23:44 -0400)]
namei: expand nested_symlink() in its only caller

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
9 years agodo_last: move path there from caller's stack frame
Al Viro [Wed, 22 Apr 2015 22:02:17 +0000 (18:02 -0400)]
do_last: move path there from caller's stack frame

We used to need it to feed to follow_link().  No more...

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
9 years agonamei: introduce nameidata->link
Al Viro [Wed, 22 Apr 2015 21:52:47 +0000 (17:52 -0400)]
namei: introduce nameidata->link

shares space with nameidata->next, walk_component() et.al. store
the struct path of symlink instead of returning it into a variable
passed by caller.

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
9 years agonamei: don't bother with ->follow_link() if ->i_link is set
Al Viro [Fri, 1 May 2015 00:08:02 +0000 (20:08 -0400)]
namei: don't bother with ->follow_link() if ->i_link is set

with new calling conventions it's trivial

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Conflicts:
fs/namei.c

9 years agonamei.c: separate the parts of follow_link() that find the link body
Al Viro [Sat, 18 Apr 2015 22:23:41 +0000 (18:23 -0400)]
namei.c: separate the parts of follow_link() that find the link body

Split a piece of fs/namei.c:follow_link() that does obtaining the link
body into a separate function.  follow_link() itself is converted to
calling get_link() and then doing the body traversal (if any).

The next step will expand follow_link() call in link_path_walk()
and this helps to keep the size down...

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
9 years agonew ->follow_link() and ->put_link() calling conventions
Al Viro [Sat, 2 May 2015 17:32:22 +0000 (13:32 -0400)]
new ->follow_link() and ->put_link() calling conventions

a) instead of storing the symlink body (via nd_set_link()) and returning
an opaque pointer later passed to ->put_link(), ->follow_link() _stores_
that opaque pointer (into void * passed by address by caller) and returns
the symlink body.  Returning ERR_PTR() on error, NULL on jump (procfs magic
symlinks) and pointer to symlink body for normal symlinks.  Stored pointer
is ignored in all cases except the last one.

Storing NULL for opaque pointer (or not storing it at all) means no call
of ->put_link().

b) the body used to be passed to ->put_link() implicitly (via nameidata).
Now only the opaque pointer is.  In the cases when we used the symlink body
to free stuff, ->follow_link() now should store it as opaque pointer in addition
to returning it.

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
9 years agonamei: lift nameidata into filename_mountpoint()
Al Viro [Sat, 2 May 2015 02:08:30 +0000 (22:08 -0400)]
namei: lift nameidata into filename_mountpoint()

when we go for on-demand allocation of saved state in
link_path_walk(), we'll want nameidata to stay around
for all 3 calls of path_mountpoint().

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
9 years agoname: shift nameidata down into user_path_walk()
Al Viro [Thu, 30 Apr 2015 20:09:11 +0000 (16:09 -0400)]
name: shift nameidata down into user_path_walk()

that avoids having nameidata on stack during the calls of
->rmdir()/->unlink() and *two* of those during the calls
of ->rename().

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
9 years agonamei: get rid of lookup_hash()
Al Viro [Thu, 30 Apr 2015 16:25:18 +0000 (12:25 -0400)]
namei: get rid of lookup_hash()

it's a convenient helper, but we'll want to shift nameidata
down the call chain, so it won't be available there...

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
9 years agodo_last: regularize the logics around following symlinks
Al Viro [Wed, 22 Apr 2015 16:10:45 +0000 (12:10 -0400)]
do_last: regularize the logics around following symlinks

With LOOKUP_FOLLOW we unlazy and return 1; without it we either
fail with ELOOP or, for O_PATH opens, succeed.  No need to mix
those cases...

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
9 years agodo_last: kill symlink_ok
Al Viro [Wed, 22 Apr 2015 16:02:25 +0000 (12:02 -0400)]
do_last: kill symlink_ok

When O_PATH is present, O_CREAT isn't, so symlink_ok is always equal to
(open_flags & O_PATH) && !(nd->flags & LOOKUP_FOLLOW).

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
9 years agonamei: take O_NOFOLLOW treatment into do_last()
Al Viro [Wed, 22 Apr 2015 15:27:43 +0000 (11:27 -0400)]
namei: take O_NOFOLLOW treatment into do_last()

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
9 years agouninline walk_component()
Al Viro [Sun, 19 Apr 2015 11:48:53 +0000 (07:48 -0400)]
uninline walk_component()

seriously improves the stack *and* I-cache footprint...

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
9 years agoSECURITY: remove nameidata arg from inode_follow_link.
NeilBrown [Mon, 23 Mar 2015 02:37:39 +0000 (13:37 +1100)]
SECURITY: remove nameidata arg from inode_follow_link.

No ->inode_follow_link() methods use the nameidata arg, and
it is about to become private to namei.c.
So remove from all inode_follow_link() functions.

Signed-off-by: NeilBrown <neilb@suse.de>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
9 years agologfs: fix a pagecache leak for symlinks
Al Viro [Tue, 21 Apr 2015 14:48:50 +0000 (10:48 -0400)]
logfs: fix a pagecache leak for symlinks

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
9 years agoceph: switch to simple_follow_link()
Al Viro [Sat, 2 May 2015 14:50:05 +0000 (10:50 -0400)]
ceph: switch to simple_follow_link()

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
9 years agoexofs: switch to {simple,page}_symlink_inode_operations
Al Viro [Sat, 2 May 2015 14:46:42 +0000 (10:46 -0400)]
exofs: switch to {simple,page}_symlink_inode_operations

ACK-by: Boaz Harrosh <ooo@electrozaur.com>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
9 years agofreevxfs: switch to simple_follow_link()
Al Viro [Sat, 2 May 2015 14:43:25 +0000 (10:43 -0400)]
freevxfs: switch to simple_follow_link()

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
9 years agojfs: switch to simple_follow_link()
Al Viro [Sat, 2 May 2015 14:41:20 +0000 (10:41 -0400)]
jfs: switch to simple_follow_link()

Reviewed-by: Jan Kara <jack@suse.cz>
Acked-by: Dave Kleikamp <dave.kleikamp@oracle.com>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
9 years agosysv: switch to simple_follow_link()
Al Viro [Sat, 2 May 2015 14:37:09 +0000 (10:37 -0400)]
sysv: switch to simple_follow_link()

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
9 years agoubifs: switch to simple_follow_link()
Al Viro [Sat, 2 May 2015 14:35:42 +0000 (10:35 -0400)]
ubifs: switch to simple_follow_link()

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
9 years agoufs: switch to simple_follow_link()
Al Viro [Sat, 2 May 2015 14:28:56 +0000 (10:28 -0400)]
ufs: switch to simple_follow_link()

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
9 years agodebugfs: switch to simple_follow_link()
Al Viro [Sat, 2 May 2015 14:27:18 +0000 (10:27 -0400)]
debugfs: switch to simple_follow_link()

Reviewed-by: Jan Kara <jack@suse.cz>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
9 years agoshmem: switch to simple_follow_link()
Al Viro [Sat, 2 May 2015 14:24:43 +0000 (10:24 -0400)]
shmem: switch to simple_follow_link()

Reviewed-by: Jan Kara <jack@suse.cz>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
9 years agojffs2: switch to simple_follow_link()
Al Viro [Sat, 2 May 2015 14:21:20 +0000 (10:21 -0400)]
jffs2: switch to simple_follow_link()

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
9 years agoext4: switch to simple_follow_link()
Al Viro [Sat, 2 May 2015 14:13:58 +0000 (10:13 -0400)]
ext4: switch to simple_follow_link()

for fast symlinks only, of course...

Reviewed-by: Jan Kara <jack@suse.cz>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>