diff --git a/kernel/pkg_observer.c b/kernel/pkg_observer.c index e0641332..ae5ee23d 100644 --- a/kernel/pkg_observer.c +++ b/kernel/pkg_observer.c @@ -2,8 +2,9 @@ #include #include #include -#include +#include #include +#include #include #include #include "klog.h" // IWYU pragma: keep @@ -23,6 +24,7 @@ struct watch_dir { static struct fsnotify_group *g; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 9, 0) static int ksu_handle_inode_event(struct fsnotify_mark *mark, u32 mask, struct inode *inode, struct inode *dir, const struct qstr *file_name, u32 cookie) @@ -41,9 +43,58 @@ static int ksu_handle_inode_event(struct fsnotify_mark *mark, u32 mask, } return 0; } +#else +#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 2, 0) +static int ksu_handle_event(struct fsnotify_group *group, + struct inode *inode, u32 mask, const void *data, int data_type, + const struct qstr *file_name, u32 cookie, + struct fsnotify_iter_info *iter_info) +#elif LINUX_VERSION_CODE >= KERNEL_VERSION(4, 18, 0) +static int ksu_handle_event(struct fsnotify_group *group, + struct inode *inode, u32 mask, const void *data, int data_type, + const unsigned char *file_name, u32 cookie, + struct fsnotify_iter_info *iter_info) +#elif LINUX_VERSION_CODE >= KERNEL_VERSION(4, 12, 0) +static int ksu_handle_event(struct fsnotify_group *group, + struct inode *inode, struct fsnotify_mark *inode_mark, + struct fsnotify_mark *vfsmount_mark, + u32 mask, const void *data, int data_type, + const unsigned char *file_name, u32 cookie, + struct fsnotify_iter_info *iter_info) +#else +static int ksu_handle_event(struct fsnotify_group *group, + struct inode *inode, + struct fsnotify_mark *inode_mark, + struct fsnotify_mark *vfsmount_mark, + u32 mask, void *data, int data_type, + const unsigned char *file_name, u32 cookie) +#endif +{ + if (!file_name) + return 0; + if (mask & FS_ISDIR) + return 0; + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 2, 0) + if (file_name->len == 13 && + !memcmp(file_name->name, "packages.list", 13)) { +#else + if (strlen(file_name) == 13 && + !memcmp(file_name, "packages.list", 13)) { +#endif + pr_info("packages.list detected: %d\n", mask); + track_throne(); + } + return 0; +} +#endif static const struct fsnotify_ops ksu_ops = { - .handle_inode_event = ksu_handle_inode_event, +#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 9, 0) + .handle_inode_event = ksu_handle_inode_event, +#else + .handle_event = ksu_handle_event, +#endif }; static int add_mark_on_inode(struct inode *inode, u32 mask, @@ -58,12 +109,23 @@ static int add_mark_on_inode(struct inode *inode, u32 mask, fsnotify_init_mark(m, g); m->mask = mask; - if (fsnotify_add_inode_mark(m, inode, 0)) { - fsnotify_put_mark(m); - return -EINVAL; - } - *out = m; - return 0; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 12, 0) + if (fsnotify_add_inode_mark(m, inode, 0)) { + fsnotify_put_mark(m); + return -EINVAL; + } +#else /* TODO: Need more tests on k4.4 and k4.9! */ + mutex_lock(&g->mark_mutex); + if (fsnotify_add_mark_locked(m, g, inode, NULL, 0)) { + fsnotify_put_mark(m); + mutex_unlock(&g->mark_mutex); + return -EINVAL; + } + mutex_unlock(&g->mark_mutex); +#endif + + *out = m; + return 0; } static int watch_one_dir(struct watch_dir *wd)