^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) };