2
0
mirror of https://gitlab.com/apparmor/apparmor synced 2025-08-31 06:16:03 +00:00

- Patches we are working on for submitting upstream.

This commit is contained in:
Andreas Gruenbacher
2007-01-10 06:33:09 +00:00
parent 38c621e337
commit 6422fe41c4
36 changed files with 12927 additions and 0 deletions

View File

@@ -0,0 +1,58 @@
From: tonyj@suse.de
Subject: Export audit subsystem for use by modules
Patch-mainline: no
Adds necessary export symbols for audit subsystem routines.
Changes audit_log_vformat to be externally visible (analagous to vprintf)
Patch is not in mainline -- pending AppArmor code submission to lkml
---
include/linux/audit.h | 5 +++++
kernel/audit.c | 6 ++++--
2 files changed, 9 insertions(+), 2 deletions(-)
Index: linux-2.6.19/include/linux/audit.h
===================================================================
--- linux-2.6.19.orig/include/linux/audit.h
+++ linux-2.6.19/include/linux/audit.h
@@ -106,6 +106,8 @@
#define AUDIT_LAST_KERN_ANOM_MSG 1799
#define AUDIT_ANOM_PROMISCUOUS 1700 /* Device changed promiscuous mode */
+#define AUDIT_SD 1500 /* AppArmor (SubDomain) audit */
+
#define AUDIT_KERNEL 2000 /* Asynchronous audit record. NOT A REQUEST. */
/* Rule flags */
@@ -472,6 +474,9 @@ extern void audit_log(struct audit_
__attribute__((format(printf,4,5)));
extern struct audit_buffer *audit_log_start(struct audit_context *ctx, gfp_t gfp_mask, int type);
+extern void audit_log_vformat(struct audit_buffer *ab,
+ const char *fmt, va_list args)
+ __attribute__((format(printf,2,0)));
extern void audit_log_format(struct audit_buffer *ab,
const char *fmt, ...)
__attribute__((format(printf,2,3)));
Index: linux-2.6.19/kernel/audit.c
===================================================================
--- linux-2.6.19.orig/kernel/audit.c
+++ linux-2.6.19/kernel/audit.c
@@ -955,8 +955,7 @@ static inline int audit_expand(struct au
* will be called a second time. Currently, we assume that a printk
* can't format message larger than 1024 bytes, so we don't either.
*/
-static void audit_log_vformat(struct audit_buffer *ab, const char *fmt,
- va_list args)
+void audit_log_vformat(struct audit_buffer *ab, const char *fmt, va_list args)
{
int len, avail;
struct sk_buff *skb;
@@ -1212,3 +1211,6 @@ EXPORT_SYMBOL(audit_log_start);
EXPORT_SYMBOL(audit_log_end);
EXPORT_SYMBOL(audit_log_format);
EXPORT_SYMBOL(audit_log);
+EXPORT_SYMBOL_GPL(audit_log_vformat);
+EXPORT_SYMBOL_GPL(audit_log_untrustedstring);
+EXPORT_SYMBOL_GPL(audit_log_d_path);

View File

@@ -0,0 +1,32 @@
Index: linux-2.6.19/security/apparmor/lsm.c
===================================================================
--- linux-2.6.19.orig/security/apparmor/lsm.c
+++ linux-2.6.19/security/apparmor/lsm.c
@@ -23,6 +23,15 @@
/* struct subdomain write update lock (read side is RCU). */
spinlock_t sd_lock = SPIN_LOCK_UNLOCKED;
+/* Boottime disable flag */
+int apparmor_enabled=1;
+static int __init apparmor_enabled_setup(char *str)
+{
+ apparmor_enabled = simple_strtol(str, NULL, 0);
+ return 1;
+}
+__setup("apparmor=", apparmor_enabled_setup);
+
/* Flag values, also controllable via apparmorfs/control.
* We explicitly do not allow these to be modifiable when exported via
* /sys/modules/parameters, as we want to do additional mediation and
@@ -827,6 +836,11 @@ static int __init apparmor_init(void)
int error;
const char *complainmsg = ": complainmode enabled";
+ if (!apparmor_enabled) {
+ AA_INFO("AppArmor: Disabled by boottime parameter\n");
+ return 0;
+ }
+
if ((error = create_apparmorfs())) {
AA_ERROR("Unable to activate AppArmor filesystem\n");
goto createfs_out;

View File

@@ -0,0 +1,139 @@
Index: linux-2.6.19/security/apparmor/Kconfig
===================================================================
--- linux-2.6.19.orig/security/apparmor/Kconfig
+++ linux-2.6.19/security/apparmor/Kconfig
@@ -1,8 +1,9 @@
config SECURITY_APPARMOR
- tristate "AppArmor support"
- depends on SECURITY!=n
+ bool "AppArmor support"
+ depends on SECURITY && AUDIT
+ default n
help
- This enables the AppArmor security module.
+ This enables the AppArmor security module (built-in only).
Required userspace tools (if they are not included in your
distribution) and further information may be found at
<http://forge.novell.com/modules/xfmod/project/?apparmor>
Index: linux-2.6.19/security/apparmor/lsm.c
===================================================================
--- linux-2.6.19.orig/security/apparmor/lsm.c
+++ linux-2.6.19/security/apparmor/lsm.c
@@ -53,36 +53,6 @@ int apparmor_logsyscall = 0;
module_param_named(logsyscall, apparmor_logsyscall, int, S_IRUSR);
MODULE_PARM_DESC(apparmor_logsyscall, "Toggle AppArmor logsyscall mode");
-#ifndef MODULE
-static int __init aa_getopt_complain(char *str)
-{
- get_option(&str, &apparmor_complain);
- return 1;
-}
-__setup("apparmor_complain=", aa_getopt_complain);
-
-static int __init aa_getopt_debug(char *str)
-{
- get_option(&str, &apparmor_debug);
- return 1;
-}
-__setup("apparmor_debug=", aa_getopt_debug);
-
-static int __init aa_getopt_audit(char *str)
-{
- get_option(&str, &apparmor_audit);
- return 1;
-}
-__setup("apparmor_audit=", aa_getopt_audit);
-
-static int __init aa_getopt_logsyscall(char *str)
-{
- get_option(&str, &apparmor_logsyscall);
- return 1;
-}
-__setup("apparmor_logsyscall=", aa_getopt_logsyscall);
-#endif
-
static int apparmor_ptrace(struct task_struct *parent,
struct task_struct *child)
{
@@ -891,67 +861,4 @@ createfs_out:
}
-static int apparmor_exit_removeall_iter(struct subdomain *sd, void *cookie)
-{
- /* spin_lock(&sd_lock) held here */
-
- if (__aa_is_confined(sd)) {
- AA_DEBUG("%s: Dropping profiles %s(%d) "
- "profile %s(%p) active %s(%p)\n",
- __FUNCTION__,
- sd->task->comm, sd->task->pid,
- BASE_PROFILE(sd->active)->name,
- BASE_PROFILE(sd->active),
- sd->active->name, sd->active);
- aa_switch_unconfined(sd);
- }
-
- return 0;
-}
-
-static void __exit apparmor_exit(void)
-{
- unsigned long flags;
-
- /* Remove profiles from the global profile list.
- * This is just for tidyness as there is no way to reference this
- * list once the AppArmor lsm hooks are detached (below)
- */
- aa_profilelist_release();
-
- /* Remove profiles from active tasks
- * If this is not done, if module is reloaded after being removed,
- * old profiles (still refcounted in memory) will become 'magically'
- * reattached
- */
-
- spin_lock_irqsave(&sd_lock, flags);
- aa_subdomainlist_iterate(apparmor_exit_removeall_iter, NULL);
- spin_unlock_irqrestore(&sd_lock, flags);
-
- /* Free up list of active subdomain */
- aa_subdomainlist_release();
-
- free_null_complain_profile();
-
- destroy_apparmorfs();
-
- if (unregister_security(&apparmor_ops))
- AA_WARN("Unable to properly unregister AppArmor\n");
-
- /* delay for an rcu cycle to make ensure that profiles pending
- * destruction in the rcu callback are freed.
- */
- synchronize_rcu();
-
- AA_INFO("AppArmor protection removed\n");
- aa_audit_message(NULL, GFP_KERNEL, 0,
- "AppArmor protection removed\n");
-}
-
module_init(apparmor_init);
-module_exit(apparmor_exit);
-
-MODULE_DESCRIPTION("AppArmor process confinement");
-MODULE_AUTHOR("Tony Jones <tonyj@suse.de>");
-MODULE_LICENSE("GPL");
Index: linux-2.6.19/security/Makefile
===================================================================
--- linux-2.6.19.orig/security/Makefile
+++ linux-2.6.19/security/Makefile
@@ -16,7 +16,7 @@ obj-$(CONFIG_SECURITY) += security.o d
# Must precede capability.o in order to stack properly.
obj-$(CONFIG_SECURITY_SELINUX) += selinux/built-in.o
ifeq ($(CONFIG_SECURITY_APPARMOR),y)
-obj-$(CONFIG_SECURITY_APPARMOR) += apparmor/built-in.o
+obj-$(CONFIG_SECURITY_APPARMOR) += apparmor/built-in.o commoncap.o
endif
obj-$(CONFIG_SECURITY_CAPABILITIES) += commoncap.o capability.o
obj-$(CONFIG_SECURITY_ROOTPLUG) += commoncap.o root_plug.o

View File

@@ -0,0 +1,33 @@
Index: linux-2.6.19/security/Kconfig
===================================================================
--- linux-2.6.19.orig/security/Kconfig
+++ linux-2.6.19/security/Kconfig
@@ -94,6 +94,7 @@ config SECURITY_ROOTPLUG
If you are unsure how to answer this question, answer N.
source security/selinux/Kconfig
+source security/apparmor/Kconfig
endmenu
Index: linux-2.6.19/security/Makefile
===================================================================
--- linux-2.6.19.orig/security/Makefile
+++ linux-2.6.19/security/Makefile
@@ -4,6 +4,7 @@
obj-$(CONFIG_KEYS) += keys/
subdir-$(CONFIG_SECURITY_SELINUX) += selinux
+subdir-$(CONFIG_SECURITY_APPARMOR) += apparmor
# if we don't select a security model, use the default capabilities
ifneq ($(CONFIG_SECURITY),y)
@@ -14,5 +15,8 @@ endif
obj-$(CONFIG_SECURITY) += security.o dummy.o inode.o
# Must precede capability.o in order to stack properly.
obj-$(CONFIG_SECURITY_SELINUX) += selinux/built-in.o
+ifeq ($(CONFIG_SECURITY_APPARMOR),y)
+obj-$(CONFIG_SECURITY_APPARMOR) += apparmor/built-in.o
+endif
obj-$(CONFIG_SECURITY_CAPABILITIES) += commoncap.o capability.o
obj-$(CONFIG_SECURITY_ROOTPLUG) += commoncap.o root_plug.o

View File

@@ -0,0 +1,455 @@
Index: linux-2.6.19/security/apparmor/apparmor.h
===================================================================
--- linux-2.6.19.orig/security/apparmor/apparmor.h
+++ linux-2.6.19/security/apparmor/apparmor.h
@@ -25,17 +25,6 @@ extern int apparmor_debug;
extern int apparmor_audit;
extern int apparmor_logsyscall;
-/* PIPEFS_MAGIC */
-#include <linux/pipe_fs_i.h>
-/* from net/socket.c */
-#define SOCKFS_MAGIC 0x534F434B
-/* from inotify.c */
-#define INOTIFYFS_MAGIC 0xBAD1DEA
-
-#define VALID_FSTYPE(inode) ((inode)->i_sb->s_magic != PIPEFS_MAGIC && \
- (inode)->i_sb->s_magic != SOCKFS_MAGIC && \
- (inode)->i_sb->s_magic != INOTIFYFS_MAGIC)
-
#define PROFILE_COMPLAIN(_profile) \
(apparmor_complain == 1 || ((_profile) && (_profile)->flags.complain))
@@ -102,7 +91,8 @@ struct aa_entry {
struct list_head listp[POS_AA_FILE_MAX + 1];
};
-#define AA_SECURE_EXEC_NEEDED 0x00000001
+#define AA_MEDIATE_FS (void*)0x00000001
+#define AA_SECURE_EXEC_NEEDED 0x00000001
#define AA_EXEC_MODIFIER_MASK(mask) ((mask) & AA_EXEC_MODIFIERS)
#define AA_EXEC_MASK(mask) ((mask) & (AA_MAY_EXEC | AA_EXEC_MODIFIERS))
@@ -151,21 +141,6 @@ struct aaprofile {
struct kref count;
};
-enum aafile_type {
- aa_file_default,
- aa_file_shmem
-};
-
-/**
- * aafile - file pointer confinement data
- *
- * Data structure assigned to each open file (by apparmor_file_alloc_security)
- */
-struct aafile {
- enum aafile_type type;
- struct aaprofile *profile;
-};
-
/**
* struct subdomain - primary label for confined tasks
* @active: the current active profile
Index: linux-2.6.19/security/apparmor/lsm.c
===================================================================
--- linux-2.6.19.orig/security/apparmor/lsm.c
+++ linux-2.6.19/security/apparmor/lsm.c
@@ -202,6 +202,9 @@ static int apparmor_sb_mount(char *dev_n
if (active) {
error = aa_audit_syscallreject(active, GFP_KERNEL, "mount");
WARN_ON(error != -EPERM);
+ } else {
+ AA_ERROR("labelling volume %s\n", nd->mnt->mnt_sb->s_id);
+ nd->mnt->mnt_sb->s_security = AA_MEDIATE_FS;
}
put_aaprofile(active);
@@ -219,6 +222,8 @@ static int apparmor_umount(struct vfsmou
if (active) {
error = aa_audit_syscallreject(active, GFP_ATOMIC, "umount");
WARN_ON(error != -EPERM);
+ } else {
+ mnt->mnt_sb->s_security = NULL;
}
put_aaprofile(active);
@@ -226,13 +231,13 @@ static int apparmor_umount(struct vfsmou
return error;
}
-static int apparmor_inode_mkdir(struct inode *inode, struct vfsmount *mnt,
+static int apparmor_inode_mkdir(struct inode *dir, struct vfsmount *mnt,
struct dentry *dentry, int mask)
{
struct aaprofile *active;
int error = 0;
- if (!mnt)
+ if (!mnt || dir->i_sb->s_security != AA_MEDIATE_FS)
goto out;
active = get_active_aaprofile();
@@ -246,13 +251,13 @@ out:
return error;
}
-static int apparmor_inode_rmdir(struct inode *inode, struct vfsmount *mnt,
+static int apparmor_inode_rmdir(struct inode *dir, struct vfsmount *mnt,
struct dentry *dentry)
{
struct aaprofile *active;
int error = 0;
- if (!mnt)
+ if (!mnt || dir->i_sb->s_security != AA_MEDIATE_FS)
goto out;
active = get_active_aaprofile();
@@ -266,13 +271,13 @@ out:
return error;
}
-static int apparmor_inode_create(struct inode *inode, struct vfsmount *mnt,
+static int apparmor_inode_create(struct inode *dir, struct vfsmount *mnt,
struct dentry *dentry, int mask)
{
struct aaprofile *active;
int error = 0;
- if (!mnt)
+ if (!mnt || dir->i_sb->s_security != AA_MEDIATE_FS)
goto out;
active = get_active_aaprofile();
@@ -287,14 +292,14 @@ out:
}
static int apparmor_inode_link(struct vfsmount *old_mnt,
- struct dentry *old_dentry, struct inode *inode,
+ struct dentry *old_dentry, struct inode *dir,
struct vfsmount *new_mnt,
struct dentry *new_dentry)
{
int error = 0;
struct aaprofile *active;
- if (!old_mnt || !new_mnt)
+ if (!old_mnt || !new_mnt || dir->i_sb->s_security != AA_MEDIATE_FS)
goto out;
active = get_active_aaprofile();
@@ -315,7 +320,7 @@ static int apparmor_inode_unlink(struct
struct aaprofile *active;
int error = 0;
- if (!mnt)
+ if (!mnt || dentry->d_inode->i_sb->s_security != AA_MEDIATE_FS)
goto out;
active = get_active_aaprofile();
@@ -329,13 +334,13 @@ out:
return error;
}
-static int apparmor_inode_mknod(struct inode *inode, struct vfsmount *mnt,
+static int apparmor_inode_mknod(struct inode *dir, struct vfsmount *mnt,
struct dentry *dentry, int mode, dev_t dev)
{
struct aaprofile *active;
int error = 0;
- if (!mnt)
+ if (!mnt || dir->i_sb->s_security != AA_MEDIATE_FS)
goto out;
active = get_active_aaprofile();
@@ -349,10 +354,10 @@ out:
return error;
}
-static int apparmor_inode_rename(struct inode *old_inode,
+static int apparmor_inode_rename(struct inode *old_dir,
struct vfsmount *old_mnt,
struct dentry *old_dentry,
- struct inode *new_inode,
+ struct inode *new_dir,
struct vfsmount *new_mnt,
struct dentry *new_dentry)
{
@@ -365,11 +370,12 @@ static int apparmor_inode_rename(struct
active = get_active_aaprofile();
if (active) {
- if (old_mnt)
+ if (old_mnt && old_dir->i_sb->s_security == AA_MEDIATE_FS)
error = aa_perm(active, old_dentry, old_mnt,
MAY_READ|MAY_WRITE);
- if (!error && new_mnt)
+ if (!error && new_mnt &&
+ new_dir->i_sb->s_security == AA_MEDIATE_FS)
error = aa_perm(active, new_dentry, new_mnt,
MAY_WRITE);
}
@@ -388,7 +394,7 @@ static int apparmor_inode_permission(str
/* Do not perform check on pipes or sockets
* Same as apparmor_file_permission
*/
- if (nd && VALID_FSTYPE(inode)) {
+ if (nd && inode->i_sb->s_security == AA_MEDIATE_FS) {
struct aaprofile *active;
active = get_active_aaprofile();
@@ -404,23 +410,21 @@ static int apparmor_inode_setattr(struct
struct iattr *iattr)
{
int error = 0;
+ struct aaprofile *active;
- if (!mnt)
+ if (!mnt || dentry->d_inode->i_sb->s_security != AA_MEDIATE_FS)
goto out;
- if (VALID_FSTYPE(dentry->d_inode)) {
- struct aaprofile *active;
+ active = get_active_aaprofile();
- active = get_active_aaprofile();
- /*
- * Mediate any attempt to change attributes of a file
- * (chmod, chown, chgrp, etc)
- */
- if (active)
- error = aa_attr(active, dentry, mnt, iattr);
+ /*
+ * Mediate any attempt to change attributes of a file
+ * (chmod, chown, chgrp, etc)
+ */
+ if (active)
+ error = aa_attr(active, dentry, mnt, iattr);
- put_aaprofile(active);
- }
+ put_aaprofile(active);
out:
return error;
@@ -431,19 +435,16 @@ static int apparmor_inode_setxattr(struc
int flags)
{
int error = 0;
+ struct aaprofile *active;
- if (!mnt)
+ if (!mnt || dentry->d_inode->i_sb->s_security != AA_MEDIATE_FS)
goto out;
- if (VALID_FSTYPE(dentry->d_inode)) {
- struct aaprofile *active;
-
- active = get_active_aaprofile();
- if (active)
- error = aa_xattr(active, dentry, mnt, name,
- aa_xattr_set);
- put_aaprofile(active);
- }
+ active = get_active_aaprofile();
+ if (active)
+ error = aa_xattr(active, dentry, mnt, name,
+ aa_xattr_set);
+ put_aaprofile(active);
out:
return error;
@@ -453,19 +454,17 @@ static int apparmor_inode_getxattr(struc
char *name)
{
int error = 0;
+ struct aaprofile *active;
- if (!mnt)
+ if (!mnt || dentry->d_inode->i_sb->s_security != AA_MEDIATE_FS)
goto out;
- if (VALID_FSTYPE(dentry->d_inode)) {
- struct aaprofile *active;
- active = get_active_aaprofile();
- if (active)
- error = aa_xattr(active, dentry, mnt, name,
- aa_xattr_get);
- put_aaprofile(active);
- }
+ active = get_active_aaprofile();
+ if (active)
+ error = aa_xattr(active, dentry, mnt, name,
+ aa_xattr_get);
+ put_aaprofile(active);
out:
return error;
@@ -473,19 +472,16 @@ out:
static int apparmor_inode_listxattr(struct vfsmount *mnt, struct dentry *dentry)
{
int error = 0;
+ struct aaprofile *active;
- if (!mnt)
+ if (!mnt || dentry->d_inode->i_sb->s_security != AA_MEDIATE_FS)
goto out;
- if (VALID_FSTYPE(dentry->d_inode)) {
- struct aaprofile *active;
-
- active = get_active_aaprofile();
- if (active)
- error = aa_xattr(active, dentry, mnt, NULL,
- aa_xattr_list);
- put_aaprofile(active);
- }
+ active = get_active_aaprofile();
+ if (active)
+ error = aa_xattr(active, dentry, mnt, NULL,
+ aa_xattr_list);
+ put_aaprofile(active);
out:
return error;
@@ -495,19 +491,16 @@ static int apparmor_inode_removexattr(st
struct dentry *dentry, char *name)
{
int error = 0;
+ struct aaprofile *active;
- if (!mnt)
+ if (!mnt || dentry->d_inode->i_sb->s_security != AA_MEDIATE_FS)
goto out;
- if (VALID_FSTYPE(dentry->d_inode)) {
- struct aaprofile *active;
-
- active = get_active_aaprofile();
- if (active)
- error = aa_xattr(active, dentry, mnt, name,
- aa_xattr_remove);
- put_aaprofile(active);
- }
+ active = get_active_aaprofile();
+ if (active)
+ error = aa_xattr(active, dentry, mnt, name,
+ aa_xattr_remove);
+ put_aaprofile(active);
out:
return error;
@@ -516,55 +509,36 @@ out:
static int apparmor_file_permission(struct file *file, int mask)
{
struct aaprofile *active;
- struct aafile *aaf;
int error = 0;
- aaf = (struct aafile *)file->f_security;
- /* bail out early if this isn't a mediated file */
- if (!aaf || !VALID_FSTYPE(file->f_dentry->d_inode))
- goto out;
-
- active = get_active_aaprofile();
- if (active && aaf->profile != active)
- error = aa_perm(active, file->f_dentry, file->f_vfsmnt,
- mask & (MAY_EXEC | MAY_WRITE | MAY_READ));
- put_aaprofile(active);
+ if (file->f_vfsmnt->mnt_sb->s_security == AA_MEDIATE_FS &&
+ file->f_security) {
+ active = get_active_aaprofile();
+ if (active && (struct aaprofile*)file->f_security != active)
+ error = aa_perm(active, file->f_dentry, file->f_vfsmnt,
+ mask & (MAY_EXEC|MAY_WRITE|MAY_READ));
+ put_aaprofile(active);
+ }
-out:
return error;
}
static int apparmor_file_alloc_security(struct file *file)
{
struct aaprofile *active;
- int error = 0;
active = get_active_aaprofile();
- if (active) {
- struct aafile *aaf;
- aaf = kmalloc(sizeof(struct aafile), GFP_KERNEL);
+ if (active)
+ file->f_security = get_aaprofile(active);
- if (aaf) {
- aaf->type = aa_file_default;
- aaf->profile = get_aaprofile(active);
- } else {
- error = -ENOMEM;
- }
- file->f_security = aaf;
- }
put_aaprofile(active);
- return error;
+ return 0;
}
static void apparmor_file_free_security(struct file *file)
{
- struct aafile *aaf = (struct aafile *)file->f_security;
-
- if (aaf) {
- put_aaprofile(aaf->profile);
- kfree(aaf);
- }
+ put_aaprofile((struct aaprofile *)file->f_security);
}
static inline int aa_mmap(struct file *file, unsigned long prot,
@@ -572,12 +546,10 @@ static inline int aa_mmap(struct file *f
{
int error = 0, mask = 0;
struct aaprofile *active;
- struct aafile *aaf;
active = get_active_aaprofile();
if (!active || !file ||
- !(aaf = (struct aafile *)file->f_security) ||
- aaf->type == aa_file_shmem)
+ file->f_vfsmnt->mnt_sb->s_security != AA_MEDIATE_FS)
goto out;
if (prot & PROT_READ)
@@ -636,17 +608,6 @@ static void apparmor_task_reparent_to_in
return;
}
-static int apparmor_shm_shmat(struct shmid_kernel *shp, char __user *shmaddr,
- int shmflg)
-{
- struct aafile *aaf = (struct aafile *)shp->shm_file->f_security;
-
- if (aaf)
- aaf->type = aa_file_shmem;
-
- return 0;
-}
-
static int apparmor_getprocattr(struct task_struct *p, char *name, void *value,
size_t size)
{
@@ -829,8 +790,6 @@ struct security_operations apparmor_ops
.task_post_setuid = apparmor_task_post_setuid,
.task_reparent_to_init = apparmor_task_reparent_to_init,
- .shm_shmat = apparmor_shm_shmat,
-
.getprocattr = apparmor_getprocattr,
.setprocattr = apparmor_setprocattr,
};

View File

@@ -0,0 +1,963 @@
Index: linux-2.6.19/security/apparmor/apparmor.h
===================================================================
--- linux-2.6.19.orig/security/apparmor/apparmor.h
+++ linux-2.6.19/security/apparmor/apparmor.h
@@ -188,16 +188,6 @@ struct subdomain {
typedef int (*aa_iter) (struct subdomain *, void *);
-/* aa_path_data
- * temp (cookie) data used by aa_path_* functions, see inline.h
- */
-struct aa_path_data {
- struct dentry *root, *dentry;
- struct namespace *namespace;
- struct list_head *head, *pos;
- int errno;
-};
-
#define AA_SUBDOMAIN(sec) ((struct subdomain*)(sec))
#define AA_PROFILE(sec) ((struct aaprofile*)(sec))
@@ -281,20 +271,18 @@ extern int aa_audit(struct aaprofile *ac
extern char *aa_get_name(struct dentry *dentry, struct vfsmount *mnt);
extern int aa_attr(struct aaprofile *active, struct dentry *dentry,
- struct iattr *iattr);
+ struct vfsmount *mnt, struct iattr *iattr);
extern int aa_xattr(struct aaprofile *active, struct dentry *dentry,
+ struct vfsmount *mnt,
const char *xattr, enum aa_xattroptype xattroptype);
extern int aa_capability(struct aaprofile *active, int cap);
extern int aa_perm(struct aaprofile *active, struct dentry *dentry,
struct vfsmount *mnt, int mask);
-extern int aa_perm_nameidata(struct aaprofile *active, struct nameidata *nd,
- int mask);
-extern int aa_perm_dentry(struct aaprofile *active, struct dentry *dentry,
- int mask);
extern int aa_perm_dir(struct aaprofile *active, struct dentry *dentry,
- enum aa_diroptype diroptype);
+ struct vfsmount *mnt, enum aa_diroptype diroptype);
extern int aa_link(struct aaprofile *active,
- struct dentry *link, struct dentry *target);
+ struct dentry *link, struct vfsmount *link_mnt,
+ struct dentry *target, struct vfsmount *target_mnt);
extern int aa_fork(struct task_struct *p);
extern int aa_register(struct linux_binprm *bprm);
extern void aa_release(struct task_struct *p);
Index: linux-2.6.19/security/apparmor/inline.h
===================================================================
--- linux-2.6.19.orig/security/apparmor/inline.h
+++ linux-2.6.19/security/apparmor/inline.h
@@ -252,84 +252,4 @@ static inline struct aaprofile *__aa_fin
}
return NULL;
}
-
-/** __aa_path_begin
- * @rdentry: filesystem root dentry (searching for vfsmnts matching this)
- * @dentry: dentry object to obtain pathname from (relative to matched vfsmnt)
- *
- * Setup data for iterating over vfsmounts (in current tasks namespace).
- */
-static inline void __aa_path_begin(struct dentry *rdentry,
- struct dentry *dentry,
- struct aa_path_data *data)
-{
- data->dentry = dentry;
- data->root = dget(rdentry->d_sb->s_root);
- data->namespace = current->namespace;
- data->head = &data->namespace->list;
- data->pos = data->head->next;
- prefetch(data->pos->next);
- data->errno = 0;
-
- down_read(&namespace_sem);
-}
-
-/** aa_path_begin
- * @dentry: filesystem root dentry and object to obtain pathname from
- *
- * Utility function for calling _aa_path_begin for when the dentry we are
- * looking for and the root are the same (this is the usual case).
- */
-static inline void aa_path_begin(struct dentry *dentry,
- struct aa_path_data *data)
-{
- __aa_path_begin(dentry, dentry, data);
-}
-
-/** aa_path_end
- * @data: data object previously initialized by aa_path_begin
- *
- * End iterating over vfsmounts.
- * If an error occured in begin or get, it is returned. Otherwise 0.
- */
-static inline int aa_path_end(struct aa_path_data *data)
-{
- up_read(&namespace_sem);
- dput(data->root);
-
- return data->errno;
-}
-
-/** aa_path_getname
- * @data: data object previously initialized by aa_path_begin
- *
- * Return the next mountpoint which has the same root dentry as data->root.
- * If no more mount points exist (or in case of error) NULL is returned
- * (caller should call aa_path_end() and inspect return code to differentiate)
- */
-static inline char *aa_path_getname(struct aa_path_data *data)
-{
- char *name = NULL;
- struct vfsmount *mnt;
-
- while (data->pos != data->head) {
- mnt = list_entry(data->pos, struct vfsmount, mnt_list);
-
- /* advance to next -- so that it is done before we break */
- data->pos = data->pos->next;
- prefetch(data->pos->next);
-
- if (mnt->mnt_root == data->root) {
- name = aa_get_name(data->dentry, mnt);
- if (IS_ERR(name)) {
- data->errno = PTR_ERR(name);
- name = NULL;
- }
- break;
- }
- }
-
- return name;
-}
-
#endif /* __INLINE_H__ */
Index: linux-2.6.19/security/apparmor/lsm.c
===================================================================
--- linux-2.6.19.orig/security/apparmor/lsm.c
+++ linux-2.6.19/security/apparmor/lsm.c
@@ -15,6 +15,7 @@
#include <linux/module.h>
#include <linux/mm.h>
#include <linux/mman.h>
+#include <linux/namei.h>
#include "apparmor.h"
#include "inline.h"
@@ -246,122 +247,157 @@ static int apparmor_umount(struct vfsmou
return error;
}
-static int apparmor_inode_mkdir(struct inode *inode, struct dentry *dentry,
- int mask)
+static int apparmor_inode_mkdir(struct inode *inode, struct vfsmount *mnt,
+ struct dentry *dentry, int mask)
{
struct aaprofile *active;
int error = 0;
+ if (!mnt)
+ goto out;
+
active = get_active_aaprofile();
if (active)
- error = aa_perm_dir(active, dentry, aa_dir_mkdir);
+ error = aa_perm_dir(active, dentry, mnt, aa_dir_mkdir);
put_aaprofile(active);
+out:
return error;
}
-static int apparmor_inode_rmdir(struct inode *inode, struct dentry *dentry)
+static int apparmor_inode_rmdir(struct inode *inode, struct vfsmount *mnt,
+ struct dentry *dentry)
{
struct aaprofile *active;
int error = 0;
+ if (!mnt)
+ goto out;
+
active = get_active_aaprofile();
if (active)
- error = aa_perm_dir(active, dentry, aa_dir_rmdir);
+ error = aa_perm_dir(active, dentry, mnt, aa_dir_rmdir);
put_aaprofile(active);
+out:
return error;
}
-static int apparmor_inode_create(struct inode *inode, struct dentry *dentry,
- int mask)
+static int apparmor_inode_create(struct inode *inode, struct vfsmount *mnt,
+ struct dentry *dentry, int mask)
{
struct aaprofile *active;
int error = 0;
+ if (!mnt)
+ goto out;
+
active = get_active_aaprofile();
/* At a minimum, need write perm to create */
if (active)
- error = aa_perm_dentry(active, dentry, MAY_WRITE);
+ error = aa_perm(active, dentry, mnt, MAY_WRITE);
put_aaprofile(active);
-
+out:
return error;
}
-static int apparmor_inode_link(struct dentry *old_dentry, struct inode *inode,
- struct dentry *new_dentry)
+static int apparmor_inode_link(struct vfsmount *old_mnt,
+ struct dentry *old_dentry, struct inode *inode,
+ struct vfsmount *new_mnt,
+ struct dentry *new_dentry)
{
int error = 0;
struct aaprofile *active;
+ if (!old_mnt || !new_mnt)
+ goto out;
+
active = get_active_aaprofile();
if (active)
- error = aa_link(active, new_dentry, old_dentry);
+ error = aa_link(active, new_dentry, new_mnt,
+ old_dentry, old_mnt);
put_aaprofile(active);
+out:
return error;
}
-static int apparmor_inode_unlink(struct inode *inode, struct dentry *dentry)
+static int apparmor_inode_unlink(struct inode *dir, struct vfsmount *mnt,
+ struct dentry *dentry)
{
struct aaprofile *active;
int error = 0;
+ if (!mnt)
+ goto out;
+
active = get_active_aaprofile();
if (active)
- error = aa_perm_dentry(active, dentry, MAY_WRITE);
+ error = aa_perm(active, dentry, mnt, MAY_WRITE);
put_aaprofile(active);
+out:
return error;
}
-static int apparmor_inode_mknod(struct inode *inode, struct dentry *dentry,
- int mode, dev_t dev)
+static int apparmor_inode_mknod(struct inode *inode, struct vfsmount *mnt,
+ struct dentry *dentry, int mode, dev_t dev)
{
struct aaprofile *active;
int error = 0;
+ if (!mnt)
+ goto out;
+
active = get_active_aaprofile();
if (active)
- error = aa_perm_dentry(active, dentry, MAY_WRITE);
+ error = aa_perm(active, dentry, mnt, MAY_WRITE);
put_aaprofile(active);
+out:
return error;
}
static int apparmor_inode_rename(struct inode *old_inode,
- struct dentry *old_dentry,
- struct inode *new_inode,
- struct dentry *new_dentry)
+ struct vfsmount *old_mnt,
+ struct dentry *old_dentry,
+ struct inode *new_inode,
+ struct vfsmount *new_mnt,
+ struct dentry *new_dentry)
{
struct aaprofile *active;
int error = 0;
+ if (!old_mnt && !new_mnt)
+ goto out;
+
active = get_active_aaprofile();
if (active) {
- error = aa_perm_dentry(active, old_dentry, MAY_READ |
- MAY_WRITE);
-
- if (!error)
- error = aa_perm_dentry(active, new_dentry,
- MAY_WRITE);
+ if (old_mnt)
+ error = aa_perm(active, old_dentry, old_mnt,
+ MAY_READ|MAY_WRITE);
+
+ if (!error && new_mnt)
+ error = aa_perm(active, new_dentry, new_mnt,
+ MAY_WRITE);
}
put_aaprofile(active);
+out:
return error;
}
@@ -373,22 +409,26 @@ static int apparmor_inode_permission(str
/* Do not perform check on pipes or sockets
* Same as apparmor_file_permission
*/
- if (VALID_FSTYPE(inode)) {
+ if (nd && VALID_FSTYPE(inode)) {
struct aaprofile *active;
active = get_active_aaprofile();
if (active)
- error = aa_perm_nameidata(active, nd, mask);
+ error = aa_perm(active, nd->dentry, nd->mnt, mask);
put_aaprofile(active);
}
return error;
}
-static int apparmor_inode_setattr(struct dentry *dentry, struct iattr *iattr)
+static int apparmor_inode_setattr(struct vfsmount *mnt, struct dentry *dentry,
+ struct iattr *iattr)
{
int error = 0;
+ if (!mnt)
+ goto out;
+
if (VALID_FSTYPE(dentry->d_inode)) {
struct aaprofile *active;
@@ -398,76 +438,99 @@ static int apparmor_inode_setattr(struct
* (chmod, chown, chgrp, etc)
*/
if (active)
- error = aa_attr(active, dentry, iattr);
+ error = aa_attr(active, dentry, mnt, iattr);
put_aaprofile(active);
}
+out:
return error;
}
-static int apparmor_inode_setxattr(struct dentry *dentry, char *name,
- void *value, size_t size, int flags)
+static int apparmor_inode_setxattr(struct vfsmount *mnt, struct dentry *dentry,
+ char *name, void *value, size_t size,
+ int flags)
{
int error = 0;
+ if (!mnt)
+ goto out;
+
if (VALID_FSTYPE(dentry->d_inode)) {
struct aaprofile *active;
active = get_active_aaprofile();
if (active)
- error = aa_xattr(active, dentry, name, aa_xattr_set);
+ error = aa_xattr(active, dentry, mnt, name,
+ aa_xattr_set);
put_aaprofile(active);
}
+out:
return error;
}
-static int apparmor_inode_getxattr(struct dentry *dentry, char *name)
+static int apparmor_inode_getxattr(struct vfsmount *mnt, struct dentry *dentry,
+ char *name)
{
int error = 0;
+ if (!mnt)
+ goto out;
+
if (VALID_FSTYPE(dentry->d_inode)) {
struct aaprofile *active;
active = get_active_aaprofile();
if (active)
- error = aa_xattr(active, dentry, name, aa_xattr_get);
+ error = aa_xattr(active, dentry, mnt, name,
+ aa_xattr_get);
put_aaprofile(active);
}
+out:
return error;
}
-static int apparmor_inode_listxattr(struct dentry *dentry)
+static int apparmor_inode_listxattr(struct vfsmount *mnt, struct dentry *dentry)
{
int error = 0;
+ if (!mnt)
+ goto out;
+
if (VALID_FSTYPE(dentry->d_inode)) {
struct aaprofile *active;
active = get_active_aaprofile();
if (active)
- error = aa_xattr(active, dentry, NULL, aa_xattr_list);
+ error = aa_xattr(active, dentry, mnt, NULL,
+ aa_xattr_list);
put_aaprofile(active);
}
+out:
return error;
}
-static int apparmor_inode_removexattr(struct dentry *dentry, char *name)
+static int apparmor_inode_removexattr(struct vfsmount *mnt,
+ struct dentry *dentry, char *name)
{
int error = 0;
+ if (!mnt)
+ goto out;
+
if (VALID_FSTYPE(dentry->d_inode)) {
struct aaprofile *active;
active = get_active_aaprofile();
if (active)
- error = aa_xattr(active, dentry, name,
+ error = aa_xattr(active, dentry, mnt, name,
aa_xattr_remove);
put_aaprofile(active);
}
+out:
return error;
}
Index: linux-2.6.19/security/apparmor/main.c
===================================================================
--- linux-2.6.19.orig/security/apparmor/main.c
+++ linux-2.6.19/security/apparmor/main.c
@@ -35,34 +35,6 @@ struct aaprofile *null_complain_profile;
**************************/
/**
- * dentry_xlate_error
- * @dentry: pointer to dentry
- * @error: error number
- * @dtype: type of dentry
- *
- * Display error message when a dentry translation error occured
- */
-static void dentry_xlate_error(struct dentry *dentry, int error, char *dtype)
-{
- const unsigned int len = 16;
- char buf[len];
-
- if (dentry->d_inode) {
- snprintf(buf, len, "%lu", dentry->d_inode->i_ino);
- } else {
- strncpy(buf, "<negative>", len);
- buf[len-1]=0;
- }
-
- AA_ERROR("An error occured while translating %s %p "
- "inode# %s to a pathname. Error %d\n",
- dtype,
- dentry,
- buf,
- error);
-}
-
-/**
* aa_taskattr_access
* @procrelname: name of file to check permission
*
@@ -345,12 +317,12 @@ done:
*
* Look up permission mode on both @link and @target. @link must have same
* permission mode as @target. At least @link must have the link bit enabled.
- * Return %0 on success, error otherwise.
+ * Return %0 on success, else -EPERM
*/
static int aa_link_perm(struct aaprofile *active,
const char *link, const char *target)
{
- int l_mode, t_mode, ret;
+ int l_mode, t_mode, ret = -EPERM;
l_mode = aa_file_mode(active, link);
if (l_mode & AA_MAY_LINK) {
@@ -360,76 +332,32 @@ static int aa_link_perm(struct aaprofile
t_mode = aa_file_mode(active, target);
t_mode &= ~AA_MAY_LINK;
- ret = (l_mode == t_mode);
- } else {
- ret = 0;
+ if (l_mode == t_mode)
+ ret = 0;
}
return ret;
}
-/**
- * _aa_perm_dentry
- * @active: profile to check against
- * @dentry: requested dentry
- * @mask: mask of requested operations
- * @pname: pointer to hold matched pathname (if any)
- *
- * Helper function. Obtain pathname for specified dentry. Verify if profile
- * authorizes mask operations on pathname (due to lack of vfsmnt it is sadly
- * necessary to search mountpoints in namespace -- when nameidata is passed
- * more fully, this code can go away). If more than one mountpoint matches
- * but none satisfy the profile, only the first pathname (mountpoint) is
- * returned for subsequent logging.
- *
- * Return %0 (success), +ve (mask of permissions not satisfied) or -ve (system
- * error, most likely -%ENOMEM).
- */
-static int _aa_perm_dentry(struct aaprofile *active, struct dentry *dentry,
- int mask, const char **pname)
+static int _aa_perm_vfsmount(struct aaprofile *active, struct dentry *dentry,
+ struct vfsmount *mnt, struct aa_audit *sa, int mask)
{
- char *name = NULL, *failed_name = NULL;
- struct aa_path_data data;
- int error = 0, failed_error = 0, path_error,
- complain = PROFILE_COMPLAIN(active);
-
- /* search all paths to dentry */
-
- aa_path_begin(dentry, &data);
- do {
- name = aa_path_getname(&data);
- if (name) {
- /* error here is 0 (success) or +ve (mask of perms) */
- error = aa_file_perm(active, name, mask);
-
- /* access via any path is enough */
- if (complain || error == 0)
- break; /* Caller must free name */
-
- /* Already have an path that failed? */
- if (failed_name) {
- aa_put_name(name);
- } else {
- failed_name = name;
- failed_error = error;
- }
- }
- } while (name);
+ int permerror, error;
+
+ sa->name = aa_get_name(dentry, mnt);
- if ((path_error = aa_path_end(&data)) != 0) {
- dentry_xlate_error(dentry, path_error, "dentry");
- WARN_ON(name); /* name should not be set if error */
- error = path_error;
- name = NULL;
- } else if (name) {
- if (failed_name)
- aa_put_name(failed_name);
+ if (IS_ERR(sa->name)) {
+ permerror = PTR_ERR(sa->name);
+ sa->name = NULL;
} else {
- name = failed_name;
- error = failed_error;
+ permerror = aa_file_perm(active, sa->name, mask);
}
- *pname = name;
+ aa_permerror2result(permerror, sa);
+
+ error = aa_audit(active, sa);
+
+ aa_put_name(sa->name);
return error;
}
@@ -803,9 +731,9 @@ out:
* @iattr: attribute changes requested
*/
int aa_attr(struct aaprofile *active, struct dentry *dentry,
- struct iattr *iattr)
+ struct vfsmount *mnt, struct iattr *iattr)
{
- int error = 0, permerror;
+ int error;
struct aa_audit sa;
sa.type = AA_AUDITTYPE_ATTR;
@@ -813,12 +741,7 @@ int aa_attr(struct aaprofile *active, st
sa.flags = 0;
sa.gfp_mask = GFP_KERNEL;
- permerror = _aa_perm_dentry(active, dentry, MAY_WRITE, &sa.name);
- aa_permerror2result(permerror, &sa);
-
- error = aa_audit(active, &sa);
-
- aa_put_name(sa.name);
+ error = _aa_perm_vfsmount(active, dentry, mnt, &sa, MAY_WRITE);
return error;
}
@@ -831,15 +754,12 @@ int aa_attr(struct aaprofile *active, st
* @xattroptype: type of xattr operation
*/
int aa_xattr(struct aaprofile *active, struct dentry *dentry,
- const char *xattr, enum aa_xattroptype xattroptype)
+ struct vfsmount *mnt, const char *xattr,
+ enum aa_xattroptype xattroptype)
{
- int error = 0, permerror, mask = 0;
+ int error = 0, mask = 0;
struct aa_audit sa;
- /* if not confined or empty mask permission granted */
- if (!active)
- goto out;
-
if (xattroptype == aa_xattr_get || xattroptype == aa_xattr_list)
mask = MAY_READ;
else if (xattroptype == aa_xattr_set || xattroptype == aa_xattr_remove)
@@ -851,14 +771,8 @@ int aa_xattr(struct aaprofile *active, s
sa.flags = 0;
sa.gfp_mask = GFP_KERNEL;
- permerror = _aa_perm_dentry(active, dentry, mask, &sa.name);
- aa_permerror2result(permerror, &sa);
-
- error = aa_audit(active, &sa);
-
- aa_put_name(sa.name);
+ error = _aa_perm_vfsmount(active, dentry, mnt, &sa, mask);
-out:
return error;
}
@@ -875,71 +789,9 @@ out:
int aa_perm(struct aaprofile *active, struct dentry *dentry,
struct vfsmount *mnt, int mask)
{
- int error = 0, permerror;
- struct aa_audit sa;
-
- if (!active)
- goto out;
-
- if ((mask = aa_filter_mask(mask, dentry->d_inode)) == 0)
- goto out;
-
- sa.type = AA_AUDITTYPE_FILE;
- sa.name = aa_get_name(dentry, mnt);
- sa.ival = mask;
- sa.flags = 0;
- sa.gfp_mask = GFP_KERNEL;
-
- if (IS_ERR(sa.name)) {
- permerror = PTR_ERR(sa.name);
- sa.name = NULL;
- } else {
- permerror = aa_file_perm(active, sa.name, mask);
- }
-
- aa_permerror2result(permerror, &sa);
-
- error = aa_audit(active, &sa);
-
- aa_put_name(sa.name);
-
-out:
- return error;
-}
-
-/**
- * aa_perm_nameidata: interface to sd_perm accepting nameidata
- * @active: profile to check against
- * @nd: namespace data (for vfsmnt and dentry)
- * @mask: access mode requested
- */
-int aa_perm_nameidata(struct aaprofile *active, struct nameidata *nd, int mask)
-{
int error = 0;
-
- if (nd)
- error = aa_perm(active, nd->dentry, nd->mnt, mask);
-
- return error;
-}
-
-/**
- * aa_perm_dentry - file permissions interface when no vfsmnt available
- * @active: profile to check against
- * @dentry: requested dentry
- * @mask: access mode requested
- *
- * Determine if access (mask) for dentry is authorized by active profile.
- * Result, %0 (success), -ve (error)
- */
-int aa_perm_dentry(struct aaprofile *active, struct dentry *dentry, int mask)
-{
- int error = 0, permerror;
struct aa_audit sa;
- if (!active)
- goto out;
-
if ((mask = aa_filter_mask(mask, dentry->d_inode)) == 0)
goto out;
@@ -947,13 +799,7 @@ int aa_perm_dentry(struct aaprofile *act
sa.ival = mask;
sa.flags = 0;
sa.gfp_mask = GFP_KERNEL;
-
- permerror = _aa_perm_dentry(active, dentry, mask, &sa.name);
- aa_permerror2result(permerror, &sa);
-
- error = aa_audit(active, &sa);
-
- aa_put_name(sa.name);
+ error = _aa_perm_vfsmount(active, dentry, mnt, &sa, mask);
out:
return error;
@@ -964,22 +810,20 @@ out:
* @active: profile to check against
* @dentry: requested dentry
* @diroptype: aa_dir_mkdir or aa_dir_rmdir
+ * @mnt: vfsmount
*
* Determine if directory operation (make/remove) for dentry is authorized
* by @active profile.
* Result, %0 (success), -ve (error)
*/
int aa_perm_dir(struct aaprofile *active, struct dentry *dentry,
- enum aa_diroptype diroptype)
+ struct vfsmount *mnt, enum aa_diroptype diroptype)
{
- int error = 0, permerror, mask;
+ int error = 0, mask;
struct aa_audit sa;
WARN_ON(diroptype != aa_dir_mkdir && diroptype != aa_dir_rmdir);
- if (!active)
- goto out;
-
mask = MAY_WRITE;
sa.type = AA_AUDITTYPE_DIR;
@@ -987,14 +831,8 @@ int aa_perm_dir(struct aaprofile *active
sa.flags = 0;
sa.gfp_mask = GFP_KERNEL;
- permerror = _aa_perm_dentry(active, dentry, mask, &sa.name);
- aa_permerror2result(permerror, &sa);
-
- error = aa_audit(active, &sa);
+ error = _aa_perm_vfsmount(active, dentry, mnt, &sa, MAY_WRITE);
- aa_put_name(sa.name);
-
-out:
return error;
}
@@ -1009,7 +847,6 @@ out:
int aa_capability(struct aaprofile *active, int cap)
{
int error = 0;
-
struct aa_audit sa;
sa.type = AA_AUDITTYPE_CAP;
@@ -1030,124 +867,42 @@ int aa_capability(struct aaprofile *acti
* @active: profile to check against
* @link: dentry for link being created
* @target: dentry for link target
- *
- * Checks link permissions for all possible name combinations. This is
- * particularly ugly. Returns %0 on sucess, error otherwise.
+ * @mnt: vfsmount (-EXDEV is link and target are not on same vfsmount)
*/
-int aa_link(struct aaprofile *active, struct dentry *link,
- struct dentry *target)
+int aa_link(struct aaprofile *active,
+ struct dentry *link, struct vfsmount *link_mnt,
+ struct dentry *target, struct vfsmount *target_mnt)
{
- char *iname = NULL, *oname = NULL,
- *failed_iname = NULL, *failed_oname = NULL;
- unsigned int result = 0;
- int error, path_error, error_code = 0, match = 0,
- complain = PROFILE_COMPLAIN(active);
- struct aa_path_data idata, odata;
+ int permerror = -EPERM, error;
struct aa_audit sa;
- if (!active)
- return 0;
-
- /* Perform nested lookup for names.
- * This is necessary in the case where /dev/block is mounted
- * multiple times, i.e /dev/block->/a and /dev/block->/b
- * This allows us to detect links where src/dest are on different
- * mounts. N.B no support yet for links across bind mounts of
- * the form mount -bind /mnt/subpath /mnt2
- *
- * Getting direct access to vfsmounts (via nameidata) for link and
- * target would allow all this uglyness to go away.
- *
- * If more than one mountpoint matches but none satisfy the profile,
- * only the first pathname (mountpoint) is logged.
- */
-
- __aa_path_begin(target, link, &odata);
- do {
- oname = aa_path_getname(&odata);
- if (oname) {
- aa_path_begin(target, &idata);
- do {
- iname = aa_path_getname(&idata);
- if (iname) {
- result = aa_link_perm(active, oname,
- iname);
-
- /* access via any path is enough */
- if (result || complain) {
- match = 1;
- break;
- }
-
- /* Already have an path that failed? */
- if (failed_iname) {
- aa_put_name(iname);
- } else {
- failed_iname = iname;
- failed_oname = oname;
- }
- }
- } while (iname && !match);
-
- /* should not be possible if we matched */
- if ((path_error = aa_path_end(&idata)) != 0) {
- dentry_xlate_error(target, path_error,
- "inner dentry [link]");
-
- /* name should not be set if error */
- WARN_ON(iname);
-
- error_code = path_error;
- }
-
- /* don't release if we're saving it */
- if (!match && failed_oname != oname)
- aa_put_name(oname);
- }
- } while (oname && !match);
+ sa.name = aa_get_name(link, link_mnt);
+ sa.pval = aa_get_name(target, target_mnt);
- if (error_code != 0) {
- /* inner error */
- (void)aa_path_end(&odata);
- } else if ((path_error = aa_path_end(&odata)) != 0) {
- dentry_xlate_error(link, path_error, "outer dentry [link]");
- error_code = path_error;
+ if (IS_ERR(sa.name)) {
+ permerror = PTR_ERR(sa.name);
+ sa.name = NULL;
}
-
- if (error_code != 0) {
- /* inner or outer error */
- result = 0;
- } else if (match) {
- result = 1;
- } else {
- /* failed to match */
- WARN_ON(iname);
- WARN_ON(oname);
-
- result = 0;
- iname = failed_iname;
- oname = failed_oname;
+ if (IS_ERR(sa.pval)) {
+ permerror = PTR_ERR(sa.pval);
+ sa.pval = NULL;
}
+ if (sa.name && sa.pval)
+ permerror = aa_link_perm(active, sa.name, sa.pval);
+
+ aa_permerror2result(permerror, &sa);
+
sa.type = AA_AUDITTYPE_LINK;
- sa.name = oname; /* link */
- sa.pval = iname; /* target */
sa.flags = 0;
- sa.error_code = error_code;
- sa.result = result;
sa.gfp_mask = GFP_KERNEL;
error = aa_audit(active, &sa);
- if (failed_oname != oname)
- aa_put_name(failed_oname);
- if (failed_iname != iname)
- aa_put_name(failed_iname);
-
- aa_put_name(oname);
- aa_put_name(iname);
+ aa_put_name(sa.name);
+ aa_put_name(sa.pval);
- return error;
+ return error;
}
/*******************************

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,26 @@
Remove redundant check from proc_setattr()
notify_change() already calls security_inode_setattr() before
calling iop->setattr.
Signed-off-by: Tony Jones <tonyj@suse.de>
Signed-off-by: Andreas Gruenbacher <agruen@suse.de>
Index: linux-2.6.19/fs/proc/base.c
===================================================================
--- linux-2.6.19.orig/fs/proc/base.c
+++ linux-2.6.19/fs/proc/base.c
@@ -344,11 +344,8 @@ static int proc_setattr(struct dentry *d
return -EPERM;
error = inode_change_ok(inode, attr);
- if (!error) {
- error = security_inode_setattr(dentry, attr);
- if (!error)
- error = inode_setattr(inode, attr);
- }
+ if (!error)
+ error = inode_setattr(inode, attr);
return error;
}

View File

@@ -0,0 +1,169 @@
Pass struct file down to remove_suid and children
We always call remove_suid for a specific struct file. Pass this
struct down into remove_suid and children instead of the dentry
of the file. We can then call notify_change() with the vfsmount
and dentry of the file (next patch).
Signed-off-by: Tony Jones <tonyj@suse.de>
Signed-off-by: Andreas Gruenbacher <agruen@suse.de>
Index: linux-2.6.19/mm/filemap.c
===================================================================
--- linux-2.6.19.orig/mm/filemap.c
+++ linux-2.6.19/mm/filemap.c
@@ -1872,9 +1872,9 @@ repeat:
* if suid or (sgid and xgrp)
* remove privs
*/
-int should_remove_suid(struct dentry *dentry)
+int should_remove_suid(struct file *file)
{
- mode_t mode = dentry->d_inode->i_mode;
+ mode_t mode = file->f_dentry->d_inode->i_mode;
int kill = 0;
/* suid always must be killed */
@@ -1894,20 +1894,20 @@ int should_remove_suid(struct dentry *de
return 0;
}
-int __remove_suid(struct dentry *dentry, int kill)
+int __remove_suid(struct file *file, int kill)
{
struct iattr newattrs;
newattrs.ia_valid = ATTR_FORCE | kill;
- return notify_change(dentry, &newattrs);
+ return notify_change(file->f_dentry, &newattrs);
}
-int remove_suid(struct dentry *dentry)
+int remove_suid(struct file *file)
{
- int kill = should_remove_suid(dentry);
+ int kill = should_remove_suid(file);
if (unlikely(kill))
- return __remove_suid(dentry, kill);
+ return __remove_suid(file, kill);
return 0;
}
@@ -2269,7 +2269,7 @@ __generic_file_aio_write_nolock(struct k
if (count == 0)
goto out;
- err = remove_suid(file->f_dentry);
+ err = remove_suid(file);
if (err)
goto out;
Index: linux-2.6.19/fs/ntfs/file.c
===================================================================
--- linux-2.6.19.orig/fs/ntfs/file.c
+++ linux-2.6.19/fs/ntfs/file.c
@@ -2162,7 +2162,7 @@ static ssize_t ntfs_file_aio_write_noloc
goto out;
if (!count)
goto out;
- err = remove_suid(file->f_dentry);
+ err = remove_suid(file);
if (err)
goto out;
file_update_time(file);
Index: linux-2.6.19/fs/reiserfs/file.c
===================================================================
--- linux-2.6.19.orig/fs/reiserfs/file.c
+++ linux-2.6.19/fs/reiserfs/file.c
@@ -1378,7 +1378,7 @@ static ssize_t reiserfs_file_write(struc
if (count == 0)
goto out;
- res = remove_suid(file->f_dentry);
+ res = remove_suid(file);
if (res)
goto out;
Index: linux-2.6.19/fs/splice.c
===================================================================
--- linux-2.6.19.orig/fs/splice.c
+++ linux-2.6.19/fs/splice.c
@@ -844,7 +844,7 @@ generic_file_splice_write_nolock(struct
ssize_t ret;
int err;
- err = remove_suid(out->f_dentry);
+ err = remove_suid(out);
if (unlikely(err))
return err;
@@ -890,10 +890,10 @@ generic_file_splice_write(struct pipe_in
ssize_t ret;
int err;
- err = should_remove_suid(out->f_dentry);
+ err = should_remove_suid(out);
if (unlikely(err)) {
mutex_lock(&inode->i_mutex);
- err = __remove_suid(out->f_dentry, err);
+ err = __remove_suid(out, err);
mutex_unlock(&inode->i_mutex);
if (err)
return err;
Index: linux-2.6.19/fs/xfs/linux-2.6/xfs_lrw.c
===================================================================
--- linux-2.6.19.orig/fs/xfs/linux-2.6/xfs_lrw.c
+++ linux-2.6.19/fs/xfs/linux-2.6/xfs_lrw.c
@@ -805,7 +805,7 @@ start:
!capable(CAP_FSETID)) {
error = xfs_write_clear_setuid(xip);
if (likely(!error))
- error = -remove_suid(file->f_dentry);
+ error = -remove_suid(file);
if (unlikely(error)) {
xfs_iunlock(xip, iolock);
goto out_unlock_mutex;
Index: linux-2.6.19/include/linux/fs.h
===================================================================
--- linux-2.6.19.orig/include/linux/fs.h
+++ linux-2.6.19/include/linux/fs.h
@@ -1712,9 +1712,9 @@ extern void __iget(struct inode * inode)
extern void clear_inode(struct inode *);
extern void destroy_inode(struct inode *);
extern struct inode *new_inode(struct super_block *);
-extern int __remove_suid(struct dentry *, int);
-extern int should_remove_suid(struct dentry *);
-extern int remove_suid(struct dentry *);
+extern int __remove_suid(struct file *, int);
+extern int should_remove_suid(struct file *);
+extern int remove_suid(struct file *);
extern void remove_dquot_ref(struct super_block *, int, struct list_head *);
extern void __insert_inode_hash(struct inode *, unsigned long hashval);
Index: linux-2.6.19/mm/filemap_xip.c
===================================================================
--- linux-2.6.19.orig/mm/filemap_xip.c
+++ linux-2.6.19/mm/filemap_xip.c
@@ -379,7 +379,7 @@ xip_file_write(struct file *filp, const
if (count == 0)
goto out_backing;
- ret = remove_suid(filp->f_dentry);
+ ret = remove_suid(filp);
if (ret)
goto out_backing;
Index: linux-2.6.19/mm/shmem.c
===================================================================
--- linux-2.6.19.orig/mm/shmem.c
+++ linux-2.6.19/mm/shmem.c
@@ -1442,7 +1442,7 @@ shmem_file_write(struct file *file, cons
if (err || !count)
goto out;
- err = remove_suid(file->f_dentry);
+ err = remove_suid(file);
if (err)
goto out;

View File

@@ -0,0 +1,91 @@
Pass struct vfsmount to the inode_create LSM hook.
Signed-off-by: Tony Jones <tonyj@suse.de>
Signed-off-by: Andreas Gruenbacher <agruen@suse.de>
Index: linux-2.6.19/fs/namei.c
===================================================================
--- linux-2.6.19.orig/fs/namei.c
+++ linux-2.6.19/fs/namei.c
@@ -1506,7 +1506,7 @@ int vfs_create(struct inode *dir, struct
return -EACCES; /* shouldn't it be ENOSYS? */
mode &= S_IALLUGO;
mode |= S_IFREG;
- error = security_inode_create(dir, dentry, mode);
+ error = security_inode_create(dir, nd ? nd->mnt : NULL, dentry, mode);
if (error)
return error;
DQUOT_INIT(dir);
Index: linux-2.6.19/include/linux/security.h
===================================================================
--- linux-2.6.19.orig/include/linux/security.h
+++ linux-2.6.19/include/linux/security.h
@@ -282,6 +282,7 @@ struct request_sock;
* @inode_create:
* Check permission to create a regular file.
* @dir contains inode structure of the parent of the new file.
+ * @mnt is the vfsmount of the new dentry (may be NULL)
* @dentry contains the dentry structure for the file to be created.
* @mode contains the file mode of the file to be created.
* Return 0 if permission is granted.
@@ -1212,7 +1213,7 @@ struct security_operations {
void (*inode_free_security) (struct inode *inode);
int (*inode_init_security) (struct inode *inode, struct inode *dir,
char **name, void **value, size_t *len);
- int (*inode_create) (struct inode *dir,
+ int (*inode_create) (struct inode *dir, struct vfsmount *mnt,
struct dentry *dentry, int mode);
int (*inode_link) (struct dentry *old_dentry,
struct inode *dir, struct dentry *new_dentry);
@@ -1619,12 +1620,13 @@ static inline int security_inode_init_se
}
static inline int security_inode_create (struct inode *dir,
+ struct vfsmount *mnt,
struct dentry *dentry,
int mode)
{
if (unlikely (IS_PRIVATE (dir)))
return 0;
- return security_ops->inode_create (dir, dentry, mode);
+ return security_ops->inode_create (dir, mnt, dentry, mode);
}
static inline int security_inode_link (struct dentry *old_dentry,
@@ -2346,6 +2348,7 @@ static inline int security_inode_init_se
}
static inline int security_inode_create (struct inode *dir,
+ struct vfsmount *mnt,
struct dentry *dentry,
int mode)
{
Index: linux-2.6.19/security/dummy.c
===================================================================
--- linux-2.6.19.orig/security/dummy.c
+++ linux-2.6.19/security/dummy.c
@@ -264,8 +264,8 @@ static int dummy_inode_init_security (st
return -EOPNOTSUPP;
}
-static int dummy_inode_create (struct inode *inode, struct dentry *dentry,
- int mask)
+static int dummy_inode_create (struct inode *inode, struct vfsmount *mnt,
+ struct dentry *dentry, int mask)
{
return 0;
}
Index: linux-2.6.19/security/selinux/hooks.c
===================================================================
--- linux-2.6.19.orig/security/selinux/hooks.c
+++ linux-2.6.19/security/selinux/hooks.c
@@ -2129,7 +2129,8 @@ static int selinux_inode_init_security(s
return 0;
}
-static int selinux_inode_create(struct inode *dir, struct dentry *dentry, int mask)
+static int selinux_inode_create(struct inode *dir, struct vfsmount *mnt,
+ struct dentry *dentry, int mask)
{
return may_create(dir, dentry, SECCLASS_FILE);
}

View File

@@ -0,0 +1,85 @@
Pass struct vfsmount to the inode_getxattr LSM hook
Signed-off-by: Tony Jones <tonyj@suse.de>
Signed-off-by: Andreas Gruenbacher <agruen@suse.de>
Index: linux-2.6.19/fs/xattr.c
===================================================================
--- linux-2.6.19.orig/fs/xattr.c
+++ linux-2.6.19/fs/xattr.c
@@ -117,7 +117,7 @@ vfs_getxattr(struct vfsmount *mnt, struc
if (error)
return error;
- error = security_inode_getxattr(dentry, name);
+ error = security_inode_getxattr(mnt, dentry, name);
if (error)
return error;
Index: linux-2.6.19/include/linux/security.h
===================================================================
--- linux-2.6.19.orig/include/linux/security.h
+++ linux-2.6.19/include/linux/security.h
@@ -1254,7 +1254,8 @@ struct security_operations {
char *name, void *value, size_t size, int flags);
void (*inode_post_setxattr) (struct dentry *dentry, char *name, void *value,
size_t size, int flags);
- int (*inode_getxattr) (struct dentry *dentry, char *name);
+ int (*inode_getxattr) (struct vfsmount *mnt, struct dentry *dentry,
+ char *name);
int (*inode_listxattr) (struct dentry *dentry);
int (*inode_removexattr) (struct dentry *dentry, char *name);
const char *(*inode_xattr_getsuffix) (void);
@@ -1787,11 +1788,12 @@ static inline void security_inode_post_s
security_ops->inode_post_setxattr (dentry, name, value, size, flags);
}
-static inline int security_inode_getxattr (struct dentry *dentry, char *name)
+static inline int security_inode_getxattr (struct vfsmount *mnt,
+ struct dentry *dentry, char *name)
{
if (unlikely (IS_PRIVATE (dentry->d_inode)))
return 0;
- return security_ops->inode_getxattr (dentry, name);
+ return security_ops->inode_getxattr (mnt, dentry, name);
}
static inline int security_inode_listxattr (struct dentry *dentry)
@@ -2489,7 +2491,8 @@ static inline void security_inode_post_s
void *value, size_t size, int flags)
{ }
-static inline int security_inode_getxattr (struct dentry *dentry, char *name)
+static inline int security_inode_getxattr (struct vfsmount *mnt,
+ struct dentry *dentry, char *name)
{
return 0;
}
Index: linux-2.6.19/security/dummy.c
===================================================================
--- linux-2.6.19.orig/security/dummy.c
+++ linux-2.6.19/security/dummy.c
@@ -366,7 +366,8 @@ static void dummy_inode_post_setxattr (s
{
}
-static int dummy_inode_getxattr (struct dentry *dentry, char *name)
+static int dummy_inode_getxattr (struct vfsmount *mnt, struct dentry *dentry,
+ char *name)
{
return 0;
}
Index: linux-2.6.19/security/selinux/hooks.c
===================================================================
--- linux-2.6.19.orig/security/selinux/hooks.c
+++ linux-2.6.19/security/selinux/hooks.c
@@ -2343,7 +2343,8 @@ static void selinux_inode_post_setxattr(
return;
}
-static int selinux_inode_getxattr (struct dentry *dentry, char *name)
+static int selinux_inode_getxattr (struct vfsmount *mnt, struct dentry *dentry,
+ char *name)
{
return dentry_has_perm(current, NULL, dentry, FILE__GETATTR);
}

View File

@@ -0,0 +1,114 @@
Pass the struct vfsmounts to the inode_link LSM hook
Signed-off-by: Tony Jones <tonyj@suse.de>
Signed-off-by: Andreas Gruenbacher <agruen@suse.de>
Index: linux-2.6.19/fs/namei.c
===================================================================
--- linux-2.6.19.orig/fs/namei.c
+++ linux-2.6.19/fs/namei.c
@@ -2279,7 +2279,8 @@ int vfs_link(struct vfsmount *old_mnt, s
if (S_ISDIR(old_dentry->d_inode->i_mode))
return -EPERM;
- error = security_inode_link(old_dentry, dir, new_dentry);
+ error = security_inode_link(old_mnt, old_dentry, dir, new_mnt,
+ new_dentry);
if (error)
return error;
Index: linux-2.6.19/include/linux/security.h
===================================================================
--- linux-2.6.19.orig/include/linux/security.h
+++ linux-2.6.19/include/linux/security.h
@@ -288,8 +288,10 @@ struct request_sock;
* Return 0 if permission is granted.
* @inode_link:
* Check permission before creating a new hard link to a file.
+ * @old_mnt is the vfsmount where @old_dentry was looked up (may be NULL)
* @old_dentry contains the dentry structure for an existing link to the file.
* @dir contains the inode structure of the parent directory of the new link.
+ * @new_mnt is the vfsmount for @new_dentry (may be NULL)
* @new_dentry contains the dentry structure for the new link.
* Return 0 if permission is granted.
* @inode_unlink:
@@ -1220,8 +1222,9 @@ struct security_operations {
char **name, void **value, size_t *len);
int (*inode_create) (struct inode *dir, struct vfsmount *mnt,
struct dentry *dentry, int mode);
- int (*inode_link) (struct dentry *old_dentry,
- struct inode *dir, struct dentry *new_dentry);
+ int (*inode_link) (struct vfsmount *old_mnt, struct dentry *old_dentry,
+ struct inode *dir, struct vfsmount *new_mnt,
+ struct dentry *new_dentry);
int (*inode_unlink) (struct inode *dir, struct dentry *dentry);
int (*inode_symlink) (struct inode *dir, struct vfsmount *mnt,
struct dentry *dentry, const char *old_name);
@@ -1636,13 +1639,16 @@ static inline int security_inode_create
return security_ops->inode_create (dir, mnt, dentry, mode);
}
-static inline int security_inode_link (struct dentry *old_dentry,
+static inline int security_inode_link (struct vfsmount *old_mnt,
+ struct dentry *old_dentry,
struct inode *dir,
+ struct vfsmount *new_mnt,
struct dentry *new_dentry)
{
if (unlikely (IS_PRIVATE (old_dentry->d_inode)))
return 0;
- return security_ops->inode_link (old_dentry, dir, new_dentry);
+ return security_ops->inode_link (old_mnt, old_dentry, dir,
+ new_mnt, new_dentry);
}
static inline int security_inode_unlink (struct inode *dir,
@@ -2367,8 +2373,10 @@ static inline int security_inode_create
return 0;
}
-static inline int security_inode_link (struct dentry *old_dentry,
+static inline int security_inode_link (struct vfsmount *old_mnt,
+ struct dentry *old_dentry,
struct inode *dir,
+ struct vfsmount *new_mnt,
struct dentry *new_dentry)
{
return 0;
Index: linux-2.6.19/security/dummy.c
===================================================================
--- linux-2.6.19.orig/security/dummy.c
+++ linux-2.6.19/security/dummy.c
@@ -270,7 +270,9 @@ static int dummy_inode_create (struct in
return 0;
}
-static int dummy_inode_link (struct dentry *old_dentry, struct inode *inode,
+static int dummy_inode_link (struct vfsmount *old_mnt,
+ struct dentry *old_dentry, struct inode *inode,
+ struct vfsmount *new_mnt,
struct dentry *new_dentry)
{
return 0;
Index: linux-2.6.19/security/selinux/hooks.c
===================================================================
--- linux-2.6.19.orig/security/selinux/hooks.c
+++ linux-2.6.19/security/selinux/hooks.c
@@ -2135,11 +2135,15 @@ static int selinux_inode_create(struct i
return may_create(dir, dentry, SECCLASS_FILE);
}
-static int selinux_inode_link(struct dentry *old_dentry, struct inode *dir, struct dentry *new_dentry)
+static int selinux_inode_link(struct vfsmount *old_mnt,
+ struct dentry *old_dentry, struct inode *dir,
+ struct vfsmount *new_mnt,
+ struct dentry *new_dentry)
{
int rc;
- rc = secondary_ops->inode_link(old_dentry,dir,new_dentry);
+ rc = secondary_ops->inode_link(old_mnt, old_dentry, dir, new_mnt,
+ new_dentry);
if (rc)
return rc;
return may_link(dir, old_dentry, MAY_LINK);

View File

@@ -0,0 +1,82 @@
Pass struct vfsmount to the inode_listxattr LSM hook
Signed-off-by: Tony Jones <tonyj@suse.de>
Signed-off-by: Andreas Gruenbacher <agruen@suse.de>
Index: linux-2.6.19/fs/xattr.c
===================================================================
--- linux-2.6.19.orig/fs/xattr.c
+++ linux-2.6.19/fs/xattr.c
@@ -150,7 +150,7 @@ vfs_listxattr(struct vfsmount *mnt, stru
struct inode *inode = dentry->d_inode;
ssize_t error;
- error = security_inode_listxattr(dentry);
+ error = security_inode_listxattr(mnt, dentry);
if (error)
return error;
error = -EOPNOTSUPP;
Index: linux-2.6.19/include/linux/security.h
===================================================================
--- linux-2.6.19.orig/include/linux/security.h
+++ linux-2.6.19/include/linux/security.h
@@ -1256,7 +1256,7 @@ struct security_operations {
size_t size, int flags);
int (*inode_getxattr) (struct vfsmount *mnt, struct dentry *dentry,
char *name);
- int (*inode_listxattr) (struct dentry *dentry);
+ int (*inode_listxattr) (struct vfsmount *mnt, struct dentry *dentry);
int (*inode_removexattr) (struct dentry *dentry, char *name);
const char *(*inode_xattr_getsuffix) (void);
int (*inode_getsecurity)(const struct inode *inode, const char *name, void *buffer, size_t size, int err);
@@ -1796,11 +1796,12 @@ static inline int security_inode_getxatt
return security_ops->inode_getxattr (mnt, dentry, name);
}
-static inline int security_inode_listxattr (struct dentry *dentry)
+static inline int security_inode_listxattr (struct vfsmount *mnt,
+ struct dentry *dentry)
{
if (unlikely (IS_PRIVATE (dentry->d_inode)))
return 0;
- return security_ops->inode_listxattr (dentry);
+ return security_ops->inode_listxattr (mnt, dentry);
}
static inline int security_inode_removexattr (struct dentry *dentry, char *name)
@@ -2497,7 +2498,8 @@ static inline int security_inode_getxatt
return 0;
}
-static inline int security_inode_listxattr (struct dentry *dentry)
+static inline int security_inode_listxattr (struct vfsmount *mnt,
+ struct dentry *dentry)
{
return 0;
}
Index: linux-2.6.19/security/dummy.c
===================================================================
--- linux-2.6.19.orig/security/dummy.c
+++ linux-2.6.19/security/dummy.c
@@ -372,7 +372,7 @@ static int dummy_inode_getxattr (struct
return 0;
}
-static int dummy_inode_listxattr (struct dentry *dentry)
+static int dummy_inode_listxattr (struct vfsmount *mnt, struct dentry *dentry)
{
return 0;
}
Index: linux-2.6.19/security/selinux/hooks.c
===================================================================
--- linux-2.6.19.orig/security/selinux/hooks.c
+++ linux-2.6.19/security/selinux/hooks.c
@@ -2349,7 +2349,7 @@ static int selinux_inode_getxattr (struc
return dentry_has_perm(current, NULL, dentry, FILE__GETATTR);
}
-static int selinux_inode_listxattr (struct dentry *dentry)
+static int selinux_inode_listxattr (struct vfsmount *mnt, struct dentry *dentry)
{
return dentry_has_perm(current, NULL, dentry, FILE__GETATTR);
}

View File

@@ -0,0 +1,92 @@
Pass struct vfsmount to the inode_mkdir LSM hook
Signed-off-by: Tony Jones <tonyj@suse.de>
Signed-off-by: Andreas Gruenbacher <agruen@suse.de>
Index: linux-2.6.19/fs/namei.c
===================================================================
--- linux-2.6.19.orig/fs/namei.c
+++ linux-2.6.19/fs/namei.c
@@ -1931,7 +1931,7 @@ int vfs_mkdir(struct inode *dir, struct
return -EPERM;
mode &= (S_IRWXUGO|S_ISVTX);
- error = security_inode_mkdir(dir, dentry, mode);
+ error = security_inode_mkdir(dir, mnt, dentry, mode);
if (error)
return error;
Index: linux-2.6.19/include/linux/security.h
===================================================================
--- linux-2.6.19.orig/include/linux/security.h
+++ linux-2.6.19/include/linux/security.h
@@ -307,6 +307,7 @@ struct request_sock;
* Check permissions to create a new directory in the existing directory
* associated with inode strcture @dir.
* @dir containst the inode structure of parent of the directory to be created.
+ * @mnt is the vfsmount of the new dentry (may be NULL)
* @dentry contains the dentry structure of new directory.
* @mode contains the mode of new directory.
* Return 0 if permission is granted.
@@ -1221,7 +1222,8 @@ struct security_operations {
int (*inode_unlink) (struct inode *dir, struct dentry *dentry);
int (*inode_symlink) (struct inode *dir,
struct dentry *dentry, const char *old_name);
- int (*inode_mkdir) (struct inode *dir, struct dentry *dentry, int mode);
+ int (*inode_mkdir) (struct inode *dir, struct vfsmount *mnt,
+ struct dentry *dentry, int mode);
int (*inode_rmdir) (struct inode *dir, struct dentry *dentry);
int (*inode_mknod) (struct inode *dir, struct dentry *dentry,
int mode, dev_t dev);
@@ -1658,12 +1660,13 @@ static inline int security_inode_symlink
}
static inline int security_inode_mkdir (struct inode *dir,
+ struct vfsmount *mnt,
struct dentry *dentry,
int mode)
{
if (unlikely (IS_PRIVATE (dir)))
return 0;
- return security_ops->inode_mkdir (dir, dentry, mode);
+ return security_ops->inode_mkdir (dir, mnt, dentry, mode);
}
static inline int security_inode_rmdir (struct inode *dir,
@@ -2379,6 +2382,7 @@ static inline int security_inode_symlink
}
static inline int security_inode_mkdir (struct inode *dir,
+ struct vfsmount *mnt,
struct dentry *dentry,
int mode)
{
Index: linux-2.6.19/security/dummy.c
===================================================================
--- linux-2.6.19.orig/security/dummy.c
+++ linux-2.6.19/security/dummy.c
@@ -287,8 +287,8 @@ static int dummy_inode_symlink (struct i
return 0;
}
-static int dummy_inode_mkdir (struct inode *inode, struct dentry *dentry,
- int mask)
+static int dummy_inode_mkdir (struct inode *inode, struct vfsmount *mnt,
+ struct dentry *dentry, int mask)
{
return 0;
}
Index: linux-2.6.19/security/selinux/hooks.c
===================================================================
--- linux-2.6.19.orig/security/selinux/hooks.c
+++ linux-2.6.19/security/selinux/hooks.c
@@ -2160,7 +2160,8 @@ static int selinux_inode_symlink(struct
return may_create(dir, dentry, SECCLASS_LNK_FILE);
}
-static int selinux_inode_mkdir(struct inode *dir, struct dentry *dentry, int mask)
+static int selinux_inode_mkdir(struct inode *dir, struct vfsmount *mnt,
+ struct dentry *dentry, int mask)
{
return may_create(dir, dentry, SECCLASS_DIR);
}

View File

@@ -0,0 +1,98 @@
Pass struct vfsmount to the inode_mknod LSM hook
Signed-off-by: Tony Jones <tonyj@suse.de>
Signed-off-by: Andreas Gruenbacher <agruen@suse.de>
Index: linux-2.6.19/fs/namei.c
===================================================================
--- linux-2.6.19.orig/fs/namei.c
+++ linux-2.6.19/fs/namei.c
@@ -1854,7 +1854,7 @@ int vfs_mknod(struct inode *dir, struct
if (!dir->i_op || !dir->i_op->mknod)
return -EPERM;
- error = security_inode_mknod(dir, dentry, mode, dev);
+ error = security_inode_mknod(dir, mnt, dentry, mode, dev);
if (error)
return error;
Index: linux-2.6.19/include/linux/security.h
===================================================================
--- linux-2.6.19.orig/include/linux/security.h
+++ linux-2.6.19/include/linux/security.h
@@ -322,6 +322,7 @@ struct request_sock;
* is being done for a regular file, then the create hook will be called
* and not this hook.
* @dir contains the inode structure of parent of the new file.
+ * @mnt is the vfsmount of the new dentry (may be NULL)
* @dentry contains the dentry structure of the new file.
* @mode contains the mode of the new file.
* @dev contains the the device number.
@@ -1225,8 +1226,8 @@ struct security_operations {
int (*inode_mkdir) (struct inode *dir, struct vfsmount *mnt,
struct dentry *dentry, int mode);
int (*inode_rmdir) (struct inode *dir, struct dentry *dentry);
- int (*inode_mknod) (struct inode *dir, struct dentry *dentry,
- int mode, dev_t dev);
+ int (*inode_mknod) (struct inode *dir, struct vfsmount *mnt,
+ struct dentry *dentry, int mode, dev_t dev);
int (*inode_rename) (struct inode *old_dir, struct dentry *old_dentry,
struct inode *new_dir, struct dentry *new_dentry);
int (*inode_readlink) (struct dentry *dentry);
@@ -1678,12 +1679,13 @@ static inline int security_inode_rmdir (
}
static inline int security_inode_mknod (struct inode *dir,
+ struct vfsmount *mnt,
struct dentry *dentry,
int mode, dev_t dev)
{
if (unlikely (IS_PRIVATE (dir)))
return 0;
- return security_ops->inode_mknod (dir, dentry, mode, dev);
+ return security_ops->inode_mknod (dir, mnt, dentry, mode, dev);
}
static inline int security_inode_rename (struct inode *old_dir,
@@ -2396,6 +2398,7 @@ static inline int security_inode_rmdir (
}
static inline int security_inode_mknod (struct inode *dir,
+ struct vfsmount *mnt,
struct dentry *dentry,
int mode, dev_t dev)
{
Index: linux-2.6.19/security/dummy.c
===================================================================
--- linux-2.6.19.orig/security/dummy.c
+++ linux-2.6.19/security/dummy.c
@@ -298,8 +298,8 @@ static int dummy_inode_rmdir (struct ino
return 0;
}
-static int dummy_inode_mknod (struct inode *inode, struct dentry *dentry,
- int mode, dev_t dev)
+static int dummy_inode_mknod (struct inode *inode, struct vfsmount *mnt,
+ struct dentry *dentry, int mode, dev_t dev)
{
return 0;
}
Index: linux-2.6.19/security/selinux/hooks.c
===================================================================
--- linux-2.6.19.orig/security/selinux/hooks.c
+++ linux-2.6.19/security/selinux/hooks.c
@@ -2171,11 +2171,12 @@ static int selinux_inode_rmdir(struct in
return may_link(dir, dentry, MAY_RMDIR);
}
-static int selinux_inode_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev)
+static int selinux_inode_mknod(struct inode *dir, struct vfsmount *mnt,
+ struct dentry *dentry, int mode, dev_t dev)
{
int rc;
- rc = secondary_ops->inode_mknod(dir, dentry, mode, dev);
+ rc = secondary_ops->inode_mknod(dir, mnt, dentry, mode, dev);
if (rc)
return rc;

View File

@@ -0,0 +1,90 @@
Pass struct vfsmount to the inode_readlink LSM hook
Signed-off-by: Tony Jones <tonyj@suse.de>
Signed-off-by: Andreas Gruenbacher <agruen@suse.de>
Index: linux-2.6.19/fs/stat.c
===================================================================
--- linux-2.6.19.orig/fs/stat.c
+++ linux-2.6.19/fs/stat.c
@@ -314,7 +314,7 @@ asmlinkage long sys_readlinkat(int dfd,
error = -EINVAL;
if (inode->i_op && inode->i_op->readlink) {
- error = security_inode_readlink(nd.dentry);
+ error = security_inode_readlink(nd.mnt, nd.dentry);
if (!error) {
touch_atime(nd.mnt, nd.dentry);
error = inode->i_op->readlink(nd.dentry, buf, bufsiz);
Index: linux-2.6.19/include/linux/security.h
===================================================================
--- linux-2.6.19.orig/include/linux/security.h
+++ linux-2.6.19/include/linux/security.h
@@ -337,6 +337,7 @@ struct request_sock;
* Return 0 if permission is granted.
* @inode_readlink:
* Check the permission to read the symbolic link.
+ * @mnt is the vfsmount where the dentry was looked up
* @dentry contains the dentry structure for the file link.
* Return 0 if permission is granted.
* @inode_follow_link:
@@ -1231,7 +1232,7 @@ struct security_operations {
struct dentry *dentry, int mode, dev_t dev);
int (*inode_rename) (struct inode *old_dir, struct dentry *old_dentry,
struct inode *new_dir, struct dentry *new_dentry);
- int (*inode_readlink) (struct dentry *dentry);
+ int (*inode_readlink) (struct vfsmount *mnt, struct dentry *dentry);
int (*inode_follow_link) (struct dentry *dentry, struct nameidata *nd);
int (*inode_permission) (struct inode *inode, int mask, struct nameidata *nd);
int (*inode_setattr) (struct vfsmount *mnt, struct dentry *dentry,
@@ -1702,11 +1703,12 @@ static inline int security_inode_rename
new_dir, new_dentry);
}
-static inline int security_inode_readlink (struct dentry *dentry)
+static inline int security_inode_readlink (struct vfsmount *mnt,
+ struct dentry *dentry)
{
if (unlikely (IS_PRIVATE (dentry->d_inode)))
return 0;
- return security_ops->inode_readlink (dentry);
+ return security_ops->inode_readlink (mnt, dentry);
}
static inline int security_inode_follow_link (struct dentry *dentry,
@@ -2416,7 +2418,8 @@ static inline int security_inode_rename
return 0;
}
-static inline int security_inode_readlink (struct dentry *dentry)
+static inline int security_inode_readlink (struct vfsmount *mnt,
+ struct dentry *dentry)
{
return 0;
}
Index: linux-2.6.19/security/dummy.c
===================================================================
--- linux-2.6.19.orig/security/dummy.c
+++ linux-2.6.19/security/dummy.c
@@ -312,7 +312,7 @@ static int dummy_inode_rename (struct in
return 0;
}
-static int dummy_inode_readlink (struct dentry *dentry)
+static int dummy_inode_readlink (struct vfsmount *mnt, struct dentry *dentry)
{
return 0;
}
Index: linux-2.6.19/security/selinux/hooks.c
===================================================================
--- linux-2.6.19.orig/security/selinux/hooks.c
+++ linux-2.6.19/security/selinux/hooks.c
@@ -2190,7 +2190,7 @@ static int selinux_inode_rename(struct i
return may_rename(old_inode, old_dentry, new_inode, new_dentry);
}
-static int selinux_inode_readlink(struct dentry *dentry)
+static int selinux_inode_readlink(struct vfsmount *mnt, struct dentry *dentry)
{
return dentry_has_perm(current, NULL, dentry, FILE__READ);
}

View File

@@ -0,0 +1,111 @@
Pass struct vfsmount to the inode_removexattr LSM hook
Signed-off-by: Tony Jones <tonyj@suse.de>
Signed-off-by: Andreas Gruenbacher <agruen@suse.de>
Index: linux-2.6.19/fs/xattr.c
===================================================================
--- linux-2.6.19.orig/fs/xattr.c
+++ linux-2.6.19/fs/xattr.c
@@ -178,7 +178,7 @@ vfs_removexattr(struct vfsmount *mnt, st
if (error)
return error;
- error = security_inode_removexattr(dentry, name);
+ error = security_inode_removexattr(mnt, dentry, name);
if (error)
return error;
Index: linux-2.6.19/include/linux/security.h
===================================================================
--- linux-2.6.19.orig/include/linux/security.h
+++ linux-2.6.19/include/linux/security.h
@@ -50,7 +50,7 @@ extern int cap_bprm_set_security (struct
extern void cap_bprm_apply_creds (struct linux_binprm *bprm, int unsafe);
extern int cap_bprm_secureexec(struct linux_binprm *bprm);
extern int cap_inode_setxattr(struct vfsmount *mnt, struct dentry *dentry, char *name, void *value, size_t size, int flags);
-extern int cap_inode_removexattr(struct dentry *dentry, char *name);
+extern int cap_inode_removexattr(struct vfsmount *mnt, struct dentry *dentry, char *name);
extern int cap_task_post_setuid (uid_t old_ruid, uid_t old_euid, uid_t old_suid, int flags);
extern void cap_task_reparent_to_init (struct task_struct *p);
extern int cap_syslog (int type);
@@ -1257,7 +1257,8 @@ struct security_operations {
int (*inode_getxattr) (struct vfsmount *mnt, struct dentry *dentry,
char *name);
int (*inode_listxattr) (struct vfsmount *mnt, struct dentry *dentry);
- int (*inode_removexattr) (struct dentry *dentry, char *name);
+ int (*inode_removexattr) (struct vfsmount *mnt, struct dentry *dentry,
+ char *name);
const char *(*inode_xattr_getsuffix) (void);
int (*inode_getsecurity)(const struct inode *inode, const char *name, void *buffer, size_t size, int err);
int (*inode_setsecurity)(struct inode *inode, const char *name, const void *value, size_t size, int flags);
@@ -1804,11 +1805,12 @@ static inline int security_inode_listxat
return security_ops->inode_listxattr (mnt, dentry);
}
-static inline int security_inode_removexattr (struct dentry *dentry, char *name)
+static inline int security_inode_removexattr (struct vfsmount *mnt,
+ struct dentry *dentry, char *name)
{
if (unlikely (IS_PRIVATE (dentry->d_inode)))
return 0;
- return security_ops->inode_removexattr (dentry, name);
+ return security_ops->inode_removexattr (mnt, dentry, name);
}
static inline const char *security_inode_xattr_getsuffix(void)
@@ -2504,9 +2506,10 @@ static inline int security_inode_listxat
return 0;
}
-static inline int security_inode_removexattr (struct dentry *dentry, char *name)
+static inline int security_inode_removexattr (struct vfsmount *mnt,
+ struct dentry *dentry, char *name)
{
- return cap_inode_removexattr(dentry, name);
+ return cap_inode_removexattr(mnt, dentry, name);
}
static inline const char *security_inode_xattr_getsuffix (void)
Index: linux-2.6.19/security/commoncap.c
===================================================================
--- linux-2.6.19.orig/security/commoncap.c
+++ linux-2.6.19/security/commoncap.c
@@ -201,7 +201,8 @@ int cap_inode_setxattr(struct vfsmount *
return 0;
}
-int cap_inode_removexattr(struct dentry *dentry, char *name)
+int cap_inode_removexattr(struct vfsmount *mnt, struct dentry *dentry,
+ char *name)
{
if (!strncmp(name, XATTR_SECURITY_PREFIX,
sizeof(XATTR_SECURITY_PREFIX) - 1) &&
Index: linux-2.6.19/security/dummy.c
===================================================================
--- linux-2.6.19.orig/security/dummy.c
+++ linux-2.6.19/security/dummy.c
@@ -377,7 +377,8 @@ static int dummy_inode_listxattr (struct
return 0;
}
-static int dummy_inode_removexattr (struct dentry *dentry, char *name)
+static int dummy_inode_removexattr (struct vfsmount *mnt, struct dentry *dentry,
+ char *name)
{
if (!strncmp(name, XATTR_SECURITY_PREFIX,
sizeof(XATTR_SECURITY_PREFIX) - 1) &&
Index: linux-2.6.19/security/selinux/hooks.c
===================================================================
--- linux-2.6.19.orig/security/selinux/hooks.c
+++ linux-2.6.19/security/selinux/hooks.c
@@ -2354,7 +2354,8 @@ static int selinux_inode_listxattr (stru
return dentry_has_perm(current, NULL, dentry, FILE__GETATTR);
}
-static int selinux_inode_removexattr (struct dentry *dentry, char *name)
+static int selinux_inode_removexattr (struct vfsmount *mnt,
+ struct dentry *dentry, char *name)
{
if (strcmp(name, XATTR_NAME_SELINUX)) {
if (!strncmp(name, XATTR_SECURITY_PREFIX,

View File

@@ -0,0 +1,122 @@
Pass struct vfsmount to the inode_rename LSM hook
Signed-off-by: Tony Jones <tonyj@suse.de>
Signed-off-by: Andreas Gruenbacher <agruen@suse.de>
Index: linux-2.6.19/fs/namei.c
===================================================================
--- linux-2.6.19.orig/fs/namei.c
+++ linux-2.6.19/fs/namei.c
@@ -2402,7 +2402,8 @@ static int vfs_rename_dir(struct inode *
return error;
}
- error = security_inode_rename(old_dir, old_dentry, new_dir, new_dentry);
+ error = security_inode_rename(old_dir, old_mnt, old_dentry, new_dir,
+ new_mnt, new_dentry);
if (error)
return error;
@@ -2436,7 +2437,8 @@ static int vfs_rename_other(struct inode
struct inode *target;
int error;
- error = security_inode_rename(old_dir, old_dentry, new_dir, new_dentry);
+ error = security_inode_rename(old_dir, old_mnt, old_dentry, new_dir,
+ new_mnt, new_dentry);
if (error)
return error;
Index: linux-2.6.19/include/linux/security.h
===================================================================
--- linux-2.6.19.orig/include/linux/security.h
+++ linux-2.6.19/include/linux/security.h
@@ -335,8 +335,10 @@ struct request_sock;
* @inode_rename:
* Check for permission to rename a file or directory.
* @old_dir contains the inode structure for parent of the old link.
+ * @old_mnt is the vfsmount where @old_dentry was looked up (may be NULL)
* @old_dentry contains the dentry structure of the old link.
* @new_dir contains the inode structure for parent of the new link.
+ * @new_mnt is the vfsmount for @new_dentry (may be NULL)
* @new_dentry contains the dentry structure of the new link.
* Return 0 if permission is granted.
* @inode_readlink:
@@ -1237,8 +1239,10 @@ struct security_operations {
struct dentry *dentry);
int (*inode_mknod) (struct inode *dir, struct vfsmount *mnt,
struct dentry *dentry, int mode, dev_t dev);
- int (*inode_rename) (struct inode *old_dir, struct dentry *old_dentry,
- struct inode *new_dir, struct dentry *new_dentry);
+ int (*inode_rename) (struct inode *old_dir, struct vfsmount *old_mnt,
+ struct dentry *old_dentry, struct inode *new_dir,
+ struct vfsmount *new_mnt,
+ struct dentry *new_dentry);
int (*inode_readlink) (struct vfsmount *mnt, struct dentry *dentry);
int (*inode_follow_link) (struct dentry *dentry, struct nameidata *nd);
int (*inode_permission) (struct inode *inode, int mask, struct nameidata *nd);
@@ -1704,15 +1708,17 @@ static inline int security_inode_mknod (
}
static inline int security_inode_rename (struct inode *old_dir,
+ struct vfsmount *old_mnt,
struct dentry *old_dentry,
struct inode *new_dir,
+ struct vfsmount *new_mnt,
struct dentry *new_dentry)
{
if (unlikely (IS_PRIVATE (old_dentry->d_inode) ||
(new_dentry->d_inode && IS_PRIVATE (new_dentry->d_inode))))
return 0;
- return security_ops->inode_rename (old_dir, old_dentry,
- new_dir, new_dentry);
+ return security_ops->inode_rename (old_dir, old_mnt, old_dentry,
+ new_dir, new_mnt, new_dentry);
}
static inline int security_inode_readlink (struct vfsmount *mnt,
@@ -2427,8 +2433,10 @@ static inline int security_inode_mknod (
}
static inline int security_inode_rename (struct inode *old_dir,
+ struct vfsmount *old_mnt,
struct dentry *old_dentry,
struct inode *new_dir,
+ struct vfsmount *new_mnt,
struct dentry *new_dentry)
{
return 0;
Index: linux-2.6.19/security/dummy.c
===================================================================
--- linux-2.6.19.orig/security/dummy.c
+++ linux-2.6.19/security/dummy.c
@@ -309,8 +309,10 @@ static int dummy_inode_mknod (struct ino
}
static int dummy_inode_rename (struct inode *old_inode,
+ struct vfsmount *old_mnt,
struct dentry *old_dentry,
struct inode *new_inode,
+ struct vfsmount *new_mnt,
struct dentry *new_dentry)
{
return 0;
Index: linux-2.6.19/security/selinux/hooks.c
===================================================================
--- linux-2.6.19.orig/security/selinux/hooks.c
+++ linux-2.6.19/security/selinux/hooks.c
@@ -2190,8 +2190,12 @@ static int selinux_inode_mknod(struct in
return may_create(dir, dentry, inode_mode_to_security_class(mode));
}
-static int selinux_inode_rename(struct inode *old_inode, struct dentry *old_dentry,
- struct inode *new_inode, struct dentry *new_dentry)
+static int selinux_inode_rename(struct inode *old_inode,
+ struct vfsmount *old_mnt,
+ struct dentry *old_dentry,
+ struct inode *new_inode,
+ struct vfsmount *new_mnt,
+ struct dentry *new_dentry)
{
return may_rename(old_inode, old_dentry, new_inode, new_dentry);
}

View File

@@ -0,0 +1,90 @@
Pass struct vfsmount to the inode_rmdir LSM hook
Signed-off-by: Tony Jones <tonyj@suse.de>
Signed-off-by: Andreas Gruenbacher <agruen@suse.de>
Index: linux-2.6.19/fs/namei.c
===================================================================
--- linux-2.6.19.orig/fs/namei.c
+++ linux-2.6.19/fs/namei.c
@@ -2027,7 +2027,7 @@ int vfs_rmdir(struct inode *dir, struct
if (d_mountpoint(dentry))
error = -EBUSY;
else {
- error = security_inode_rmdir(dir, dentry);
+ error = security_inode_rmdir(dir, mnt, dentry);
if (!error) {
error = dir->i_op->rmdir(dir, dentry);
if (!error)
Index: linux-2.6.19/include/linux/security.h
===================================================================
--- linux-2.6.19.orig/include/linux/security.h
+++ linux-2.6.19/include/linux/security.h
@@ -317,6 +317,7 @@ struct request_sock;
* @inode_rmdir:
* Check the permission to remove a directory.
* @dir contains the inode structure of parent of the directory to be removed.
+ * @mnt is the vfsmount where the dentry was looked up (may be NULL)
* @dentry contains the dentry structure of directory to be removed.
* Return 0 if permission is granted.
* @inode_mknod:
@@ -1230,7 +1231,8 @@ struct security_operations {
struct dentry *dentry, const char *old_name);
int (*inode_mkdir) (struct inode *dir, struct vfsmount *mnt,
struct dentry *dentry, int mode);
- int (*inode_rmdir) (struct inode *dir, struct dentry *dentry);
+ int (*inode_rmdir) (struct inode *dir, struct vfsmount *mnt,
+ struct dentry *dentry);
int (*inode_mknod) (struct inode *dir, struct vfsmount *mnt,
struct dentry *dentry, int mode, dev_t dev);
int (*inode_rename) (struct inode *old_dir, struct dentry *old_dentry,
@@ -1680,11 +1682,12 @@ static inline int security_inode_mkdir (
}
static inline int security_inode_rmdir (struct inode *dir,
+ struct vfsmount *mnt,
struct dentry *dentry)
{
if (unlikely (IS_PRIVATE (dentry->d_inode)))
return 0;
- return security_ops->inode_rmdir (dir, dentry);
+ return security_ops->inode_rmdir (dir, mnt, dentry);
}
static inline int security_inode_mknod (struct inode *dir,
@@ -2405,6 +2408,7 @@ static inline int security_inode_mkdir (
}
static inline int security_inode_rmdir (struct inode *dir,
+ struct vfsmount *mnt,
struct dentry *dentry)
{
return 0;
Index: linux-2.6.19/security/dummy.c
===================================================================
--- linux-2.6.19.orig/security/dummy.c
+++ linux-2.6.19/security/dummy.c
@@ -295,7 +295,8 @@ static int dummy_inode_mkdir (struct ino
return 0;
}
-static int dummy_inode_rmdir (struct inode *inode, struct dentry *dentry)
+static int dummy_inode_rmdir (struct inode *inode, struct vfsmount *mnt,
+ struct dentry *dentry)
{
return 0;
}
Index: linux-2.6.19/security/selinux/hooks.c
===================================================================
--- linux-2.6.19.orig/security/selinux/hooks.c
+++ linux-2.6.19/security/selinux/hooks.c
@@ -2171,7 +2171,8 @@ static int selinux_inode_mkdir(struct in
return may_create(dir, dentry, SECCLASS_DIR);
}
-static int selinux_inode_rmdir(struct inode *dir, struct dentry *dentry)
+static int selinux_inode_rmdir(struct inode *dir, struct vfsmount *mnt,
+ struct dentry *dentry)
{
return may_link(dir, dentry, MAY_RMDIR);
}

View File

@@ -0,0 +1,106 @@
Pass struct vfsmount to the inode_setattr LSM hook
Signed-off-by: Tony Jones <tonyj@suse.de>
Signed-off-by: Andreas Gruenbacher <agruen@suse.de>
Index: linux-2.6.19/fs/attr.c
===================================================================
--- linux-2.6.19.orig/fs/attr.c
+++ linux-2.6.19/fs/attr.c
@@ -145,13 +145,13 @@ int notify_change(struct vfsmount *mnt,
down_write(&dentry->d_inode->i_alloc_sem);
if (inode->i_op && inode->i_op->setattr) {
- error = security_inode_setattr(dentry, attr);
+ error = security_inode_setattr(mnt, dentry, attr);
if (!error)
error = inode->i_op->setattr(dentry, attr);
} else {
error = inode_change_ok(inode, attr);
if (!error)
- error = security_inode_setattr(dentry, attr);
+ error = security_inode_setattr(mnt, dentry, attr);
if (!error) {
if ((ia_valid & ATTR_UID && attr->ia_uid != inode->i_uid) ||
(ia_valid & ATTR_GID && attr->ia_gid != inode->i_gid))
Index: linux-2.6.19/include/linux/security.h
===================================================================
--- linux-2.6.19.orig/include/linux/security.h
+++ linux-2.6.19/include/linux/security.h
@@ -357,6 +357,7 @@ struct request_sock;
* call to notify_change is performed from several locations, whenever
* file attributes change (such as when a file is truncated, chown/chmod
* operations, transferring disk quotas, etc).
+ * @mnt is the vfsmount where the dentry was looked up (may be NULL)
* @dentry contains the dentry structure for the file.
* @attr is the iattr structure containing the new file attributes.
* Return 0 if permission is granted.
@@ -1229,7 +1230,8 @@ struct security_operations {
int (*inode_readlink) (struct dentry *dentry);
int (*inode_follow_link) (struct dentry *dentry, struct nameidata *nd);
int (*inode_permission) (struct inode *inode, int mask, struct nameidata *nd);
- int (*inode_setattr) (struct dentry *dentry, struct iattr *attr);
+ int (*inode_setattr) (struct vfsmount *mnt, struct dentry *dentry,
+ struct iattr *attr);
int (*inode_getattr) (struct vfsmount *mnt, struct dentry *dentry);
void (*inode_delete) (struct inode *inode);
int (*inode_setxattr) (struct dentry *dentry, char *name, void *value,
@@ -1716,12 +1718,13 @@ static inline int security_inode_permiss
return security_ops->inode_permission (inode, mask, nd);
}
-static inline int security_inode_setattr (struct dentry *dentry,
+static inline int security_inode_setattr (struct vfsmount *mnt,
+ struct dentry *dentry,
struct iattr *attr)
{
if (unlikely (IS_PRIVATE (dentry->d_inode)))
return 0;
- return security_ops->inode_setattr (dentry, attr);
+ return security_ops->inode_setattr (mnt, dentry, attr);
}
static inline int security_inode_getattr (struct vfsmount *mnt,
@@ -2420,7 +2423,8 @@ static inline int security_inode_permiss
return 0;
}
-static inline int security_inode_setattr (struct dentry *dentry,
+static inline int security_inode_setattr (struct vfsmount *mnt,
+ struct dentry *dentry,
struct iattr *attr)
{
return 0;
Index: linux-2.6.19/security/dummy.c
===================================================================
--- linux-2.6.19.orig/security/dummy.c
+++ linux-2.6.19/security/dummy.c
@@ -328,7 +328,8 @@ static int dummy_inode_permission (struc
return 0;
}
-static int dummy_inode_setattr (struct dentry *dentry, struct iattr *iattr)
+static int dummy_inode_setattr (struct vfsmount *mnt, struct dentry *dentry,
+ struct iattr *iattr)
{
return 0;
}
Index: linux-2.6.19/security/selinux/hooks.c
===================================================================
--- linux-2.6.19.orig/security/selinux/hooks.c
+++ linux-2.6.19/security/selinux/hooks.c
@@ -2220,11 +2220,12 @@ static int selinux_inode_permission(stru
file_mask_to_av(inode->i_mode, mask), NULL);
}
-static int selinux_inode_setattr(struct dentry *dentry, struct iattr *iattr)
+static int selinux_inode_setattr(struct vfsmount *mnt, struct dentry *dentry,
+ struct iattr *iattr)
{
int rc;
- rc = secondary_ops->inode_setattr(dentry, iattr);
+ rc = secondary_ops->inode_setattr(mnt, dentry, iattr);
if (rc)
return rc;

View File

@@ -0,0 +1,119 @@
Pass struct vfsmount to the inode_setxattr LSM hook
Signed-off-by: Tony Jones <tonyj@suse.de>
Signed-off-by: Andreas Gruenbacher <agruen@suse.de>
Index: linux-2.6.19/include/linux/security.h
===================================================================
--- linux-2.6.19.orig/include/linux/security.h
+++ linux-2.6.19/include/linux/security.h
@@ -49,7 +49,7 @@ extern void cap_capset_set (struct task_
extern int cap_bprm_set_security (struct linux_binprm *bprm);
extern void cap_bprm_apply_creds (struct linux_binprm *bprm, int unsafe);
extern int cap_bprm_secureexec(struct linux_binprm *bprm);
-extern int cap_inode_setxattr(struct dentry *dentry, char *name, void *value, size_t size, int flags);
+extern int cap_inode_setxattr(struct vfsmount *mnt, struct dentry *dentry, char *name, void *value, size_t size, int flags);
extern int cap_inode_removexattr(struct dentry *dentry, char *name);
extern int cap_task_post_setuid (uid_t old_ruid, uid_t old_euid, uid_t old_suid, int flags);
extern void cap_task_reparent_to_init (struct task_struct *p);
@@ -1250,8 +1250,8 @@ struct security_operations {
struct iattr *attr);
int (*inode_getattr) (struct vfsmount *mnt, struct dentry *dentry);
void (*inode_delete) (struct inode *inode);
- int (*inode_setxattr) (struct dentry *dentry, char *name, void *value,
- size_t size, int flags);
+ int (*inode_setxattr) (struct vfsmount *mnt, struct dentry *dentry,
+ char *name, void *value, size_t size, int flags);
void (*inode_post_setxattr) (struct dentry *dentry, char *name, void *value,
size_t size, int flags);
int (*inode_getxattr) (struct dentry *dentry, char *name);
@@ -1769,12 +1769,14 @@ static inline void security_inode_delete
security_ops->inode_delete (inode);
}
-static inline int security_inode_setxattr (struct dentry *dentry, char *name,
+static inline int security_inode_setxattr (struct vfsmount *mnt,
+ struct dentry *dentry, char *name,
void *value, size_t size, int flags)
{
if (unlikely (IS_PRIVATE (dentry->d_inode)))
return 0;
- return security_ops->inode_setxattr (dentry, name, value, size, flags);
+ return security_ops->inode_setxattr (mnt, dentry, name, value, size,
+ flags);
}
static inline void security_inode_post_setxattr (struct dentry *dentry, char *name,
@@ -2476,10 +2478,11 @@ static inline int security_inode_getattr
static inline void security_inode_delete (struct inode *inode)
{ }
-static inline int security_inode_setxattr (struct dentry *dentry, char *name,
+static inline int security_inode_setxattr (struct vfsmount *mnt,
+ struct dentry *dentry, char *name,
void *value, size_t size, int flags)
{
- return cap_inode_setxattr(dentry, name, value, size, flags);
+ return cap_inode_setxattr(mnt, dentry, name, value, size, flags);
}
static inline void security_inode_post_setxattr (struct dentry *dentry, char *name,
Index: linux-2.6.19/security/commoncap.c
===================================================================
--- linux-2.6.19.orig/security/commoncap.c
+++ linux-2.6.19/security/commoncap.c
@@ -191,8 +191,8 @@ int cap_bprm_secureexec (struct linux_bi
current->egid != current->gid);
}
-int cap_inode_setxattr(struct dentry *dentry, char *name, void *value,
- size_t size, int flags)
+int cap_inode_setxattr(struct vfsmount *mnt, struct dentry *dentry, char *name,
+ void *value, size_t size, int flags)
{
if (!strncmp(name, XATTR_SECURITY_PREFIX,
sizeof(XATTR_SECURITY_PREFIX) - 1) &&
Index: linux-2.6.19/security/dummy.c
===================================================================
--- linux-2.6.19.orig/security/dummy.c
+++ linux-2.6.19/security/dummy.c
@@ -350,8 +350,9 @@ static void dummy_inode_delete (struct i
return;
}
-static int dummy_inode_setxattr (struct dentry *dentry, char *name, void *value,
- size_t size, int flags)
+static int dummy_inode_setxattr (struct vfsmount *mnt, struct dentry *dentry,
+ char *name, void *value, size_t size,
+ int flags)
{
if (!strncmp(name, XATTR_SECURITY_PREFIX,
sizeof(XATTR_SECURITY_PREFIX) - 1) &&
Index: linux-2.6.19/security/selinux/hooks.c
===================================================================
--- linux-2.6.19.orig/security/selinux/hooks.c
+++ linux-2.6.19/security/selinux/hooks.c
@@ -2257,7 +2257,9 @@ static int selinux_inode_getattr(struct
return dentry_has_perm(current, mnt, dentry, FILE__GETATTR);
}
-static int selinux_inode_setxattr(struct dentry *dentry, char *name, void *value, size_t size, int flags)
+static int selinux_inode_setxattr(struct vfsmount *mnt, struct dentry *dentry,
+ char *name, void *value, size_t size,
+ int flags)
{
struct task_security_struct *tsec = current->security;
struct inode *inode = dentry->d_inode;
Index: linux-2.6.19/fs/xattr.c
===================================================================
--- linux-2.6.19.orig/fs/xattr.c
+++ linux-2.6.19/fs/xattr.c
@@ -81,7 +81,7 @@ vfs_setxattr(struct vfsmount *mnt, struc
return error;
mutex_lock(&inode->i_mutex);
- error = security_inode_setxattr(dentry, name, value, size, flags);
+ error = security_inode_setxattr(mnt, dentry, name, value, size, flags);
if (error)
goto out;
error = -EOPNOTSUPP;

View File

@@ -0,0 +1,91 @@
Pass struct vfsmount to the inode_symlink LSM hook.
Signed-off-by: Tony Jones <tonyj@suse.de>
Signed-off-by: Andreas Gruenbacher <agruen@suse.de>
Index: linux-2.6.19/fs/namei.c
===================================================================
--- linux-2.6.19.orig/fs/namei.c
+++ linux-2.6.19/fs/namei.c
@@ -2200,7 +2200,7 @@ int vfs_symlink(struct inode *dir, struc
if (!dir->i_op || !dir->i_op->symlink)
return -EPERM;
- error = security_inode_symlink(dir, dentry, oldname);
+ error = security_inode_symlink(dir, mnt, dentry, oldname);
if (error)
return error;
Index: linux-2.6.19/include/linux/security.h
===================================================================
--- linux-2.6.19.orig/include/linux/security.h
+++ linux-2.6.19/include/linux/security.h
@@ -300,6 +300,7 @@ struct request_sock;
* @inode_symlink:
* Check the permission to create a symbolic link to a file.
* @dir contains the inode structure of parent directory of the symbolic link.
+ * @mnt is the vfsmount of the new dentry (may be NULL)
* @dentry contains the dentry structure of the symbolic link.
* @old_name contains the pathname of file.
* Return 0 if permission is granted.
@@ -1221,7 +1222,7 @@ struct security_operations {
int (*inode_link) (struct dentry *old_dentry,
struct inode *dir, struct dentry *new_dentry);
int (*inode_unlink) (struct inode *dir, struct dentry *dentry);
- int (*inode_symlink) (struct inode *dir,
+ int (*inode_symlink) (struct inode *dir, struct vfsmount *mnt,
struct dentry *dentry, const char *old_name);
int (*inode_mkdir) (struct inode *dir, struct vfsmount *mnt,
struct dentry *dentry, int mode);
@@ -1652,12 +1653,13 @@ static inline int security_inode_unlink
}
static inline int security_inode_symlink (struct inode *dir,
+ struct vfsmount *mnt,
struct dentry *dentry,
const char *old_name)
{
if (unlikely (IS_PRIVATE (dir)))
return 0;
- return security_ops->inode_symlink (dir, dentry, old_name);
+ return security_ops->inode_symlink (dir, mnt, dentry, old_name);
}
static inline int security_inode_mkdir (struct inode *dir,
@@ -2377,6 +2379,7 @@ static inline int security_inode_unlink
}
static inline int security_inode_symlink (struct inode *dir,
+ struct vfsmount *mnt,
struct dentry *dentry,
const char *old_name)
{
Index: linux-2.6.19/security/dummy.c
===================================================================
--- linux-2.6.19.orig/security/dummy.c
+++ linux-2.6.19/security/dummy.c
@@ -281,8 +281,8 @@ static int dummy_inode_unlink (struct in
return 0;
}
-static int dummy_inode_symlink (struct inode *inode, struct dentry *dentry,
- const char *name)
+static int dummy_inode_symlink (struct inode *inode, struct vfsmount *mnt,
+ struct dentry *dentry, const char *name)
{
return 0;
}
Index: linux-2.6.19/security/selinux/hooks.c
===================================================================
--- linux-2.6.19.orig/security/selinux/hooks.c
+++ linux-2.6.19/security/selinux/hooks.c
@@ -2155,7 +2155,8 @@ static int selinux_inode_unlink(struct i
return may_link(dir, dentry, MAY_UNLINK);
}
-static int selinux_inode_symlink(struct inode *dir, struct dentry *dentry, const char *name)
+static int selinux_inode_symlink(struct inode *dir, struct vfsmount *mnt,
+ struct dentry *dentry, const char *name)
{
return may_create(dir, dentry, SECCLASS_LNK_FILE);
}

View File

@@ -0,0 +1,95 @@
Pass struct vfsmount to the inode_unlink LSM hook
Signed-off-by: Tony Jones <tonyj@suse.de>
Signed-off-by: Andreas Gruenbacher <agruen@suse.de>
Index: linux-2.6.19/fs/namei.c
===================================================================
--- linux-2.6.19.orig/fs/namei.c
+++ linux-2.6.19/fs/namei.c
@@ -2106,7 +2106,7 @@ int vfs_unlink(struct inode *dir, struct
if (d_mountpoint(dentry))
error = -EBUSY;
else {
- error = security_inode_unlink(dir, dentry);
+ error = security_inode_unlink(dir, mnt, dentry);
if (!error)
error = dir->i_op->unlink(dir, dentry);
}
Index: linux-2.6.19/include/linux/security.h
===================================================================
--- linux-2.6.19.orig/include/linux/security.h
+++ linux-2.6.19/include/linux/security.h
@@ -297,6 +297,7 @@ struct request_sock;
* @inode_unlink:
* Check the permission to remove a hard link to a file.
* @dir contains the inode structure of parent directory of the file.
+ * @mnt is the vfsmount where the dentry was looked up (may be NULL)
* @dentry contains the dentry structure for file to be unlinked.
* Return 0 if permission is granted.
* @inode_symlink:
@@ -1226,7 +1227,8 @@ struct security_operations {
int (*inode_link) (struct vfsmount *old_mnt, struct dentry *old_dentry,
struct inode *dir, struct vfsmount *new_mnt,
struct dentry *new_dentry);
- int (*inode_unlink) (struct inode *dir, struct dentry *dentry);
+ int (*inode_unlink) (struct inode *dir, struct vfsmount *mnt,
+ struct dentry *dentry);
int (*inode_symlink) (struct inode *dir, struct vfsmount *mnt,
struct dentry *dentry, const char *old_name);
int (*inode_mkdir) (struct inode *dir, struct vfsmount *mnt,
@@ -1654,11 +1656,12 @@ static inline int security_inode_link (s
}
static inline int security_inode_unlink (struct inode *dir,
+ struct vfsmount *mnt,
struct dentry *dentry)
{
if (unlikely (IS_PRIVATE (dentry->d_inode)))
return 0;
- return security_ops->inode_unlink (dir, dentry);
+ return security_ops->inode_unlink (dir, mnt, dentry);
}
static inline int security_inode_symlink (struct inode *dir,
@@ -2386,6 +2389,7 @@ static inline int security_inode_link (s
}
static inline int security_inode_unlink (struct inode *dir,
+ struct vfsmount *mnt,
struct dentry *dentry)
{
return 0;
Index: linux-2.6.19/security/dummy.c
===================================================================
--- linux-2.6.19.orig/security/dummy.c
+++ linux-2.6.19/security/dummy.c
@@ -278,7 +278,8 @@ static int dummy_inode_link (struct vfsm
return 0;
}
-static int dummy_inode_unlink (struct inode *inode, struct dentry *dentry)
+static int dummy_inode_unlink (struct inode *inode, struct vfsmount *mnt,
+ struct dentry *dentry)
{
return 0;
}
Index: linux-2.6.19/security/selinux/hooks.c
===================================================================
--- linux-2.6.19.orig/security/selinux/hooks.c
+++ linux-2.6.19/security/selinux/hooks.c
@@ -2149,11 +2149,12 @@ static int selinux_inode_link(struct vfs
return may_link(dir, old_dentry, MAY_LINK);
}
-static int selinux_inode_unlink(struct inode *dir, struct dentry *dentry)
+static int selinux_inode_unlink(struct inode *dir, struct vfsmount *mnt,
+ struct dentry *dentry)
{
int rc;
- rc = secondary_ops->inode_unlink(dir, dentry);
+ rc = secondary_ops->inode_unlink(dir, mnt, dentry);
if (rc)
return rc;
return may_link(dir, dentry, MAY_UNLINK);

View File

@@ -0,0 +1,36 @@
security-create.diff
proc_setattr.diff
remove_suid.diff
vfs-notify_change.diff
security-setattr.diff
vfs-mkdir.diff
security-mkdir.diff
vfs-mknod.diff
security-mknod.diff
vfs-symlink.diff
security-symlink.diff
security-readlink.diff
vfs-link.diff
security-link.diff
vfs-rmdir.diff
security-rmdir.diff
vfs-unlink.diff
security-unlink.diff
vfs-rename.diff
security-rename.diff
vfs-setxattr.diff
security-setxattr.diff
vfs-getxattr.diff
security-getxattr.diff
vfs-listxattr.diff
security-listxattr.diff
vfs-removexattr.diff
security-removexattr.diff
apparmor-audit.diff
apparmor-intree.diff
apparmor.diff
apparmor-vfsmnt.diff
apparmor-builtinonly.diff
apparmor-bootdisable.diff
apparmor-twophaseinit.diff
apparmor-novalidfstype.diff

View File

@@ -0,0 +1,101 @@
Add a struct vfsmount parameter to vfs_getxattr()
Signed-off-by: Tony Jones <tonyj@suse.de>
Signed-off-by: Andreas Gruenbacher <agruen@suse.de>
Index: linux-2.6.19/fs/nfsd/vfs.c
===================================================================
--- linux-2.6.19.orig/fs/nfsd/vfs.c
+++ linux-2.6.19/fs/nfsd/vfs.c
@@ -383,7 +383,7 @@ static ssize_t nfsd_getxattr(struct dent
{
ssize_t buflen;
- buflen = vfs_getxattr(dentry, key, NULL, 0);
+ buflen = vfs_getxattr(NULL, dentry, key, NULL, 0);
if (buflen <= 0)
return buflen;
@@ -391,7 +391,7 @@ static ssize_t nfsd_getxattr(struct dent
if (!*buf)
return -ENOMEM;
- return vfs_getxattr(dentry, key, *buf, buflen);
+ return vfs_getxattr(NULL, dentry, key, *buf, buflen);
}
#endif
Index: linux-2.6.19/fs/xattr.c
===================================================================
--- linux-2.6.19.orig/fs/xattr.c
+++ linux-2.6.19/fs/xattr.c
@@ -107,7 +107,8 @@ out:
EXPORT_SYMBOL_GPL(vfs_setxattr);
ssize_t
-vfs_getxattr(struct dentry *dentry, char *name, void *value, size_t size)
+vfs_getxattr(struct vfsmount *mnt, struct dentry *dentry, char *name,
+ void *value, size_t size)
{
struct inode *inode = dentry->d_inode;
int error;
@@ -279,7 +280,8 @@ sys_fsetxattr(int fd, char __user *name,
* Extended attribute GET operations
*/
static ssize_t
-getxattr(struct dentry *d, char __user *name, void __user *value, size_t size)
+getxattr(struct vfsmount *mnt, struct dentry *dentry, char __user *name,
+ void __user *value, size_t size)
{
ssize_t error;
void *kvalue = NULL;
@@ -299,7 +301,7 @@ getxattr(struct dentry *d, char __user *
return -ENOMEM;
}
- error = vfs_getxattr(d, kname, kvalue, size);
+ error = vfs_getxattr(mnt, dentry, kname, kvalue, size);
if (error > 0) {
if (size && copy_to_user(value, kvalue, error))
error = -EFAULT;
@@ -322,7 +324,7 @@ sys_getxattr(char __user *path, char __u
error = user_path_walk(path, &nd);
if (error)
return error;
- error = getxattr(nd.dentry, name, value, size);
+ error = getxattr(nd.mnt, nd.dentry, name, value, size);
path_release(&nd);
return error;
}
@@ -337,7 +339,7 @@ sys_lgetxattr(char __user *path, char __
error = user_path_walk_link(path, &nd);
if (error)
return error;
- error = getxattr(nd.dentry, name, value, size);
+ error = getxattr(nd.mnt, nd.dentry, name, value, size);
path_release(&nd);
return error;
}
@@ -351,7 +353,7 @@ sys_fgetxattr(int fd, char __user *name,
f = fget(fd);
if (!f)
return error;
- error = getxattr(f->f_dentry, name, value, size);
+ error = getxattr(f->f_vfsmnt, f->f_dentry, name, value, size);
fput(f);
return error;
}
Index: linux-2.6.19/include/linux/xattr.h
===================================================================
--- linux-2.6.19.orig/include/linux/xattr.h
+++ linux-2.6.19/include/linux/xattr.h
@@ -40,7 +40,8 @@ struct xattr_handler {
size_t size, int flags);
};
-ssize_t vfs_getxattr(struct dentry *, char *, void *, size_t);
+ssize_t vfs_getxattr(struct vfsmount *, struct dentry *, char *, void *,
+ size_t);
ssize_t vfs_listxattr(struct dentry *d, char *list, size_t size);
int vfs_setxattr(struct vfsmount *, struct dentry *, char *, void *, size_t,
int);

View File

@@ -0,0 +1,83 @@
Add struct vfsmount parameters to vfs_link()
Signed-off-by: Tony Jones <tonyj@suse.de>
Signed-off-by: Andreas Gruenbacher <agruen@suse.de>
Index: linux-2.6.19/fs/namei.c
===================================================================
--- linux-2.6.19.orig/fs/namei.c
+++ linux-2.6.19/fs/namei.c
@@ -2254,7 +2254,7 @@ asmlinkage long sys_symlink(const char _
return sys_symlinkat(oldname, AT_FDCWD, newname);
}
-int vfs_link(struct dentry *old_dentry, struct inode *dir, struct dentry *new_dentry)
+int vfs_link(struct vfsmount *old_mnt, struct dentry *old_dentry, struct inode *dir, struct vfsmount *new_mnt, struct dentry *new_dentry)
{
struct inode *inode = old_dentry->d_inode;
int error;
@@ -2332,7 +2332,8 @@ asmlinkage long sys_linkat(int olddfd, c
error = PTR_ERR(new_dentry);
if (IS_ERR(new_dentry))
goto out_unlock;
- error = vfs_link(old_nd.dentry, nd.dentry->d_inode, new_dentry);
+ error = vfs_link(old_nd.mnt, old_nd.dentry, nd.dentry->d_inode, nd.mnt,
+ new_dentry);
dput(new_dentry);
out_unlock:
mutex_unlock(&nd.dentry->d_inode->i_mutex);
Index: linux-2.6.19/include/linux/fs.h
===================================================================
--- linux-2.6.19.orig/include/linux/fs.h
+++ linux-2.6.19/include/linux/fs.h
@@ -1016,7 +1016,7 @@ extern int vfs_create(struct inode *, st
extern int vfs_mkdir(struct inode *, struct vfsmount *, struct dentry *, int);
extern int vfs_mknod(struct inode *, struct vfsmount *, struct dentry *, int, dev_t);
extern int vfs_symlink(struct inode *, struct vfsmount *, struct dentry *, const char *, int);
-extern int vfs_link(struct dentry *, struct inode *, struct dentry *);
+extern int vfs_link(struct vfsmount *, struct dentry *, struct inode *, struct vfsmount *, struct dentry *);
extern int vfs_rmdir(struct inode *, struct dentry *);
extern int vfs_unlink(struct inode *, struct dentry *);
extern int vfs_rename(struct inode *, struct dentry *, struct inode *, struct dentry *);
Index: linux-2.6.19/fs/ecryptfs/inode.c
===================================================================
--- linux-2.6.19.orig/fs/ecryptfs/inode.c
+++ linux-2.6.19/fs/ecryptfs/inode.c
@@ -444,18 +444,23 @@ static int ecryptfs_link(struct dentry *
struct dentry *new_dentry)
{
struct dentry *lower_old_dentry;
+ struct vfsmount *lower_old_mnt;
struct dentry *lower_new_dentry;
+ struct vfsmount *lower_new_mnt;
struct dentry *lower_dir_dentry;
u64 file_size_save;
int rc;
file_size_save = i_size_read(old_dentry->d_inode);
lower_old_dentry = ecryptfs_dentry_to_lower(old_dentry);
+ lower_old_mnt = ecryptfs_dentry_to_lower_mnt(old_dentry);
lower_new_dentry = ecryptfs_dentry_to_lower(new_dentry);
+ lower_new_mnt = ecryptfs_dentry_to_lower_mnt(new_dentry);
dget(lower_old_dentry);
dget(lower_new_dentry);
lower_dir_dentry = lock_parent(lower_new_dentry);
- rc = vfs_link(lower_old_dentry, lower_dir_dentry->d_inode,
+ rc = vfs_link(lower_old_mnt, lower_old_dentry,
+ lower_dir_dentry->d_inode, lower_new_mnt,
lower_new_dentry);
if (rc || !lower_new_dentry->d_inode)
goto out_lock;
Index: linux-2.6.19/fs/nfsd/vfs.c
===================================================================
--- linux-2.6.19.orig/fs/nfsd/vfs.c
+++ linux-2.6.19/fs/nfsd/vfs.c
@@ -1538,7 +1538,7 @@ nfsd_link(struct svc_rqst *rqstp, struct
dold = tfhp->fh_dentry;
dest = dold->d_inode;
- host_err = vfs_link(dold, dirp, dnew);
+ host_err = vfs_link(NULL, dold, dirp, NULL, dnew);
if (!host_err) {
if (EX_ISSYNC(ffhp->fh_export)) {
err = nfserrno(nfsd_sync_dir(ddir));

View File

@@ -0,0 +1,95 @@
Add a struct vfsmount parameter to vfs_listxattr()
Signed-off-by: Tony Jones <tonyj@suse.de>
Signed-off-by: Andreas Gruenbacher <agruen@suse.de>
Index: linux-2.6.19/fs/xattr.c
===================================================================
--- linux-2.6.19.orig/fs/xattr.c
+++ linux-2.6.19/fs/xattr.c
@@ -144,18 +144,20 @@ vfs_getxattr(struct vfsmount *mnt, struc
EXPORT_SYMBOL_GPL(vfs_getxattr);
ssize_t
-vfs_listxattr(struct dentry *d, char *list, size_t size)
+vfs_listxattr(struct vfsmount *mnt, struct dentry *dentry, char *list,
+ size_t size)
{
+ struct inode *inode = dentry->d_inode;
ssize_t error;
- error = security_inode_listxattr(d);
+ error = security_inode_listxattr(dentry);
if (error)
return error;
error = -EOPNOTSUPP;
- if (d->d_inode->i_op && d->d_inode->i_op->listxattr) {
- error = d->d_inode->i_op->listxattr(d, list, size);
- } else {
- error = security_inode_listsecurity(d->d_inode, list, size);
+ if (inode->i_op && inode->i_op->listxattr)
+ error = inode->i_op->listxattr(dentry, list, size);
+ else {
+ error = security_inode_listsecurity(inode, list, size);
if (size && error > size)
error = -ERANGE;
}
@@ -362,7 +364,8 @@ sys_fgetxattr(int fd, char __user *name,
* Extended attribute LIST operations
*/
static ssize_t
-listxattr(struct dentry *d, char __user *list, size_t size)
+listxattr(struct vfsmount *mnt, struct dentry *dentry, char __user *list,
+ size_t size)
{
ssize_t error;
char *klist = NULL;
@@ -375,7 +378,7 @@ listxattr(struct dentry *d, char __user
return -ENOMEM;
}
- error = vfs_listxattr(d, klist, size);
+ error = vfs_listxattr(mnt, dentry, klist, size);
if (error > 0) {
if (size && copy_to_user(list, klist, error))
error = -EFAULT;
@@ -397,7 +400,7 @@ sys_listxattr(char __user *path, char __
error = user_path_walk(path, &nd);
if (error)
return error;
- error = listxattr(nd.dentry, list, size);
+ error = listxattr(nd.mnt, nd.dentry, list, size);
path_release(&nd);
return error;
}
@@ -411,7 +414,7 @@ sys_llistxattr(char __user *path, char _
error = user_path_walk_link(path, &nd);
if (error)
return error;
- error = listxattr(nd.dentry, list, size);
+ error = listxattr(nd.mnt, nd.dentry, list, size);
path_release(&nd);
return error;
}
@@ -425,7 +428,7 @@ sys_flistxattr(int fd, char __user *list
f = fget(fd);
if (!f)
return error;
- error = listxattr(f->f_dentry, list, size);
+ error = listxattr(f->f_vfsmnt, f->f_dentry, list, size);
fput(f);
return error;
}
Index: linux-2.6.19/include/linux/xattr.h
===================================================================
--- linux-2.6.19.orig/include/linux/xattr.h
+++ linux-2.6.19/include/linux/xattr.h
@@ -42,7 +42,7 @@ struct xattr_handler {
ssize_t vfs_getxattr(struct vfsmount *, struct dentry *, char *, void *,
size_t);
-ssize_t vfs_listxattr(struct dentry *d, char *list, size_t size);
+ssize_t vfs_listxattr(struct vfsmount *, struct dentry *, char *, size_t);
int vfs_setxattr(struct vfsmount *, struct dentry *, char *, void *, size_t,
int);
int vfs_removexattr(struct dentry *, char *);

View File

@@ -0,0 +1,87 @@
Add struct vfsmount parameter to vfs_mkdir
Signed-off-by: Tony Jones <tonyj@suse.de>
Signed-off-by: Andreas Gruenbacher <agruen@suse.de>
Index: linux-2.6.19/fs/ecryptfs/inode.c
===================================================================
--- linux-2.6.19.orig/fs/ecryptfs/inode.c
+++ linux-2.6.19/fs/ecryptfs/inode.c
@@ -540,11 +540,14 @@ static int ecryptfs_mkdir(struct inode *
{
int rc;
struct dentry *lower_dentry;
+ struct vfsmount *lower_mnt;
struct dentry *lower_dir_dentry;
lower_dentry = ecryptfs_dentry_to_lower(dentry);
+ lower_mnt = ecryptfs_dentry_to_lower_mnt(dentry);
lower_dir_dentry = lock_parent(lower_dentry);
- rc = vfs_mkdir(lower_dir_dentry->d_inode, lower_dentry, mode);
+ rc = vfs_mkdir(lower_dir_dentry->d_inode, lower_mnt, lower_dentry,
+ mode);
if (rc || !lower_dentry->d_inode)
goto out;
rc = ecryptfs_interpose(lower_dentry, dentry, dir->i_sb, 0);
Index: linux-2.6.19/fs/namei.c
===================================================================
--- linux-2.6.19.orig/fs/namei.c
+++ linux-2.6.19/fs/namei.c
@@ -1919,7 +1919,8 @@ asmlinkage long sys_mknod(const char __u
return sys_mknodat(AT_FDCWD, filename, mode, dev);
}
-int vfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
+int vfs_mkdir(struct inode *dir, struct vfsmount *mnt, struct dentry *dentry,
+ int mode)
{
int error = may_create(dir, dentry, NULL);
@@ -1963,7 +1964,7 @@ asmlinkage long sys_mkdirat(int dfd, con
if (!IS_POSIXACL(nd.dentry->d_inode))
mode &= ~current->fs->umask;
- error = vfs_mkdir(nd.dentry->d_inode, dentry, mode);
+ error = vfs_mkdir(nd.dentry->d_inode, nd.mnt, dentry, mode);
dput(dentry);
out_unlock:
mutex_unlock(&nd.dentry->d_inode->i_mutex);
Index: linux-2.6.19/fs/nfsd/nfs4recover.c
===================================================================
--- linux-2.6.19.orig/fs/nfsd/nfs4recover.c
+++ linux-2.6.19/fs/nfsd/nfs4recover.c
@@ -156,7 +156,7 @@ nfsd4_create_clid_dir(struct nfs4_client
dprintk("NFSD: nfsd4_create_clid_dir: DIRECTORY EXISTS\n");
goto out_put;
}
- status = vfs_mkdir(rec_dir.dentry->d_inode, dentry, S_IRWXU);
+ status = vfs_mkdir(rec_dir.dentry->d_inode, NULL, dentry, S_IRWXU);
out_put:
dput(dentry);
out_unlock:
Index: linux-2.6.19/fs/nfsd/vfs.c
===================================================================
--- linux-2.6.19.orig/fs/nfsd/vfs.c
+++ linux-2.6.19/fs/nfsd/vfs.c
@@ -1183,7 +1183,7 @@ nfsd_create(struct svc_rqst *rqstp, stru
host_err = vfs_create(dirp, dchild, iap->ia_mode, NULL);
break;
case S_IFDIR:
- host_err = vfs_mkdir(dirp, dchild, iap->ia_mode);
+ host_err = vfs_mkdir(dirp, NULL, dchild, iap->ia_mode);
break;
case S_IFCHR:
case S_IFBLK:
Index: linux-2.6.19/include/linux/fs.h
===================================================================
--- linux-2.6.19.orig/include/linux/fs.h
+++ linux-2.6.19/include/linux/fs.h
@@ -1013,7 +1013,7 @@ static inline void unlock_super(struct s
*/
extern int vfs_permission(struct nameidata *, int);
extern int vfs_create(struct inode *, struct dentry *, int, struct nameidata *);
-extern int vfs_mkdir(struct inode *, struct dentry *, int);
+extern int vfs_mkdir(struct inode *, struct vfsmount *, struct dentry *, int);
extern int vfs_mknod(struct inode *, struct dentry *, int, dev_t);
extern int vfs_symlink(struct inode *, struct dentry *, const char *, int);
extern int vfs_link(struct dentry *, struct inode *, struct dentry *);

View File

@@ -0,0 +1,94 @@
Add a struct vfsmount parameter to vfs_mknod()
Signed-off-by: Tony Jones <tonyj@suse.de>
Signed-off-by: Andreas Gruenbacher <agruen@suse.de>
Index: linux-2.6.19/fs/ecryptfs/inode.c
===================================================================
--- linux-2.6.19.orig/fs/ecryptfs/inode.c
+++ linux-2.6.19/fs/ecryptfs/inode.c
@@ -590,11 +590,14 @@ ecryptfs_mknod(struct inode *dir, struct
{
int rc;
struct dentry *lower_dentry;
+ struct vfsmount *lower_mnt;
struct dentry *lower_dir_dentry;
lower_dentry = ecryptfs_dentry_to_lower(dentry);
+ lower_mnt = ecryptfs_dentry_to_lower_mnt(dentry);
lower_dir_dentry = lock_parent(lower_dentry);
- rc = vfs_mknod(lower_dir_dentry->d_inode, lower_dentry, mode, dev);
+ rc = vfs_mknod(lower_dir_dentry->d_inode, lower_mnt, lower_dentry, mode,
+ dev);
if (rc || !lower_dentry->d_inode)
goto out;
rc = ecryptfs_interpose(lower_dentry, dentry, dir->i_sb, 0);
Index: linux-2.6.19/fs/namei.c
===================================================================
--- linux-2.6.19.orig/fs/namei.c
+++ linux-2.6.19/fs/namei.c
@@ -1840,7 +1840,8 @@ fail:
}
EXPORT_SYMBOL_GPL(lookup_create);
-int vfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev)
+int vfs_mknod(struct inode *dir, struct vfsmount *mnt, struct dentry *dentry,
+ int mode, dev_t dev)
{
int error = may_create(dir, dentry, NULL);
@@ -1892,11 +1893,12 @@ asmlinkage long sys_mknodat(int dfd, con
error = vfs_create(nd.dentry->d_inode,dentry,mode,&nd);
break;
case S_IFCHR: case S_IFBLK:
- error = vfs_mknod(nd.dentry->d_inode,dentry,mode,
- new_decode_dev(dev));
+ error = vfs_mknod(nd.dentry->d_inode, nd.mnt, dentry,
+ mode, new_decode_dev(dev));
break;
case S_IFIFO: case S_IFSOCK:
- error = vfs_mknod(nd.dentry->d_inode,dentry,mode,0);
+ error = vfs_mknod(nd.dentry->d_inode, nd.mnt, dentry,
+ mode, 0);
break;
case S_IFDIR:
error = -EPERM;
Index: linux-2.6.19/fs/nfsd/vfs.c
===================================================================
--- linux-2.6.19.orig/fs/nfsd/vfs.c
+++ linux-2.6.19/fs/nfsd/vfs.c
@@ -1189,7 +1189,7 @@ nfsd_create(struct svc_rqst *rqstp, stru
case S_IFBLK:
case S_IFIFO:
case S_IFSOCK:
- host_err = vfs_mknod(dirp, dchild, iap->ia_mode, rdev);
+ host_err = vfs_mknod(dirp, NULL, dchild, iap->ia_mode, rdev);
break;
default:
printk("nfsd: bad file type %o in nfsd_create\n", type);
Index: linux-2.6.19/include/linux/fs.h
===================================================================
--- linux-2.6.19.orig/include/linux/fs.h
+++ linux-2.6.19/include/linux/fs.h
@@ -1014,7 +1014,7 @@ static inline void unlock_super(struct s
extern int vfs_permission(struct nameidata *, int);
extern int vfs_create(struct inode *, struct dentry *, int, struct nameidata *);
extern int vfs_mkdir(struct inode *, struct vfsmount *, struct dentry *, int);
-extern int vfs_mknod(struct inode *, struct dentry *, int, dev_t);
+extern int vfs_mknod(struct inode *, struct vfsmount *, struct dentry *, int, dev_t);
extern int vfs_symlink(struct inode *, struct dentry *, const char *, int);
extern int vfs_link(struct dentry *, struct inode *, struct dentry *);
extern int vfs_rmdir(struct inode *, struct dentry *);
Index: linux-2.6.19/net/unix/af_unix.c
===================================================================
--- linux-2.6.19.orig/net/unix/af_unix.c
+++ linux-2.6.19/net/unix/af_unix.c
@@ -807,7 +807,7 @@ static int unix_bind(struct socket *sock
*/
mode = S_IFSOCK |
(SOCK_INODE(sock)->i_mode & ~current->fs->umask);
- err = vfs_mknod(nd.dentry->d_inode, dentry, mode, 0);
+ err = vfs_mknod(nd.dentry->d_inode, nd.mnt, dentry, mode, 0);
if (err)
goto out_mknod_dput;
mutex_unlock(&nd.dentry->d_inode->i_mutex);

View File

@@ -0,0 +1,365 @@
Add a vfsmount parameter to notify_change()
The vfsmount parameter must be set appropriately for files visibile
outside the kernel. Files that are only used in a filesystem (e.g.,
reiserfs xattr files) will have a NULL vfsmount.
The kernel nfsd also doesn't have the necessary context for client
requests. We cannot put it under any pathname based policy, and
also set vfsmount to NULL there.
The next patch passes the vfsmount to the inode_setattr LSM hook.
Signed-off-by: Tony Jones <tonyj@suse.de>
Signed-off-by: Andreas Gruenbacher <agruen@suse.de>
Index: linux-2.6.19/fs/attr.c
===================================================================
--- linux-2.6.19.orig/fs/attr.c
+++ linux-2.6.19/fs/attr.c
@@ -101,7 +101,8 @@ int inode_setattr(struct inode * inode,
}
EXPORT_SYMBOL(inode_setattr);
-int notify_change(struct dentry * dentry, struct iattr * attr)
+int notify_change(struct vfsmount *mnt, struct dentry * dentry,
+ struct iattr * attr)
{
struct inode *inode = dentry->d_inode;
mode_t mode;
Index: linux-2.6.19/include/linux/fs.h
===================================================================
--- linux-2.6.19.orig/include/linux/fs.h
+++ linux-2.6.19/include/linux/fs.h
@@ -1491,8 +1491,8 @@ static inline int break_lease(struct ino
/* fs/open.c */
-extern int do_truncate(struct dentry *, loff_t start, unsigned int time_attrs,
- struct file *filp);
+extern int do_truncate(struct vfsmount *, struct dentry *, loff_t start,
+ unsigned int time_attrs, struct file *filp);
extern long do_sys_open(int fdf, const char __user *filename, int flags,
int mode);
extern struct file *filp_open(const char *, int, int);
@@ -1639,7 +1639,7 @@ extern int do_remount_sb(struct super_bl
#ifdef CONFIG_BLOCK
extern sector_t bmap(struct inode *, sector_t);
#endif
-extern int notify_change(struct dentry *, struct iattr *);
+extern int notify_change(struct vfsmount *, struct dentry *, struct iattr *);
extern int permission(struct inode *, int, struct nameidata *);
extern int generic_permission(struct inode *, int,
int (*check_acl)(struct inode *, int));
Index: linux-2.6.19/fs/ecryptfs/inode.c
===================================================================
--- linux-2.6.19.orig/fs/ecryptfs/inode.c
+++ linux-2.6.19/fs/ecryptfs/inode.c
@@ -893,12 +893,14 @@ static int ecryptfs_setattr(struct dentr
{
int rc = 0;
struct dentry *lower_dentry;
+ struct vfsmount *lower_mnt;
struct inode *inode;
struct inode *lower_inode;
struct ecryptfs_crypt_stat *crypt_stat;
crypt_stat = &ecryptfs_inode_to_private(dentry->d_inode)->crypt_stat;
lower_dentry = ecryptfs_dentry_to_lower(dentry);
+ lower_mnt = ecryptfs_dentry_to_lower_mnt(dentry);
inode = dentry->d_inode;
lower_inode = ecryptfs_inode_to_lower(inode);
if (ia->ia_valid & ATTR_SIZE) {
@@ -913,7 +915,7 @@ static int ecryptfs_setattr(struct dentr
if (rc < 0)
goto out;
}
- rc = notify_change(lower_dentry, ia);
+ rc = notify_change(lower_mnt, lower_dentry, ia);
out:
ecryptfs_copy_attr_all(inode, lower_inode);
return rc;
Index: linux-2.6.19/fs/fat/file.c
===================================================================
--- linux-2.6.19.orig/fs/fat/file.c
+++ linux-2.6.19/fs/fat/file.c
@@ -92,7 +92,7 @@ int fat_generic_ioctl(struct inode *inod
}
/* This MUST be done before doing anything irreversible... */
- err = notify_change(filp->f_dentry, &ia);
+ err = notify_change(filp->f_vfsmnt, filp->f_dentry, &ia);
if (err)
goto up;
Index: linux-2.6.19/fs/hpfs/namei.c
===================================================================
--- linux-2.6.19.orig/fs/hpfs/namei.c
+++ linux-2.6.19/fs/hpfs/namei.c
@@ -426,7 +426,7 @@ again:
/*printk("HPFS: truncating file before delete.\n");*/
newattrs.ia_size = 0;
newattrs.ia_valid = ATTR_SIZE | ATTR_CTIME;
- err = notify_change(dentry, &newattrs);
+ err = notify_change(NULL, dentry, &newattrs);
put_write_access(inode);
if (!err)
goto again;
Index: linux-2.6.19/fs/nfsd/vfs.c
===================================================================
--- linux-2.6.19.orig/fs/nfsd/vfs.c
+++ linux-2.6.19/fs/nfsd/vfs.c
@@ -359,7 +359,7 @@ nfsd_setattr(struct svc_rqst *rqstp, str
err = nfserr_notsync;
if (!check_guard || guardtime == inode->i_ctime.tv_sec) {
fh_lock(fhp);
- host_err = notify_change(dentry, iap);
+ host_err = notify_change(NULL, dentry, iap);
err = nfserrno(host_err);
fh_unlock(fhp);
}
@@ -896,7 +896,7 @@ static void kill_suid(struct dentry *den
ia.ia_valid = ATTR_KILL_SUID | ATTR_KILL_SGID;
mutex_lock(&dentry->d_inode->i_mutex);
- notify_change(dentry, &ia);
+ notify_change(NULL, dentry, &ia);
mutex_unlock(&dentry->d_inode->i_mutex);
}
Index: linux-2.6.19/fs/open.c
===================================================================
--- linux-2.6.19.orig/fs/open.c
+++ linux-2.6.19/fs/open.c
@@ -194,8 +194,8 @@ out:
return error;
}
-int do_truncate(struct dentry *dentry, loff_t length, unsigned int time_attrs,
- struct file *filp)
+int do_truncate(struct vfsmount *mnt, struct dentry *dentry, loff_t length,
+ unsigned int time_attrs, struct file *filp)
{
int err;
struct iattr newattrs;
@@ -212,7 +212,7 @@ int do_truncate(struct dentry *dentry, l
}
mutex_lock(&dentry->d_inode->i_mutex);
- err = notify_change(dentry, &newattrs);
+ err = notify_change(mnt, dentry, &newattrs);
mutex_unlock(&dentry->d_inode->i_mutex);
return err;
}
@@ -267,7 +267,7 @@ static long do_sys_truncate(const char _
error = locks_verify_truncate(inode, NULL, length);
if (!error) {
DQUOT_INIT(inode);
- error = do_truncate(nd.dentry, length, 0, NULL);
+ error = do_truncate(nd.mnt, nd.dentry, length, 0, NULL);
}
put_write_access(inode);
@@ -319,7 +319,8 @@ static long do_sys_ftruncate(unsigned in
error = locks_verify_truncate(inode, file, length);
if (!error)
- error = do_truncate(dentry, length, ATTR_MTIME|ATTR_CTIME, file);
+ error = do_truncate(file->f_vfsmnt, dentry, length,
+ ATTR_MTIME|ATTR_CTIME, file);
out_putf:
fput(file);
out:
@@ -519,7 +520,7 @@ asmlinkage long sys_fchmod(unsigned int
mode = inode->i_mode;
newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO);
newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
- err = notify_change(dentry, &newattrs);
+ err = notify_change(file->f_vfsmnt, dentry, &newattrs);
mutex_unlock(&inode->i_mutex);
out_putf:
@@ -554,7 +555,7 @@ asmlinkage long sys_fchmodat(int dfd, co
mode = inode->i_mode;
newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO);
newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
- error = notify_change(nd.dentry, &newattrs);
+ error = notify_change(nd.mnt, nd.dentry, &newattrs);
mutex_unlock(&inode->i_mutex);
dput_and_out:
@@ -568,7 +569,8 @@ asmlinkage long sys_chmod(const char __u
return sys_fchmodat(AT_FDCWD, filename, mode);
}
-static int chown_common(struct dentry * dentry, uid_t user, gid_t group)
+static int chown_common(struct vfsmount *mnt, struct dentry * dentry,
+ uid_t user, gid_t group)
{
struct inode * inode;
int error;
@@ -597,7 +599,7 @@ static int chown_common(struct dentry *
if (!S_ISDIR(inode->i_mode))
newattrs.ia_valid |= ATTR_KILL_SUID|ATTR_KILL_SGID;
mutex_lock(&inode->i_mutex);
- error = notify_change(dentry, &newattrs);
+ error = notify_change(mnt, dentry, &newattrs);
mutex_unlock(&inode->i_mutex);
out:
return error;
@@ -611,7 +613,7 @@ asmlinkage long sys_chown(const char __u
error = user_path_walk(filename, &nd);
if (error)
goto out;
- error = chown_common(nd.dentry, user, group);
+ error = chown_common(nd.mnt, nd.dentry, user, group);
path_release(&nd);
out:
return error;
@@ -631,7 +633,7 @@ asmlinkage long sys_fchownat(int dfd, co
error = __user_walk_fd(dfd, filename, follow, &nd);
if (error)
goto out;
- error = chown_common(nd.dentry, user, group);
+ error = chown_common(nd.mnt, nd.dentry, user, group);
path_release(&nd);
out:
return error;
@@ -645,7 +647,7 @@ asmlinkage long sys_lchown(const char __
error = user_path_walk_link(filename, &nd);
if (error)
goto out;
- error = chown_common(nd.dentry, user, group);
+ error = chown_common(nd.mnt, nd.dentry, user, group);
path_release(&nd);
out:
return error;
@@ -664,7 +666,7 @@ asmlinkage long sys_fchown(unsigned int
dentry = file->f_dentry;
audit_inode(NULL, dentry->d_inode);
- error = chown_common(dentry, user, group);
+ error = chown_common(file->f_vfsmnt, dentry, user, group);
fput(file);
out:
return error;
Index: linux-2.6.19/fs/reiserfs/xattr.c
===================================================================
--- linux-2.6.19.orig/fs/reiserfs/xattr.c
+++ linux-2.6.19/fs/reiserfs/xattr.c
@@ -527,7 +527,7 @@ reiserfs_xattr_set(struct inode *inode,
newattrs.ia_size = buffer_size;
newattrs.ia_valid = ATTR_SIZE | ATTR_CTIME;
mutex_lock(&xinode->i_mutex);
- err = notify_change(fp->f_dentry, &newattrs);
+ err = notify_change(NULL, fp->f_dentry, &newattrs);
if (err)
goto out_filp;
@@ -867,7 +867,7 @@ reiserfs_chown_xattrs_filler(void *buf,
}
if (!S_ISDIR(xafile->d_inode->i_mode))
- err = notify_change(xafile, attrs);
+ err = notify_change(NULL, xafile, attrs);
dput(xafile);
return err;
@@ -919,7 +919,7 @@ int reiserfs_chown_xattrs(struct inode *
goto out_dir;
}
- err = notify_change(dir, attrs);
+ err = notify_change(NULL, dir, attrs);
unlock_kernel();
out_dir:
Index: linux-2.6.19/fs/sysfs/file.c
===================================================================
--- linux-2.6.19.orig/fs/sysfs/file.c
+++ linux-2.6.19/fs/sysfs/file.c
@@ -523,7 +523,7 @@ int sysfs_chmod_file(struct kobject *kob
newattrs.ia_mode = (mode & S_IALLUGO) |
(inode->i_mode & ~S_IALLUGO);
newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
- res = notify_change(victim, &newattrs);
+ res = notify_change(NULL, victim, &newattrs);
mutex_unlock(&inode->i_mutex);
}
dput(victim);
Index: linux-2.6.19/fs/utimes.c
===================================================================
--- linux-2.6.19.orig/fs/utimes.c
+++ linux-2.6.19/fs/utimes.c
@@ -61,7 +61,7 @@ asmlinkage long sys_utime(char __user *
goto dput_and_out;
}
mutex_lock(&inode->i_mutex);
- error = notify_change(nd.dentry, &newattrs);
+ error = notify_change(nd.mnt, nd.dentry, &newattrs);
mutex_unlock(&inode->i_mutex);
dput_and_out:
path_release(&nd);
@@ -114,7 +114,7 @@ long do_utimes(int dfd, char __user *fil
goto dput_and_out;
}
mutex_lock(&inode->i_mutex);
- error = notify_change(nd.dentry, &newattrs);
+ error = notify_change(nd.mnt, nd.dentry, &newattrs);
mutex_unlock(&inode->i_mutex);
dput_and_out:
path_release(&nd);
Index: linux-2.6.19/mm/filemap.c
===================================================================
--- linux-2.6.19.orig/mm/filemap.c
+++ linux-2.6.19/mm/filemap.c
@@ -1899,7 +1899,7 @@ int __remove_suid(struct file *file, int
struct iattr newattrs;
newattrs.ia_valid = ATTR_FORCE | kill;
- return notify_change(file->f_dentry, &newattrs);
+ return notify_change(file->f_vfsmnt, file->f_dentry, &newattrs);
}
int remove_suid(struct file *file)
Index: linux-2.6.19/fs/exec.c
===================================================================
--- linux-2.6.19.orig/fs/exec.c
+++ linux-2.6.19/fs/exec.c
@@ -1532,7 +1532,8 @@ int do_coredump(long signr, int exit_cod
goto close_fail;
if (!file->f_op->write)
goto close_fail;
- if (!ispipe && do_truncate(file->f_dentry, 0, 0, file) != 0)
+ if (!ispipe &&
+ do_truncate(file->f_vfsmnt, file->f_dentry, 0, 0, file) != 0)
goto close_fail;
retval = binfmt->core_dump(signr, regs, file);
Index: linux-2.6.19/fs/namei.c
===================================================================
--- linux-2.6.19.orig/fs/namei.c
+++ linux-2.6.19/fs/namei.c
@@ -1583,7 +1583,8 @@ int may_open(struct nameidata *nd, int a
if (!error) {
DQUOT_INIT(inode);
- error = do_truncate(dentry, 0, ATTR_MTIME|ATTR_CTIME, NULL);
+ error = do_truncate(nd->mnt, dentry, 0,
+ ATTR_MTIME|ATTR_CTIME, NULL);
}
put_write_access(inode);
if (error)
Index: linux-2.6.19/mm/tiny-shmem.c
===================================================================
--- linux-2.6.19.orig/mm/tiny-shmem.c
+++ linux-2.6.19/mm/tiny-shmem.c
@@ -86,7 +86,7 @@ struct file *shmem_file_setup(char *name
file->f_mode = FMODE_WRITE | FMODE_READ;
/* notify everyone as to the change of file size */
- error = do_truncate(dentry, size, 0, file);
+ error = do_truncate(file->f_vfsmnt, dentry, size, 0, file);
if (error < 0)
goto close_file;

View File

@@ -0,0 +1,89 @@
Add a struct vfsmount parameter to vfs_removexattr()
Signed-off-by: Tony Jones <tonyj@suse.de>
Signed-off-by: Andreas Gruenbacher <agruen@suse.de>
Index: linux-2.6.19/fs/nfsd/vfs.c
===================================================================
--- linux-2.6.19.orig/fs/nfsd/vfs.c
+++ linux-2.6.19/fs/nfsd/vfs.c
@@ -1986,7 +1986,7 @@ nfsd_set_posix_acl(struct svc_fh *fhp, i
if (!S_ISDIR(inode->i_mode) && type == ACL_TYPE_DEFAULT)
error = 0;
else {
- error = vfs_removexattr(fhp->fh_dentry, name);
+ error = vfs_removexattr(NULL, fhp->fh_dentry, name);
if (error == -ENODATA)
error = 0;
}
Index: linux-2.6.19/fs/xattr.c
===================================================================
--- linux-2.6.19.orig/fs/xattr.c
+++ linux-2.6.19/fs/xattr.c
@@ -166,7 +166,7 @@ vfs_listxattr(struct vfsmount *mnt, stru
EXPORT_SYMBOL_GPL(vfs_listxattr);
int
-vfs_removexattr(struct dentry *dentry, char *name)
+vfs_removexattr(struct vfsmount *mnt, struct dentry *dentry, char *name)
{
struct inode *inode = dentry->d_inode;
int error;
@@ -437,7 +437,7 @@ sys_flistxattr(int fd, char __user *list
* Extended attribute REMOVE operations
*/
static long
-removexattr(struct dentry *d, char __user *name)
+removexattr(struct vfsmount *mnt, struct dentry *dentry, char __user *name)
{
int error;
char kname[XATTR_NAME_MAX + 1];
@@ -448,7 +448,7 @@ removexattr(struct dentry *d, char __use
if (error < 0)
return error;
- return vfs_removexattr(d, kname);
+ return vfs_removexattr(mnt, dentry, kname);
}
asmlinkage long
@@ -460,7 +460,7 @@ sys_removexattr(char __user *path, char
error = user_path_walk(path, &nd);
if (error)
return error;
- error = removexattr(nd.dentry, name);
+ error = removexattr(nd.mnt, nd.dentry, name);
path_release(&nd);
return error;
}
@@ -474,7 +474,7 @@ sys_lremovexattr(char __user *path, char
error = user_path_walk_link(path, &nd);
if (error)
return error;
- error = removexattr(nd.dentry, name);
+ error = removexattr(nd.mnt, nd.dentry, name);
path_release(&nd);
return error;
}
@@ -491,7 +491,7 @@ sys_fremovexattr(int fd, char __user *na
return error;
dentry = f->f_dentry;
audit_inode(NULL, dentry->d_inode);
- error = removexattr(dentry, name);
+ error = removexattr(f->f_vfsmnt, dentry, name);
fput(f);
return error;
}
Index: linux-2.6.19/include/linux/xattr.h
===================================================================
--- linux-2.6.19.orig/include/linux/xattr.h
+++ linux-2.6.19/include/linux/xattr.h
@@ -45,7 +45,7 @@ ssize_t vfs_getxattr(struct vfsmount *,
ssize_t vfs_listxattr(struct vfsmount *, struct dentry *, char *, size_t);
int vfs_setxattr(struct vfsmount *, struct dentry *, char *, void *, size_t,
int);
-int vfs_removexattr(struct dentry *, char *);
+int vfs_removexattr(struct vfsmount *, struct dentry *, char *);
ssize_t generic_getxattr(struct dentry *dentry, const char *name, void *buffer, size_t size);
ssize_t generic_listxattr(struct dentry *dentry, char *buffer, size_t buffer_size);

View File

@@ -0,0 +1,127 @@
Add struct vfsmount parameters to vfs_rename()
Signed-off-by: Tony Jones <tonyj@suse.de>
Signed-off-by: Andreas Gruenbacher <agruen@suse.de>
Index: linux-2.6.19/fs/ecryptfs/inode.c
===================================================================
--- linux-2.6.19.orig/fs/ecryptfs/inode.c
+++ linux-2.6.19/fs/ecryptfs/inode.c
@@ -627,19 +627,24 @@ ecryptfs_rename(struct inode *old_dir, s
{
int rc;
struct dentry *lower_old_dentry;
+ struct vfsmount *lower_old_mnt;
struct dentry *lower_new_dentry;
+ struct vfsmount *lower_new_mnt;
struct dentry *lower_old_dir_dentry;
struct dentry *lower_new_dir_dentry;
lower_old_dentry = ecryptfs_dentry_to_lower(old_dentry);
+ lower_old_mnt = ecryptfs_dentry_to_lower_mnt(old_dentry);
lower_new_dentry = ecryptfs_dentry_to_lower(new_dentry);
+ lower_new_mnt = ecryptfs_dentry_to_lower_mnt(new_dentry);
dget(lower_old_dentry);
dget(lower_new_dentry);
lower_old_dir_dentry = dget_parent(lower_old_dentry);
lower_new_dir_dentry = dget_parent(lower_new_dentry);
lock_rename(lower_old_dir_dentry, lower_new_dir_dentry);
- rc = vfs_rename(lower_old_dir_dentry->d_inode, lower_old_dentry,
- lower_new_dir_dentry->d_inode, lower_new_dentry);
+ rc = vfs_rename(lower_old_dir_dentry->d_inode, lower_old_mnt,
+ lower_old_dentry, lower_new_dir_dentry->d_inode,
+ lower_new_mnt, lower_new_dentry);
if (rc)
goto out_lock;
ecryptfs_copy_attr_all(new_dir, lower_new_dir_dentry->d_inode);
Index: linux-2.6.19/fs/namei.c
===================================================================
--- linux-2.6.19.orig/fs/namei.c
+++ linux-2.6.19/fs/namei.c
@@ -2385,8 +2385,9 @@ asmlinkage long sys_link(const char __us
* ->i_mutex on parents, which works but leads to some truely excessive
* locking].
*/
-static int vfs_rename_dir(struct inode *old_dir, struct dentry *old_dentry,
- struct inode *new_dir, struct dentry *new_dentry)
+static int vfs_rename_dir(struct inode *old_dir, struct vfsmount *old_mnt,
+ struct dentry *old_dentry, struct inode *new_dir,
+ struct vfsmount *new_mnt, struct dentry *new_dentry)
{
int error = 0;
struct inode *target;
@@ -2428,8 +2429,9 @@ static int vfs_rename_dir(struct inode *
return error;
}
-static int vfs_rename_other(struct inode *old_dir, struct dentry *old_dentry,
- struct inode *new_dir, struct dentry *new_dentry)
+static int vfs_rename_other(struct inode *old_dir, struct vfsmount *old_mnt,
+ struct dentry *old_dentry, struct inode *new_dir,
+ struct vfsmount *new_mnt, struct dentry *new_dentry)
{
struct inode *target;
int error;
@@ -2456,8 +2458,9 @@ static int vfs_rename_other(struct inode
return error;
}
-int vfs_rename(struct inode *old_dir, struct dentry *old_dentry,
- struct inode *new_dir, struct dentry *new_dentry)
+int vfs_rename(struct inode *old_dir, struct vfsmount *old_mnt,
+ struct dentry *old_dentry, struct inode *new_dir,
+ struct vfsmount *new_mnt, struct dentry *new_dentry)
{
int error;
int is_dir = S_ISDIR(old_dentry->d_inode->i_mode);
@@ -2486,9 +2489,11 @@ int vfs_rename(struct inode *old_dir, st
old_name = fsnotify_oldname_init(old_dentry->d_name.name);
if (is_dir)
- error = vfs_rename_dir(old_dir,old_dentry,new_dir,new_dentry);
+ error = vfs_rename_dir(old_dir, old_mnt, old_dentry,
+ new_dir, new_mnt, new_dentry);
else
- error = vfs_rename_other(old_dir,old_dentry,new_dir,new_dentry);
+ error = vfs_rename_other(old_dir, old_mnt, old_dentry,
+ new_dir, new_mnt, new_dentry);
if (!error) {
const char *new_name = old_dentry->d_name.name;
fsnotify_move(old_dir, new_dir, old_name, new_name, is_dir,
@@ -2560,8 +2565,8 @@ static int do_rename(int olddfd, const c
if (new_dentry == trap)
goto exit5;
- error = vfs_rename(old_dir->d_inode, old_dentry,
- new_dir->d_inode, new_dentry);
+ error = vfs_rename(old_dir->d_inode, oldnd.mnt, old_dentry,
+ new_dir->d_inode, newnd.mnt, new_dentry);
exit5:
dput(new_dentry);
exit4:
Index: linux-2.6.19/fs/nfsd/vfs.c
===================================================================
--- linux-2.6.19.orig/fs/nfsd/vfs.c
+++ linux-2.6.19/fs/nfsd/vfs.c
@@ -1631,7 +1631,7 @@ nfsd_rename(struct svc_rqst *rqstp, stru
host_err = -EPERM;
} else
#endif
- host_err = vfs_rename(fdir, odentry, tdir, ndentry);
+ host_err = vfs_rename(fdir, NULL, odentry, tdir, NULL, ndentry);
if (!host_err && EX_ISSYNC(tfhp->fh_export)) {
host_err = nfsd_sync_dir(tdentry);
if (!host_err)
Index: linux-2.6.19/include/linux/fs.h
===================================================================
--- linux-2.6.19.orig/include/linux/fs.h
+++ linux-2.6.19/include/linux/fs.h
@@ -1019,7 +1019,7 @@ extern int vfs_symlink(struct inode *, s
extern int vfs_link(struct vfsmount *, struct dentry *, struct inode *, struct vfsmount *, struct dentry *);
extern int vfs_rmdir(struct inode *, struct vfsmount *, struct dentry *);
extern int vfs_unlink(struct inode *, struct vfsmount *, struct dentry *);
-extern int vfs_rename(struct inode *, struct dentry *, struct inode *, struct dentry *);
+extern int vfs_rename(struct inode *, struct vfsmount *, struct dentry *, struct inode *, struct vfsmount *, struct dentry *);
/*
* VFS dentry helper functions.

View File

@@ -0,0 +1,101 @@
Add a struct vfsmount parameter to vfs_rmdir()
Signed-off-by: Tony Jones <tonyj@suse.de>
Signed-off-by: Andreas Gruenbacher <agruen@suse.de>
Index: linux-2.6.19/fs/ecryptfs/inode.c
===================================================================
--- linux-2.6.19.orig/fs/ecryptfs/inode.c
+++ linux-2.6.19/fs/ecryptfs/inode.c
@@ -572,14 +572,16 @@ out:
static int ecryptfs_rmdir(struct inode *dir, struct dentry *dentry)
{
struct dentry *lower_dentry;
+ struct vfsmount *lower_mnt;
struct dentry *lower_dir_dentry;
int rc;
lower_dentry = ecryptfs_dentry_to_lower(dentry);
+ lower_mnt = ecryptfs_dentry_to_lower_mnt(dentry);
dget(dentry);
lower_dir_dentry = lock_parent(lower_dentry);
dget(lower_dentry);
- rc = vfs_rmdir(lower_dir_dentry->d_inode, lower_dentry);
+ rc = vfs_rmdir(lower_dir_dentry->d_inode, lower_mnt, lower_dentry);
dput(lower_dentry);
if (!rc)
d_delete(lower_dentry);
Index: linux-2.6.19/fs/namei.c
===================================================================
--- linux-2.6.19.orig/fs/namei.c
+++ linux-2.6.19/fs/namei.c
@@ -2010,7 +2010,7 @@ void dentry_unhash(struct dentry *dentry
spin_unlock(&dcache_lock);
}
-int vfs_rmdir(struct inode *dir, struct dentry *dentry)
+int vfs_rmdir(struct inode *dir, struct vfsmount *mnt, struct dentry *dentry)
{
int error = may_delete(dir, dentry, 1);
@@ -2074,7 +2074,7 @@ static long do_rmdir(int dfd, const char
error = PTR_ERR(dentry);
if (IS_ERR(dentry))
goto exit2;
- error = vfs_rmdir(nd.dentry->d_inode, dentry);
+ error = vfs_rmdir(nd.dentry->d_inode, nd.mnt, dentry);
dput(dentry);
exit2:
mutex_unlock(&nd.dentry->d_inode->i_mutex);
Index: linux-2.6.19/fs/nfsd/nfs4recover.c
===================================================================
--- linux-2.6.19.orig/fs/nfsd/nfs4recover.c
+++ linux-2.6.19/fs/nfsd/nfs4recover.c
@@ -275,7 +275,7 @@ nfsd4_clear_clid_dir(struct dentry *dir,
* a kernel from the future.... */
nfsd4_list_rec_dir(dentry, nfsd4_remove_clid_file);
mutex_lock_nested(&dir->d_inode->i_mutex, I_MUTEX_PARENT);
- status = vfs_rmdir(dir->d_inode, dentry);
+ status = vfs_rmdir(dir->d_inode, NULL, dentry);
mutex_unlock(&dir->d_inode->i_mutex);
return status;
}
Index: linux-2.6.19/fs/nfsd/vfs.c
===================================================================
--- linux-2.6.19.orig/fs/nfsd/vfs.c
+++ linux-2.6.19/fs/nfsd/vfs.c
@@ -1705,7 +1705,7 @@ nfsd_unlink(struct svc_rqst *rqstp, stru
#endif
host_err = vfs_unlink(dirp, rdentry);
} else { /* It's RMDIR */
- host_err = vfs_rmdir(dirp, rdentry);
+ host_err = vfs_rmdir(dirp, NULL, rdentry);
}
dput(rdentry);
Index: linux-2.6.19/fs/reiserfs/xattr.c
===================================================================
--- linux-2.6.19.orig/fs/reiserfs/xattr.c
+++ linux-2.6.19/fs/reiserfs/xattr.c
@@ -823,7 +823,7 @@ int reiserfs_delete_xattrs(struct inode
if (dir->d_inode->i_nlink <= 2) {
root = get_xa_root(inode->i_sb);
reiserfs_write_lock_xattrs(inode->i_sb);
- err = vfs_rmdir(root->d_inode, dir);
+ err = vfs_rmdir(root->d_inode, NULL, dir);
reiserfs_write_unlock_xattrs(inode->i_sb);
dput(root);
} else {
Index: linux-2.6.19/include/linux/fs.h
===================================================================
--- linux-2.6.19.orig/include/linux/fs.h
+++ linux-2.6.19/include/linux/fs.h
@@ -1017,7 +1017,7 @@ extern int vfs_mkdir(struct inode *, str
extern int vfs_mknod(struct inode *, struct vfsmount *, struct dentry *, int, dev_t);
extern int vfs_symlink(struct inode *, struct vfsmount *, struct dentry *, const char *, int);
extern int vfs_link(struct vfsmount *, struct dentry *, struct inode *, struct vfsmount *, struct dentry *);
-extern int vfs_rmdir(struct inode *, struct dentry *);
+extern int vfs_rmdir(struct inode *, struct vfsmount *, struct dentry *);
extern int vfs_unlink(struct inode *, struct dentry *);
extern int vfs_rename(struct inode *, struct dentry *, struct inode *, struct dentry *);

View File

@@ -0,0 +1,103 @@
Add a struct vfsmount parameter to vfs_setxattr()
Signed-off-by: Tony Jones <tonyj@suse.de>
Signed-off-by: Andreas Gruenbacher <agruen@suse.de>
Index: linux-2.6.19/fs/nfsd/vfs.c
===================================================================
--- linux-2.6.19.orig/fs/nfsd/vfs.c
+++ linux-2.6.19/fs/nfsd/vfs.c
@@ -416,7 +416,7 @@ set_nfsv4_acl_one(struct dentry *dentry,
goto out;
}
- error = vfs_setxattr(dentry, key, buf, len, 0);
+ error = vfs_setxattr(NULL, dentry, key, buf, len, 0);
out:
kfree(buf);
return error;
@@ -1981,7 +1981,7 @@ nfsd_set_posix_acl(struct svc_fh *fhp, i
size = 0;
if (size)
- error = vfs_setxattr(fhp->fh_dentry, name, value, size, 0);
+ error = vfs_setxattr(NULL, fhp->fh_dentry, name, value, size,0);
else {
if (!S_ISDIR(inode->i_mode) && type == ACL_TYPE_DEFAULT)
error = 0;
Index: linux-2.6.19/fs/xattr.c
===================================================================
--- linux-2.6.19.orig/fs/xattr.c
+++ linux-2.6.19/fs/xattr.c
@@ -70,8 +70,8 @@ xattr_permission(struct inode *inode, co
}
int
-vfs_setxattr(struct dentry *dentry, char *name, void *value,
- size_t size, int flags)
+vfs_setxattr(struct vfsmount *mnt, struct dentry *dentry, char *name,
+ void *value, size_t size, int flags)
{
struct inode *inode = dentry->d_inode;
int error;
@@ -194,8 +194,8 @@ EXPORT_SYMBOL_GPL(vfs_removexattr);
* Extended attribute SET operations
*/
static long
-setxattr(struct dentry *d, char __user *name, void __user *value,
- size_t size, int flags)
+setxattr(struct vfsmount *mnt, struct dentry *dentry, char __user *name,
+ void __user *value, size_t size, int flags)
{
int error;
void *kvalue = NULL;
@@ -222,7 +222,7 @@ setxattr(struct dentry *d, char __user *
}
}
- error = vfs_setxattr(d, kname, kvalue, size, flags);
+ error = vfs_setxattr(mnt, dentry, kname, kvalue, size, flags);
kfree(kvalue);
return error;
}
@@ -237,7 +237,7 @@ sys_setxattr(char __user *path, char __u
error = user_path_walk(path, &nd);
if (error)
return error;
- error = setxattr(nd.dentry, name, value, size, flags);
+ error = setxattr(nd.mnt, nd.dentry, name, value, size, flags);
path_release(&nd);
return error;
}
@@ -252,7 +252,7 @@ sys_lsetxattr(char __user *path, char __
error = user_path_walk_link(path, &nd);
if (error)
return error;
- error = setxattr(nd.dentry, name, value, size, flags);
+ error = setxattr(nd.mnt, nd.dentry, name, value, size, flags);
path_release(&nd);
return error;
}
@@ -270,7 +270,7 @@ sys_fsetxattr(int fd, char __user *name,
return error;
dentry = f->f_dentry;
audit_inode(NULL, dentry->d_inode);
- error = setxattr(dentry, name, value, size, flags);
+ error = setxattr(f->f_vfsmnt, dentry, name, value, size, flags);
fput(f);
return error;
}
Index: linux-2.6.19/include/linux/xattr.h
===================================================================
--- linux-2.6.19.orig/include/linux/xattr.h
+++ linux-2.6.19/include/linux/xattr.h
@@ -42,7 +42,8 @@ struct xattr_handler {
ssize_t vfs_getxattr(struct dentry *, char *, void *, size_t);
ssize_t vfs_listxattr(struct dentry *d, char *list, size_t size);
-int vfs_setxattr(struct dentry *, char *, void *, size_t, int);
+int vfs_setxattr(struct vfsmount *, struct dentry *, char *, void *, size_t,
+ int);
int vfs_removexattr(struct dentry *, char *);
ssize_t generic_getxattr(struct dentry *dentry, const char *name, void *buffer, size_t size);

View File

@@ -0,0 +1,90 @@
Add a struct vfsmount parameter to vfs_symlink()
Signed-off-by: Tony Jones <tonyj@suse.de>
Signed-off-by: Andreas Gruenbacher <agruen@suse.de>
Index: linux-2.6.19/fs/ecryptfs/inode.c
===================================================================
--- linux-2.6.19.orig/fs/ecryptfs/inode.c
+++ linux-2.6.19/fs/ecryptfs/inode.c
@@ -502,6 +502,7 @@ static int ecryptfs_symlink(struct inode
{
int rc;
struct dentry *lower_dentry;
+ struct vfsmount *lower_mnt;
struct dentry *lower_dir_dentry;
umode_t mode;
char *encoded_symname;
@@ -510,6 +511,7 @@ static int ecryptfs_symlink(struct inode
lower_dentry = ecryptfs_dentry_to_lower(dentry);
dget(lower_dentry);
+ lower_mnt = ecryptfs_dentry_to_lower_mnt(dentry);
lower_dir_dentry = lock_parent(lower_dentry);
mode = S_IALLUGO;
encoded_symlen = ecryptfs_encode_filename(crypt_stat, symname,
@@ -519,7 +521,7 @@ static int ecryptfs_symlink(struct inode
rc = encoded_symlen;
goto out_lock;
}
- rc = vfs_symlink(lower_dir_dentry->d_inode, lower_dentry,
+ rc = vfs_symlink(lower_dir_dentry->d_inode, lower_mnt, lower_dentry,
encoded_symname, mode);
kfree(encoded_symname);
if (rc || !lower_dentry->d_inode)
Index: linux-2.6.19/fs/namei.c
===================================================================
--- linux-2.6.19.orig/fs/namei.c
+++ linux-2.6.19/fs/namei.c
@@ -2189,7 +2189,8 @@ asmlinkage long sys_unlink(const char __
return do_unlinkat(AT_FDCWD, pathname);
}
-int vfs_symlink(struct inode *dir, struct dentry *dentry, const char *oldname, int mode)
+int vfs_symlink(struct inode *dir, struct vfsmount *mnt, struct dentry *dentry,
+ const char *oldname, int mode)
{
int error = may_create(dir, dentry, NULL);
@@ -2235,7 +2236,8 @@ asmlinkage long sys_symlinkat(const char
if (IS_ERR(dentry))
goto out_unlock;
- error = vfs_symlink(nd.dentry->d_inode, dentry, from, S_IALLUGO);
+ error = vfs_symlink(nd.dentry->d_inode, nd.mnt, dentry, from,
+ S_IALLUGO);
dput(dentry);
out_unlock:
mutex_unlock(&nd.dentry->d_inode->i_mutex);
Index: linux-2.6.19/fs/nfsd/vfs.c
===================================================================
--- linux-2.6.19.orig/fs/nfsd/vfs.c
+++ linux-2.6.19/fs/nfsd/vfs.c
@@ -1474,11 +1474,12 @@ nfsd_symlink(struct svc_rqst *rqstp, str
else {
strncpy(path_alloced, path, plen);
path_alloced[plen] = 0;
- host_err = vfs_symlink(dentry->d_inode, dnew, path_alloced, mode);
+ host_err = vfs_symlink(dentry->d_inode, NULL, dnew,
+ path_alloced, mode);
kfree(path_alloced);
}
} else
- host_err = vfs_symlink(dentry->d_inode, dnew, path, mode);
+ host_err = vfs_symlink(dentry->d_inode, NULL, dnew, path, mode);
if (!host_err) {
if (EX_ISSYNC(fhp->fh_export))
Index: linux-2.6.19/include/linux/fs.h
===================================================================
--- linux-2.6.19.orig/include/linux/fs.h
+++ linux-2.6.19/include/linux/fs.h
@@ -1015,7 +1015,7 @@ extern int vfs_permission(struct nameida
extern int vfs_create(struct inode *, struct dentry *, int, struct nameidata *);
extern int vfs_mkdir(struct inode *, struct vfsmount *, struct dentry *, int);
extern int vfs_mknod(struct inode *, struct vfsmount *, struct dentry *, int, dev_t);
-extern int vfs_symlink(struct inode *, struct dentry *, const char *, int);
+extern int vfs_symlink(struct inode *, struct vfsmount *, struct dentry *, const char *, int);
extern int vfs_link(struct dentry *, struct inode *, struct dentry *);
extern int vfs_rmdir(struct inode *, struct dentry *);
extern int vfs_unlink(struct inode *, struct dentry *);

View File

@@ -0,0 +1,96 @@
Add a struct vfsmount parameter to vfs_unlink()
Signed-off-by: Tony Jones <tonyj@suse.de>
Signed-off-by: Andreas Gruenbacher <agruen@suse.de>
Index: linux-2.6.19/fs/ecryptfs/inode.c
===================================================================
--- linux-2.6.19.orig/fs/ecryptfs/inode.c
+++ linux-2.6.19/fs/ecryptfs/inode.c
@@ -485,10 +485,11 @@ static int ecryptfs_unlink(struct inode
{
int rc = 0;
struct dentry *lower_dentry = ecryptfs_dentry_to_lower(dentry);
+ struct vfsmount *lower_mnt = ecryptfs_dentry_to_lower_mnt(dentry);
struct inode *lower_dir_inode = ecryptfs_inode_to_lower(dir);
lock_parent(lower_dentry);
- rc = vfs_unlink(lower_dir_inode, lower_dentry);
+ rc = vfs_unlink(lower_dir_inode, lower_mnt, lower_dentry);
if (rc) {
printk(KERN_ERR "Error in vfs_unlink; rc = [%d]\n", rc);
goto out_unlock;
Index: linux-2.6.19/fs/namei.c
===================================================================
--- linux-2.6.19.orig/fs/namei.c
+++ linux-2.6.19/fs/namei.c
@@ -2090,7 +2090,7 @@ asmlinkage long sys_rmdir(const char __u
return do_rmdir(AT_FDCWD, pathname);
}
-int vfs_unlink(struct inode *dir, struct dentry *dentry)
+int vfs_unlink(struct inode *dir, struct vfsmount *mnt, struct dentry *dentry)
{
int error = may_delete(dir, dentry, 0);
@@ -2154,7 +2154,7 @@ static long do_unlinkat(int dfd, const c
inode = dentry->d_inode;
if (inode)
atomic_inc(&inode->i_count);
- error = vfs_unlink(nd.dentry->d_inode, dentry);
+ error = vfs_unlink(nd.dentry->d_inode, nd.mnt, dentry);
exit2:
dput(dentry);
}
Index: linux-2.6.19/fs/nfsd/nfs4recover.c
===================================================================
--- linux-2.6.19.orig/fs/nfsd/nfs4recover.c
+++ linux-2.6.19/fs/nfsd/nfs4recover.c
@@ -260,7 +260,7 @@ nfsd4_remove_clid_file(struct dentry *di
return -EINVAL;
}
mutex_lock(&dir->d_inode->i_mutex);
- status = vfs_unlink(dir->d_inode, dentry);
+ status = vfs_unlink(dir->d_inode, NULL, dentry);
mutex_unlock(&dir->d_inode->i_mutex);
return status;
}
Index: linux-2.6.19/fs/nfsd/vfs.c
===================================================================
--- linux-2.6.19.orig/fs/nfsd/vfs.c
+++ linux-2.6.19/fs/nfsd/vfs.c
@@ -1703,7 +1703,7 @@ nfsd_unlink(struct svc_rqst *rqstp, stru
host_err = -EPERM;
} else
#endif
- host_err = vfs_unlink(dirp, rdentry);
+ host_err = vfs_unlink(dirp, NULL, rdentry);
} else { /* It's RMDIR */
host_err = vfs_rmdir(dirp, NULL, rdentry);
}
Index: linux-2.6.19/include/linux/fs.h
===================================================================
--- linux-2.6.19.orig/include/linux/fs.h
+++ linux-2.6.19/include/linux/fs.h
@@ -1018,7 +1018,7 @@ extern int vfs_mknod(struct inode *, str
extern int vfs_symlink(struct inode *, struct vfsmount *, struct dentry *, const char *, int);
extern int vfs_link(struct vfsmount *, struct dentry *, struct inode *, struct vfsmount *, struct dentry *);
extern int vfs_rmdir(struct inode *, struct vfsmount *, struct dentry *);
-extern int vfs_unlink(struct inode *, struct dentry *);
+extern int vfs_unlink(struct inode *, struct vfsmount *, struct dentry *);
extern int vfs_rename(struct inode *, struct dentry *, struct inode *, struct dentry *);
/*
Index: linux-2.6.19/ipc/mqueue.c
===================================================================
--- linux-2.6.19.orig/ipc/mqueue.c
+++ linux-2.6.19/ipc/mqueue.c
@@ -747,7 +747,7 @@ asmlinkage long sys_mq_unlink(const char
if (inode)
atomic_inc(&inode->i_count);
- err = vfs_unlink(dentry->d_parent->d_inode, dentry);
+ err = vfs_unlink(dentry->d_parent->d_inode, mqueue_mnt, dentry);
out_err:
dput(dentry);