Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  * fs/inotify_user.c - inotify support for userspace
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  * Authors:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  *	John McCutchan	<ttb@tentacle.dhs.org>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7)  *	Robert Love	<rml@novell.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9)  * Copyright (C) 2005 John McCutchan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10)  * Copyright 2006 Hewlett-Packard Development Company, L.P.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12)  * Copyright (C) 2009 Eric Paris <Red Hat Inc>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13)  * inotify was largely rewriten to make use of the fsnotify infrastructure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) #include <linux/dcache.h> /* d_unlinked */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) #include <linux/fs.h> /* struct inode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) #include <linux/fsnotify_backend.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) #include <linux/inotify.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) #include <linux/path.h> /* struct path */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) #include <linux/slab.h> /* kmem_* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) #include <linux/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) #include <linux/sched.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) #include <linux/sched/user.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) #include <linux/sched/mm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) #include "inotify.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30)  * Check if 2 events contain the same information.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) static bool event_compare(struct fsnotify_event *old_fsn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) 			  struct fsnotify_event *new_fsn)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) 	struct inotify_event_info *old, *new;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) 	old = INOTIFY_E(old_fsn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) 	new = INOTIFY_E(new_fsn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) 	if (old->mask & FS_IN_IGNORED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) 		return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) 	if ((old->mask == new->mask) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) 	    (old->wd == new->wd) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) 	    (old->name_len == new->name_len) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) 	    (!old->name_len || !strcmp(old->name, new->name)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) 		return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) 	return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) static int inotify_merge(struct list_head *list,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) 			  struct fsnotify_event *event)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) 	struct fsnotify_event *last_event;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 	last_event = list_entry(list->prev, struct fsnotify_event, list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) 	return event_compare(last_event, event);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) int inotify_handle_inode_event(struct fsnotify_mark *inode_mark, u32 mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 			       struct inode *inode, struct inode *dir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 			       const struct qstr *name, u32 cookie)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 	struct inotify_inode_mark *i_mark;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 	struct inotify_event_info *event;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 	struct fsnotify_event *fsn_event;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 	struct fsnotify_group *group = inode_mark->group;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 	int len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 	int alloc_len = sizeof(struct inotify_event_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 	struct mem_cgroup *old_memcg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 	if (name) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 		len = name->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 		alloc_len += len + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 	pr_debug("%s: group=%p mark=%p mask=%x\n", __func__, group, inode_mark,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 		 mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 	i_mark = container_of(inode_mark, struct inotify_inode_mark,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 			      fsn_mark);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 	 * Whoever is interested in the event, pays for the allocation. Do not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 	 * trigger OOM killer in the target monitoring memcg as it may have
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 	 * security repercussion.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 	old_memcg = set_active_memcg(group->memcg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 	event = kmalloc(alloc_len, GFP_KERNEL_ACCOUNT | __GFP_RETRY_MAYFAIL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 	set_active_memcg(old_memcg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 	if (unlikely(!event)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 		 * Treat lost event due to ENOMEM the same way as queue
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 		 * overflow to let userspace know event was lost.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 		fsnotify_queue_overflow(group);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 	 * We now report FS_ISDIR flag with MOVE_SELF and DELETE_SELF events
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 	 * for fanotify. inotify never reported IN_ISDIR with those events.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 	 * It looks like an oversight, but to avoid the risk of breaking
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 	 * existing inotify programs, mask the flag out from those events.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 	if (mask & (IN_MOVE_SELF | IN_DELETE_SELF))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 		mask &= ~IN_ISDIR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 	fsn_event = &event->fse;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 	fsnotify_init_event(fsn_event, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 	event->mask = mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 	event->wd = i_mark->wd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 	event->sync_cookie = cookie;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 	event->name_len = len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 	if (len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 		strcpy(event->name, name->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 	ret = fsnotify_add_event(group, fsn_event, inotify_merge);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 	if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 		/* Our event wasn't used in the end. Free it. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 		fsnotify_destroy_event(group, fsn_event);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 	if (inode_mark->mask & IN_ONESHOT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 		fsnotify_destroy_mark(inode_mark, group);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) static void inotify_freeing_mark(struct fsnotify_mark *fsn_mark, struct fsnotify_group *group)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 	inotify_ignored_and_remove_idr(fsn_mark, group);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136)  * This is NEVER supposed to be called.  Inotify marks should either have been
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137)  * removed from the idr when the watch was removed or in the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138)  * fsnotify_destroy_mark_by_group() call when the inotify instance was being
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139)  * torn down.  This is only called if the idr is about to be freed but there
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140)  * are still marks in it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) static int idr_callback(int id, void *p, void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) 	struct fsnotify_mark *fsn_mark;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 	struct inotify_inode_mark *i_mark;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 	static bool warned = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 	if (warned)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 	warned = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 	fsn_mark = p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 	i_mark = container_of(fsn_mark, struct inotify_inode_mark, fsn_mark);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 	WARN(1, "inotify closing but id=%d for fsn_mark=%p in group=%p still in "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 		"idr.  Probably leaking memory\n", id, p, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 	 * I'm taking the liberty of assuming that the mark in question is a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 	 * valid address and I'm dereferencing it.  This might help to figure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 	 * out why we got here and the panic is no worse than the original
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 	 * BUG() that was here.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 	if (fsn_mark)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 		printk(KERN_WARNING "fsn_mark->group=%p wd=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 			fsn_mark->group, i_mark->wd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) static void inotify_free_group_priv(struct fsnotify_group *group)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) 	/* ideally the idr is empty and we won't hit the BUG in the callback */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 	idr_for_each(&group->inotify_data.idr, idr_callback, group);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) 	idr_destroy(&group->inotify_data.idr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) 	if (group->inotify_data.ucounts)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) 		dec_inotify_instances(group->inotify_data.ucounts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) static void inotify_free_event(struct fsnotify_event *fsn_event)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) 	kfree(INOTIFY_E(fsn_event));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) /* ding dong the mark is dead */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) static void inotify_free_mark(struct fsnotify_mark *fsn_mark)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) 	struct inotify_inode_mark *i_mark;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) 	i_mark = container_of(fsn_mark, struct inotify_inode_mark, fsn_mark);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) 	kmem_cache_free(inotify_inode_mark_cachep, i_mark);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) const struct fsnotify_ops inotify_fsnotify_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) 	.handle_inode_event = inotify_handle_inode_event,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) 	.free_group_priv = inotify_free_group_priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) 	.free_event = inotify_free_event,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) 	.freeing_mark = inotify_freeing_mark,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) 	.free_mark = inotify_free_mark,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) };