Thread (12 messages) 12 messages, 3 authors, 2016-01-11

Re: [PATCH v6] fs: clear file privilege bits when mmap writing

flat view

From: Konstantin Khlebnikov <hidden>
Date: 2016-01-10 19:51:52
Also in: linux-arch, linux-mm

On Sun, Jan 10, 2016 at 10:30 PM, Al Viro [off-list ref] wrote:
On Sun, Jan 10, 2016 at 06:48:32PM +0300, Konstantin Khlebnikov wrote:
quoted
I think this should be done in mmap/mprotect. Code in sys_mmap is trivial.

In sys_mprotect you can check file_needs_remove_privs() and VM_SHARED
under mmap_sem, then if needed grab reference to struct file from vma and
clear suid after unlocking mmap_sem.
Which vma?  mprotect(2) can cover more than one mapping...  You'd have to
play interesting games to collect the set of affected struct file; it
_might_ be doable (e.g. by using task_work_add() to have the damn thing
trigger on the way to userland), but it would require some care to avoid
hitting the same file more than once - it might, after all, be mmapped
in more than one process, so racing mprotect() would need to be taken
into account.  Hell knows - might be doable, but I'm not sure it'll be
any prettier.
Ok, I didn't thought about that. mprotect don't have to be atomic for whole
range -- we could drop mmap_sem, clear suid from one file and restart it
for next vma and so on.
->f_u.fu_rcuhead.func would need to be zeroed on struct file allocation,
and that code would need to
        * check ->f_u.fu_rcuhead.func; if non-NULL - sod off, nothing to do
        * lock ->f_lock
        * recheck (and unlock if we'd lost a race and need to sod off)
        * get_file()
        * task_work_add() on ->f_u.fu_rcuhead
        * drop ->f_lock
with task_work_add() callback removing SUID, zero ->fu.fu_rcuhead.func (under
->f_lock) and finally fput().

In principle, that would work; the primitive would be along the lines of
"make sure that SUID is removed before return to userland" and both mmap
and mprotect would use it.  The primitive itself would be in fs/file_table.c,
encapsulating the messy details in there.  All existing users of ->f_u don't
touch it until ->f_count drops to 0, so we are OK to use it here.  It obviously
should _not_ be used for kernel threads (task_work_add() won't do us any
good in those, but then we are not going to do mmap or mprotect there either).
Regular writes should *not* use that - they ought to strip SUID directly.

Might be worth trying...  Any takers?
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help