[PATCHES] file->f_path safety and struct path constifications

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



	struct path is embedded into several objects, starting with
struct file.  In a lot of places we rely upon e.g. file->f_path of an
opened file remaining unchanging; things like "ask for write access to
file->f_path.mnt when opening for write, release that on final fput()"
would break badly if ->f_path.mnt could change between those.  It's not
the only place like that; both VFS and filesystems expect that to hold.
Anything that would want to play silly buggers with that would have to be
_very_ careful and would be rather brittle, at that.  It's not impossible
to get away with, but any such place is a source of headache for proofs
of correctness, as well as a likely cause of bugs in the future.

	Unfortunately, verifying that turns into several hours of manual
audit that has to be repeated once in a while and I'm sick and tired of
doing that.  Let the compiler deal with that crap.  The same goes for
struct unix_sock ->path, etc.

Note that in the mainline we have _very_ few places that store to ->f_path.
	1) init_file() zeroes it out
	2) file_init_path() copies the caller-supplied struct path into it
(common helper of alloc_file() family of primitives; struct file is freshly
allocated, we are setting it up)
	3) atomic_open()/finish_open()/finish_no_open() arrange for setting
->f_path between them.  Again, that's before it gets opened.
	4) vfs_tmpfile() - ditto.
	5) do_dentry_open() clears it on early failure exits
	6) vfs_open() sets it to caller-supplied struct path - that's opening
the file by path (dentry_open() and its ilk are using that one).  Again,
prior to file getting opened.
	7) acct_on() (acct(2) helper) is flipping ->f_path.mnt of its internally
opened and internally used file to cloned mount.  It does get away with that,
but it's neither pretty nor robust.

	All except the last one are in core VFS and not dealing with
already opened files.  Killing (7) is doable - it's not hard to get rid
of that weird shit in acct_on().  After that no stores happen to opened
files and all those stores are local to fs/file_table.c, fs/open.c and
fs/namei.c (the latter - in the open-related parts).

	After that the obvious next step would be to turn f_path into
type-punning union of struct path __f_path and const struct path
f_path, and switch the places that should do stores (see above) to
using ->__f_path.  It's valid C99 - no UB there.  struct file no longer
can be a modifiable lvalue, but we never did wholesale copying for those
and there's no reason to start; what's more, we never embed struct file
into any other objects.

	It's not quite that simple, though - things like
	return vfs_statx_path(&fd_file(f)->f_path, flags, stat, request_mask);
would have the compiler complain; it needs to be told that vfs_statx_path()
is not going to modify the struct path it's been given.  IOW, we need to
switch a bunch of struct path * arguments to const struct path * before we
can go for the final part.  Turns out that there's not a lot of such
missing annotations.

So this stuff sits in two branches:

#work.path switches the struct path * arguments that are never used to modify
the struct path in question to const struct path *.  Not all of those
functions are used for ->f_path, but there's not a lot of them and new call
sites might appear, so let's deal with all that bunch.

#work.f_path starts with getting rid of the shit in acct_on(), then merges
#work.path and #work.mount in (I don't want to pull constification patches
out of #work.mount), then does the conversion of f_path to anon union.

Branches are in
git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs.git #work.path and
git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs.git #work.f_path resp.;
individual patches in followups.

Please, review.  If nobody objects, I'm putting that into #for-next early
next week...




[Index of Archives]     [Linux Ext4 Filesystem]     [Union Filesystem]     [Filesystem Testing]     [Ceph Users]     [Ecryptfs]     [NTFS 3]     [AutoFS]     [Kernel Newbies]     [Share Photos]     [Security]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux Cachefs]     [Reiser Filesystem]     [Linux RAID]     [NTFS 3]     [Samba]     [Device Mapper]     [CEPH Development]

  Powered by Linux