mirror of
https://gitlab.com/apparmor/apparmor.git
synced 2025-03-06 09:21:00 +01:00
278 lines
7 KiB
Diff
278 lines
7 KiB
Diff
---
|
|
security/Makefile | 2
|
|
security/foobar/Makefile | 1
|
|
security/foobar/foobar.c | 257 +++++++++++++++++++++++++++++++++++++++++++++++
|
|
3 files changed, 260 insertions(+)
|
|
|
|
--- a/security/Makefile
|
|
+++ b/security/Makefile
|
|
@@ -16,3 +16,5 @@ obj-$(CONFIG_SECURITY) += security.o d
|
|
obj-$(CONFIG_SECURITY_SELINUX) += selinux/built-in.o
|
|
obj-$(CONFIG_SECURITY_CAPABILITIES) += commoncap.o capability.o
|
|
obj-$(CONFIG_SECURITY_ROOTPLUG) += commoncap.o root_plug.o
|
|
+
|
|
+subdir-$(CONFIG_SECURITY) += foobar
|
|
--- /dev/null
|
|
+++ b/security/foobar/Makefile
|
|
@@ -0,0 +1 @@
|
|
+obj-m += foobar.o
|
|
--- /dev/null
|
|
+++ b/security/foobar/foobar.c
|
|
@@ -0,0 +1,257 @@
|
|
+#include <linux/security.h>
|
|
+#include <linux/module.h>
|
|
+#include <linux/namei.h>
|
|
+
|
|
+#define log_path(dentry, mnt, fmt...) \
|
|
+ __log_path(__FUNCTION__, dentry, mnt, NULL, ##fmt)
|
|
+
|
|
+#define log_path_inode(inode, fmt...) \
|
|
+ __log_path(__FUNCTION__, NULL, NULL, inode, ##fmt)
|
|
+
|
|
+static int show_traversals;
|
|
+module_param(show_traversals, bool, 0644);
|
|
+
|
|
+static void __log_path(const char *op, struct dentry *dentry,
|
|
+ struct vfsmount *mnt, struct inode *inode,
|
|
+ char *fmt, ...)
|
|
+{
|
|
+ va_list ap;
|
|
+ char *page = NULL, *name = "<?>";
|
|
+
|
|
+ page = (char *)__get_free_page(GFP_KERNEL);
|
|
+ if (!page)
|
|
+ name = "<ENOMEM>";
|
|
+ else if (mnt) {
|
|
+ name = d_path(dentry, mnt, page + 1, PAGE_SIZE - 2);
|
|
+ if (IS_ERR(name)) {
|
|
+ snprintf(page, PAGE_SIZE, "<%ld>", PTR_ERR(name));
|
|
+ name = page;
|
|
+ } else {
|
|
+ page[PAGE_SIZE - 2] = '"';
|
|
+ page[PAGE_SIZE - 1] = '\0';
|
|
+ *--name = '"';
|
|
+ }
|
|
+ } else if (dentry) {
|
|
+ snprintf(page, PAGE_SIZE, "<%s>", dentry->d_name.name);
|
|
+ name = page;
|
|
+ } else if (inode) {
|
|
+ snprintf(page, PAGE_SIZE, "<%s:%ld>",
|
|
+ inode->i_sb->s_type->name,
|
|
+ inode->i_ino);
|
|
+ name = page;
|
|
+ }
|
|
+
|
|
+ if (fmt) {
|
|
+ char *buffer = (char *)__get_free_page(GFP_KERNEL);
|
|
+
|
|
+ if (buffer) {
|
|
+ int n;
|
|
+
|
|
+ n = snprintf(buffer, PAGE_SIZE, KERN_INFO "%s(%s, ",
|
|
+ op, name);
|
|
+ va_start(ap, fmt);
|
|
+ n += vsnprintf(buffer + n, PAGE_SIZE - n, fmt, ap);
|
|
+ va_end(ap);
|
|
+ snprintf(buffer + n, PAGE_SIZE - n, ")\n");
|
|
+ printk("%s", buffer);
|
|
+
|
|
+ free_page((unsigned long)buffer);
|
|
+ } else
|
|
+ printk("%s: Out of memory\n", __FUNCTION__);
|
|
+ } else
|
|
+ printk(KERN_INFO "%s(%s)\n", op, name);
|
|
+
|
|
+ free_page((unsigned long)page);
|
|
+}
|
|
+
|
|
+static int foobar_inode_mkdir(struct inode *inode, struct dentry *dentry,
|
|
+ struct vfsmount *mnt, int mask)
|
|
+{
|
|
+ log_path(dentry, mnt, NULL);
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+static int foobar_inode_rmdir(struct inode *inode, struct dentry *dentry,
|
|
+ struct vfsmount *mnt)
|
|
+{
|
|
+ log_path(dentry, mnt, NULL);
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+static int foobar_inode_create(struct inode *inode, struct dentry *dentry,
|
|
+ struct vfsmount *mnt, int mask)
|
|
+{
|
|
+ log_path(dentry, mnt, NULL);
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+static int foobar_inode_link(struct dentry *old_dentry,
|
|
+ struct vfsmount *old_mnt,
|
|
+ struct inode *inode,
|
|
+ struct dentry *new_dentry,
|
|
+ struct vfsmount *new_mnt)
|
|
+{
|
|
+ log_path(old_dentry, old_mnt, "<old>");
|
|
+ log_path(new_dentry, new_mnt, "<new>");
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+static int foobar_inode_unlink(struct inode *dir, struct dentry *dentry,
|
|
+ struct vfsmount *mnt)
|
|
+{
|
|
+ log_path(dentry, mnt, NULL);
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+static int foobar_inode_mknod(struct inode *inode, struct dentry *dentry,
|
|
+ struct vfsmount *mnt, int mode, dev_t dev)
|
|
+{
|
|
+ log_path(dentry, mnt, NULL);
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+static int foobar_inode_rename(struct inode *old_inode,
|
|
+ struct dentry *old_dentry,
|
|
+ struct vfsmount *old_mnt,
|
|
+ struct inode *new_inode,
|
|
+ struct dentry *new_dentry,
|
|
+ struct vfsmount *new_mnt)
|
|
+{
|
|
+ log_path(old_dentry, old_mnt, "<old>");
|
|
+ log_path(new_dentry, new_mnt, "<new>");
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+static int foobar_inode_setattr(struct dentry *dentry, struct vfsmount *mnt,
|
|
+ struct iattr *iattr)
|
|
+{
|
|
+ log_path(dentry, mnt, NULL);
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+static int foobar_inode_setxattr(struct dentry *dentry, struct vfsmount *mnt,
|
|
+ char *name, void *value, size_t size,
|
|
+ int flags, struct file *file)
|
|
+{
|
|
+ log_path(dentry, mnt, NULL);
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+static int foobar_inode_getxattr(struct dentry *dentry,
|
|
+ struct vfsmount *mnt, char *name, struct file *file)
|
|
+{
|
|
+ log_path(dentry, mnt, NULL);
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+static int foobar_inode_listxattr(struct dentry *dentry,
|
|
+ struct vfsmount *mnt, struct file *file)
|
|
+{
|
|
+ log_path(dentry, mnt, NULL);
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+static int foobar_inode_removexattr(struct dentry *dentry,
|
|
+ struct vfsmount *mnt, char *name, struct file *file)
|
|
+{
|
|
+ log_path(dentry, mnt, NULL);
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+static int foobar_inode_symlink(struct inode *dir,
|
|
+ struct dentry *dentry, struct vfsmount *mnt,
|
|
+ const char *old_name)
|
|
+{
|
|
+ log_path(dentry, mnt, NULL);
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+static int foobar_inode_permission(struct inode *inode, int mask,
|
|
+ struct nameidata *nd)
|
|
+{
|
|
+ if (nd && (nd->flags & (LOOKUP_PARENT | LOOKUP_CONTINUE)) &&
|
|
+ !show_traversals)
|
|
+ return 0;
|
|
+
|
|
+ if (nd) {
|
|
+ char *parent = "", *sep="", *cont = "";
|
|
+
|
|
+ if (nd->flags & LOOKUP_PARENT)
|
|
+ parent = "LOOKUP_PARENT";
|
|
+ if (nd->flags & LOOKUP_CONTINUE)
|
|
+ cont = "LOOKUP_CONTINUE";
|
|
+ if ((nd->flags & (LOOKUP_PARENT | LOOKUP_CONTINUE)) ==
|
|
+ (LOOKUP_PARENT | LOOKUP_CONTINUE))
|
|
+ sep = ", ";
|
|
+ else if (!(nd->flags & (LOOKUP_PARENT | LOOKUP_CONTINUE)))
|
|
+ sep = "0";
|
|
+
|
|
+ log_path(nd->dentry, nd->mnt, "%c%c%c%c, %s%s%s",
|
|
+ mask & MAY_READ ? 'r' : '-',
|
|
+ mask & MAY_WRITE ? 'w' : '-',
|
|
+ mask & MAY_EXEC ? 'x' : '-',
|
|
+ mask & MAY_APPEND ? 'a' : '-',
|
|
+ parent, sep, cont);
|
|
+ } else {
|
|
+ log_path_inode(inode, "%c%c%c%c, 0",
|
|
+ mask & MAY_READ ? 'r' : '-',
|
|
+ mask & MAY_WRITE ? 'w' : '-',
|
|
+ mask & MAY_EXEC ? 'x' : '-',
|
|
+ mask & MAY_APPEND ? 'a' : '-');
|
|
+ }
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+struct security_operations foobar_ops = {
|
|
+ .inode_create = foobar_inode_create,
|
|
+ .inode_link = foobar_inode_link,
|
|
+ .inode_unlink = foobar_inode_unlink,
|
|
+ .inode_mkdir = foobar_inode_mkdir,
|
|
+ .inode_rmdir = foobar_inode_rmdir,
|
|
+ .inode_mknod = foobar_inode_mknod,
|
|
+ .inode_rename = foobar_inode_rename,
|
|
+ .inode_setattr = foobar_inode_setattr,
|
|
+ .inode_setxattr = foobar_inode_setxattr,
|
|
+ .inode_getxattr = foobar_inode_getxattr,
|
|
+ .inode_listxattr = foobar_inode_listxattr,
|
|
+ .inode_removexattr = foobar_inode_removexattr,
|
|
+ .inode_symlink = foobar_inode_symlink,
|
|
+ .inode_permission = foobar_inode_permission,
|
|
+};
|
|
+
|
|
+static int __init foobar_init(void)
|
|
+{
|
|
+ int error;
|
|
+
|
|
+ error = register_security(&foobar_ops);
|
|
+ if (error)
|
|
+ printk(KERN_ERR "Unable to load foobar lsm\n");
|
|
+
|
|
+ return error;
|
|
+}
|
|
+
|
|
+static void __exit foobar_exit(void)
|
|
+{
|
|
+ if (unregister_security(&foobar_ops))
|
|
+ printk(KERN_ERR "Unable to properly unregister foobar lsm\n");
|
|
+}
|
|
+
|
|
+module_init(foobar_init);
|
|
+module_exit(foobar_exit);
|
|
+
|
|
+MODULE_DESCRIPTION("lsm module logging to syslog");
|
|
+MODULE_LICENSE("GPL");
|