Back to home page

LXR

 
 

    


0001 /* audit_fsnotify.c -- tracking inodes
0002  *
0003  * Copyright 2003-2009,2014-2015 Red Hat, Inc.
0004  * Copyright 2005 Hewlett-Packard Development Company, L.P.
0005  * Copyright 2005 IBM Corporation
0006  *
0007  * This program is free software; you can redistribute it and/or modify
0008  * it under the terms of the GNU General Public License as published by
0009  * the Free Software Foundation; either version 2 of the License, or
0010  * (at your option) any later version.
0011  *
0012  * This program is distributed in the hope that it will be useful,
0013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
0014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
0015  * GNU General Public License for more details.
0016  */
0017 
0018 #include <linux/kernel.h>
0019 #include <linux/audit.h>
0020 #include <linux/kthread.h>
0021 #include <linux/mutex.h>
0022 #include <linux/fs.h>
0023 #include <linux/fsnotify_backend.h>
0024 #include <linux/namei.h>
0025 #include <linux/netlink.h>
0026 #include <linux/sched.h>
0027 #include <linux/slab.h>
0028 #include <linux/security.h>
0029 #include "audit.h"
0030 
0031 /*
0032  * this mark lives on the parent directory of the inode in question.
0033  * but dev, ino, and path are about the child
0034  */
0035 struct audit_fsnotify_mark {
0036     dev_t dev;      /* associated superblock device */
0037     unsigned long ino;  /* associated inode number */
0038     char *path;     /* insertion path */
0039     struct fsnotify_mark mark; /* fsnotify mark on the inode */
0040     struct audit_krule *rule;
0041 };
0042 
0043 /* fsnotify handle. */
0044 static struct fsnotify_group *audit_fsnotify_group;
0045 
0046 /* fsnotify events we care about. */
0047 #define AUDIT_FS_EVENTS (FS_MOVE | FS_CREATE | FS_DELETE | FS_DELETE_SELF |\
0048              FS_MOVE_SELF | FS_EVENT_ON_CHILD)
0049 
0050 static void audit_fsnotify_mark_free(struct audit_fsnotify_mark *audit_mark)
0051 {
0052     kfree(audit_mark->path);
0053     kfree(audit_mark);
0054 }
0055 
0056 static void audit_fsnotify_free_mark(struct fsnotify_mark *mark)
0057 {
0058     struct audit_fsnotify_mark *audit_mark;
0059 
0060     audit_mark = container_of(mark, struct audit_fsnotify_mark, mark);
0061     audit_fsnotify_mark_free(audit_mark);
0062 }
0063 
0064 char *audit_mark_path(struct audit_fsnotify_mark *mark)
0065 {
0066     return mark->path;
0067 }
0068 
0069 int audit_mark_compare(struct audit_fsnotify_mark *mark, unsigned long ino, dev_t dev)
0070 {
0071     if (mark->ino == AUDIT_INO_UNSET)
0072         return 0;
0073     return (mark->ino == ino) && (mark->dev == dev);
0074 }
0075 
0076 static void audit_update_mark(struct audit_fsnotify_mark *audit_mark,
0077                  const struct inode *inode)
0078 {
0079     audit_mark->dev = inode ? inode->i_sb->s_dev : AUDIT_DEV_UNSET;
0080     audit_mark->ino = inode ? inode->i_ino : AUDIT_INO_UNSET;
0081 }
0082 
0083 struct audit_fsnotify_mark *audit_alloc_mark(struct audit_krule *krule, char *pathname, int len)
0084 {
0085     struct audit_fsnotify_mark *audit_mark;
0086     struct path path;
0087     struct dentry *dentry;
0088     struct inode *inode;
0089     int ret;
0090 
0091     if (pathname[0] != '/' || pathname[len-1] == '/')
0092         return ERR_PTR(-EINVAL);
0093 
0094     dentry = kern_path_locked(pathname, &path);
0095     if (IS_ERR(dentry))
0096         return (void *)dentry; /* returning an error */
0097     inode = path.dentry->d_inode;
0098     inode_unlock(inode);
0099 
0100     audit_mark = kzalloc(sizeof(*audit_mark), GFP_KERNEL);
0101     if (unlikely(!audit_mark)) {
0102         audit_mark = ERR_PTR(-ENOMEM);
0103         goto out;
0104     }
0105 
0106     fsnotify_init_mark(&audit_mark->mark, audit_fsnotify_free_mark);
0107     audit_mark->mark.mask = AUDIT_FS_EVENTS;
0108     audit_mark->path = pathname;
0109     audit_update_mark(audit_mark, dentry->d_inode);
0110     audit_mark->rule = krule;
0111 
0112     ret = fsnotify_add_mark(&audit_mark->mark, audit_fsnotify_group, inode, NULL, true);
0113     if (ret < 0) {
0114         audit_fsnotify_mark_free(audit_mark);
0115         audit_mark = ERR_PTR(ret);
0116     }
0117 out:
0118     dput(dentry);
0119     path_put(&path);
0120     return audit_mark;
0121 }
0122 
0123 static void audit_mark_log_rule_change(struct audit_fsnotify_mark *audit_mark, char *op)
0124 {
0125     struct audit_buffer *ab;
0126     struct audit_krule *rule = audit_mark->rule;
0127 
0128     if (!audit_enabled)
0129         return;
0130     ab = audit_log_start(NULL, GFP_NOFS, AUDIT_CONFIG_CHANGE);
0131     if (unlikely(!ab))
0132         return;
0133     audit_log_format(ab, "auid=%u ses=%u op=%s",
0134              from_kuid(&init_user_ns, audit_get_loginuid(current)),
0135              audit_get_sessionid(current), op);
0136     audit_log_format(ab, " path=");
0137     audit_log_untrustedstring(ab, audit_mark->path);
0138     audit_log_key(ab, rule->filterkey);
0139     audit_log_format(ab, " list=%d res=1", rule->listnr);
0140     audit_log_end(ab);
0141 }
0142 
0143 void audit_remove_mark(struct audit_fsnotify_mark *audit_mark)
0144 {
0145     fsnotify_destroy_mark(&audit_mark->mark, audit_fsnotify_group);
0146     fsnotify_put_mark(&audit_mark->mark);
0147 }
0148 
0149 void audit_remove_mark_rule(struct audit_krule *krule)
0150 {
0151     struct audit_fsnotify_mark *mark = krule->exe;
0152 
0153     audit_remove_mark(mark);
0154 }
0155 
0156 static void audit_autoremove_mark_rule(struct audit_fsnotify_mark *audit_mark)
0157 {
0158     struct audit_krule *rule = audit_mark->rule;
0159     struct audit_entry *entry = container_of(rule, struct audit_entry, rule);
0160 
0161     audit_mark_log_rule_change(audit_mark, "autoremove_rule");
0162     audit_del_rule(entry);
0163 }
0164 
0165 /* Update mark data in audit rules based on fsnotify events. */
0166 static int audit_mark_handle_event(struct fsnotify_group *group,
0167                     struct inode *to_tell,
0168                     struct fsnotify_mark *inode_mark,
0169                     struct fsnotify_mark *vfsmount_mark,
0170                     u32 mask, const void *data, int data_type,
0171                     const unsigned char *dname, u32 cookie)
0172 {
0173     struct audit_fsnotify_mark *audit_mark;
0174     const struct inode *inode = NULL;
0175 
0176     audit_mark = container_of(inode_mark, struct audit_fsnotify_mark, mark);
0177 
0178     BUG_ON(group != audit_fsnotify_group);
0179 
0180     switch (data_type) {
0181     case (FSNOTIFY_EVENT_PATH):
0182         inode = ((const struct path *)data)->dentry->d_inode;
0183         break;
0184     case (FSNOTIFY_EVENT_INODE):
0185         inode = (const struct inode *)data;
0186         break;
0187     default:
0188         BUG();
0189         return 0;
0190     };
0191 
0192     if (mask & (FS_CREATE|FS_MOVED_TO|FS_DELETE|FS_MOVED_FROM)) {
0193         if (audit_compare_dname_path(dname, audit_mark->path, AUDIT_NAME_FULL))
0194             return 0;
0195         audit_update_mark(audit_mark, inode);
0196     } else if (mask & (FS_DELETE_SELF|FS_UNMOUNT|FS_MOVE_SELF))
0197         audit_autoremove_mark_rule(audit_mark);
0198 
0199     return 0;
0200 }
0201 
0202 static const struct fsnotify_ops audit_mark_fsnotify_ops = {
0203     .handle_event = audit_mark_handle_event,
0204 };
0205 
0206 static int __init audit_fsnotify_init(void)
0207 {
0208     audit_fsnotify_group = fsnotify_alloc_group(&audit_mark_fsnotify_ops);
0209     if (IS_ERR(audit_fsnotify_group)) {
0210         audit_fsnotify_group = NULL;
0211         audit_panic("cannot create audit fsnotify group");
0212     }
0213     return 0;
0214 }
0215 device_initcall(audit_fsnotify_init);