[AppArmor 00/47] AppArmor security module overview

2007-12-20 Thread John
-- 

This submission of the AppArmor security module is based against 2.6.24-rc4-mm.

Any comments and feedback to improve implementation are appreciated.

Changes since previous submission
- added apparmor security goal document.
  Documentation/lsm/AppArmor-Security-Goal.txt
- removed DAC style permissions in favor of a simpler file owner
  permissions specification
- include the fgetattr and fsetattr patches by Miklos Szeredi
  [EMAIL PROTECTED], and update them to use ATTR_FILE to enable LSMs to
  distinguish file descriptor operations
- fix error where a NULL sock passed to socket_getsocket_getpeersec_dgram()
  was not correctly handled.
- fix error in link permission subset test

Outstanding Issues
- use of d_namespace_path and buffer allocation to obtain a pathname for
  mediation.
- conditional passing of the vfsmnt.  This can be addressed by rebasing
  on the lookup intent patches but that has not been done for this
  submission.
- ipc and signal mediation are a wip and not included.
- fine grained network mediation
- system confinement from boot is a wip and not included.
- documentation needs to be updated to include newest features


The patch series consists of five areas:

 (1) Pass struct vfsmount through to LSM hooks.

 (2) Fixes and improvements to __d_path():

 (a) make it unambiguous and exclude unreachable paths from
 /proc/mounts,

 (b) make its result consistent in the face of remounts,

 (c) introduce d_namespace_path(), a variant of d_path that goes up
 to the namespace root instead of the chroot.

 (d) the behavior of d_path() and getcwd() remain unchanged, and
 there is no hidding of unreachable paths in /proc/mounts.  The
 patches addressing these have been seperated from the AppArmor
 submission and will be introduced at a later date.
 
 Part (a) has been in the -mm tree for a while; this series includes
 an updated copy of the -mm patch. Parts (b) and (c) shouldn't be too
 controversial.

 (3) Be able to distinguish file descriptor access from access by name
 in LSM hooks.

 Applications expect different behavior from file descriptor
 accesses and accesses by name in some cases. We need to pass this
 information down the LSM hooks to allow AppArmor to tell which is
 which.

 (4) Convert the selinux sysctl pathname computation code into a standalone
 function.

 (5) The AppArmor LSM itself.

 (See below.)

A tarball of the kernel patches, base user-space utilities, example
profiles, and technical documentation (including a walk-through) are
available at:

  http://forgeftp.novell.com/apparmor/LKML_Submission-Dec-07/

Only the most recent features are covered in brief here for a more
complete explaination please refere to the technical documentation.


File ownership permissions
  The DAC style permissions mask allowing the specification of permission
  for each of user, group, and other have been removed, after further feed
  back and discussion, in favor of a simpler permission set that allows
  specifying permissions for file ownership as determined by fsuid.

  Traditional AppArmor rules map to specifying permissions for files
  all files, to reduce the permissions grant the owner keyword can
  be added to a rule.

  /foo rw,  # allow access to file /foo
  owner /foo rw,# allow access to file /foo only if its uid == fsuid


-
To unsubscribe from this list: send the line unsubscribe 
linux-security-module in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[AppArmor 01/47] Pass struct vfsmount to the inode_create LSM hook

2007-12-20 Thread John
This is needed for computing pathnames in the AppArmor LSM.

Signed-off-by: Tony Jones [EMAIL PROTECTED]
Signed-off-by: Andreas Gruenbacher [EMAIL PROTECTED]
Signed-off-by: John Johansen [EMAIL PROTECTED]

---
 fs/namei.c   |2 +-
 include/linux/security.h |9 ++---
 security/dummy.c |2 +-
 security/security.c  |5 +++--
 security/selinux/hooks.c |3 ++-
 5 files changed, 13 insertions(+), 8 deletions(-)

--- a/fs/namei.c
+++ b/fs/namei.c
@@ -1586,7 +1586,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, dentry, nd ? nd-path.mnt : NULL, 
mode);
if (error)
return error;
DQUOT_INIT(dir);
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -314,6 +314,7 @@ struct request_sock;
  * Check permission to create a regular file.
  * @dir contains inode structure of the parent of the new file.
  * @dentry contains the dentry structure for the file to be created.
+ * @mnt is the vfsmount corresponding to @dentry (may be NULL).
  * @mode contains the file mode of the file to be created.
  * Return 0 if permission is granted.
  * @inode_link:
@@ -1272,8 +1273,8 @@ 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,
-struct dentry *dentry, int mode);
+   int (*inode_create) (struct inode *dir, struct dentry *dentry,
+struct vfsmount *mnt, int mode);
int (*inode_link) (struct dentry *old_dentry,
   struct inode *dir, struct dentry *new_dentry);
int (*inode_unlink) (struct inode *dir, struct dentry *dentry);
@@ -1536,7 +1537,8 @@ int security_inode_alloc(struct inode *i
 void security_inode_free(struct inode *inode);
 int security_inode_init_security(struct inode *inode, struct inode *dir,
  char **name, void **value, size_t *len);
-int security_inode_create(struct inode *dir, struct dentry *dentry, int mode);
+int security_inode_create(struct inode *dir, struct dentry *dentry,
+ struct vfsmount *mnt, int mode);
 int security_inode_link(struct dentry *old_dentry, struct inode *dir,
 struct dentry *new_dentry);
 int security_inode_unlink(struct inode *dir, struct dentry *dentry);
@@ -1847,6 +1849,7 @@ static inline int security_inode_init_se

 static inline int security_inode_create (struct inode *dir,
 struct dentry *dentry,
+struct vfsmount *mnt,
 int mode)
 {
return 0;
--- a/security/dummy.c
+++ b/security/dummy.c
@@ -290,7 +290,7 @@ static int dummy_inode_init_security (st
 }
 
 static int dummy_inode_create (struct inode *inode, struct dentry *dentry,
-  int mask)
+  struct vfsmount *mnt, int mask)
 {
return 0;
 }
--- a/security/security.c
+++ b/security/security.c
@@ -348,11 +348,12 @@ int security_inode_init_security(struct 
 }
 EXPORT_SYMBOL(security_inode_init_security);
 
-int security_inode_create(struct inode *dir, struct dentry *dentry, int mode)
+int security_inode_create(struct inode *dir, struct dentry *dentry,
+ struct vfsmount *mnt, int mode)
 {
if (unlikely(IS_PRIVATE(dir)))
return 0;
-   return security_ops-inode_create(dir, dentry, mode);
+   return security_ops-inode_create(dir, dentry, mnt, mode);
 }
 
 int security_inode_link(struct dentry *old_dentry, struct inode *dir,
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -2411,7 +2411,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 dentry *dentry,
+struct vfsmount *mnt, int mask)
 {
return may_create(dir, dentry, SECCLASS_FILE);
 }

-- 

-
To unsubscribe from this list: send the line unsubscribe 
linux-security-module in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[AppArmor 02/47] Pass struct path down to remove_suid and children

2007-12-20 Thread John
Required by a later patch that adds a struct vfsmount parameter to
notify_change().

Signed-off-by: Tony Jones [EMAIL PROTECTED]
Signed-off-by: Andreas Gruenbacher [EMAIL PROTECTED]
Signed-off-by: John Johansen [EMAIL PROTECTED]

---

 fs/ntfs/file.c |2 +-
 fs/reiser4/plugin/file/cryptcompress.c |2 +-
 fs/reiser4/plugin/file/file.c  |2 +-
 fs/splice.c|4 ++--
 fs/xfs/linux-2.6/xfs_lrw.c |2 +-
 include/linux/fs.h |4 ++--
 mm/filemap.c   |   16 
 mm/filemap_xip.c   |2 +-
 8 files changed, 17 insertions(+), 17 deletions(-)

--- a/fs/ntfs/file.c
+++ b/fs/ntfs/file.c
@@ -2118,7 +2118,7 @@ static ssize_t ntfs_file_aio_write_noloc
goto out;
if (!count)
goto out;
-   err = remove_suid(file-f_path.dentry);
+   err = remove_suid(file-f_path);
if (err)
goto out;
file_update_time(file);
--- a/fs/reiser4/plugin/file/cryptcompress.c
+++ b/fs/reiser4/plugin/file/cryptcompress.c
@@ -2828,7 +2828,7 @@ ssize_t write_cryptcompress(struct file 
goto out;
if (unlikely(count == 0))
goto out;
-   result = remove_suid(file-f_dentry);
+   result = remove_suid(file-f_path);
if (unlikely(result != 0))
goto out;
/* remove_suid might create a transaction */
--- a/fs/reiser4/plugin/file/file.c
+++ b/fs/reiser4/plugin/file/file.c
@@ -2124,7 +2124,7 @@ ssize_t write_unix_file(struct file *fil
return result;
}
 
-   result = remove_suid(file-f_dentry);
+   result = remove_suid(file-f_path);
if (result) {
mutex_unlock(inode-i_mutex);
context_set_commit_async(ctx);
--- a/fs/splice.c
+++ b/fs/splice.c
@@ -781,7 +781,7 @@ generic_file_splice_write_nolock(struct 
ssize_t ret;
int err;
 
-   err = remove_suid(out-f_path.dentry);
+   err = remove_suid(out-f_path);
if (unlikely(err))
return err;
 
@@ -841,7 +841,7 @@ generic_file_splice_write(struct pipe_in
if (killpriv)
err = security_inode_killpriv(out-f_path.dentry);
if (!err  killsuid)
-   err = __remove_suid(out-f_path.dentry, killsuid);
+   err = __remove_suid(out-f_path, killsuid);
mutex_unlock(inode-i_mutex);
if (err)
return err;
--- a/fs/xfs/linux-2.6/xfs_lrw.c
+++ b/fs/xfs/linux-2.6/xfs_lrw.c
@@ -723,7 +723,7 @@ start:
 !capable(CAP_FSETID)) {
error = xfs_write_clear_setuid(xip);
if (likely(!error))
-   error = -remove_suid(file-f_path.dentry);
+   error = -remove_suid(file-f_path);
if (unlikely(error)) {
goto out_unlock_internal;
}
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -1757,9 +1757,9 @@ extern void iget_failed(struct 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 __remove_suid(struct path *, int);
 extern int should_remove_suid(struct dentry *);
-extern int remove_suid(struct dentry *);
+extern int remove_suid(struct path *);
 
 extern void __insert_inode_hash(struct inode *, unsigned long hashval);
 extern void remove_inode_hash(struct inode *);
--- a/mm/filemap.c
+++ b/mm/filemap.c
@@ -1638,26 +1638,26 @@ int should_remove_suid(struct dentry *de
 }
 EXPORT_SYMBOL(should_remove_suid);
 
-int __remove_suid(struct dentry *dentry, int kill)
+int __remove_suid(struct path *path, int kill)
 {
struct iattr newattrs;
 
newattrs.ia_valid = ATTR_FORCE | kill;
-   return notify_change(dentry, newattrs);
+   return notify_change(path-dentry, newattrs);
 }
 
-int remove_suid(struct dentry *dentry)
+int remove_suid(struct path *path)
 {
-   int killsuid = should_remove_suid(dentry);
-   int killpriv = security_inode_need_killpriv(dentry);
+   int killsuid = should_remove_suid(path-dentry);
+   int killpriv = security_inode_need_killpriv(path-dentry);
int error = 0;
 
if (killpriv  0)
return killpriv;
if (killpriv)
-   error = security_inode_killpriv(dentry);
+   error = security_inode_killpriv(path-dentry);
if (!error  killsuid)
-   error = __remove_suid(dentry, killsuid);
+   error = __remove_suid(path, killsuid);
 
return error;
 }
@@ -2370,7 +2370,7 @@ __generic_file_aio_write_nolock(struct k
if (count == 0)
goto out;
 
-   err = remove_suid(file-f_path.dentry);
+   err = remove_suid(file-f_path);

[AppArmor 04/47] Pass struct vfsmount to the inode_setattr LSM hook

2007-12-20 Thread John
This is needed for computing pathnames in the AppArmor LSM.

Signed-off-by: Tony Jones [EMAIL PROTECTED]
Signed-off-by: Andreas Gruenbacher [EMAIL PROTECTED]
Signed-off-by: John Johansen [EMAIL PROTECTED]

---
 fs/attr.c|4 ++--
 include/linux/security.h |8 ++--
 security/dummy.c |3 ++-
 security/security.c  |5 +++--
 security/selinux/hooks.c |5 +++--
 5 files changed, 16 insertions(+), 9 deletions(-)

--- a/fs/attr.c
+++ b/fs/attr.c
@@ -159,13 +159,13 @@ int notify_change(struct dentry *dentry,
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(dentry, mnt, 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(dentry, mnt, attr);
if (!error) {
if ((ia_valid  ATTR_UID  attr-ia_uid != 
inode-i_uid) ||
(ia_valid  ATTR_GID  attr-ia_gid != 
inode-i_gid))
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -389,6 +389,7 @@ struct request_sock;
  * file attributes change (such as when a file is truncated, chown/chmod
  * operations, transferring disk quotas, etc).
  * @dentry contains the dentry structure for the file.
+ * @mnt is the vfsmount corresponding to @dentry (may be NULL).
  * @attr is the iattr structure containing the new file attributes.
  * Return 0 if permission is granted.
  * @inode_getattr:
@@ -1289,7 +1290,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 dentry *dentry, struct vfsmount *mnt,
+ 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,
@@ -1552,7 +1554,8 @@ int security_inode_rename(struct inode *
 int security_inode_readlink(struct dentry *dentry);
 int security_inode_follow_link(struct dentry *dentry, struct nameidata *nd);
 int security_inode_permission(struct inode *inode, int mask, struct nameidata 
*nd);
-int security_inode_setattr(struct dentry *dentry, struct iattr *attr);
+int security_inode_setattr(struct dentry *dentry, struct vfsmount *mnt,
+  struct iattr *attr);
 int security_inode_getattr(struct vfsmount *mnt, struct dentry *dentry);
 void security_inode_delete(struct inode *inode);
 int security_inode_setxattr(struct dentry *dentry, char *name,
@@ -1921,6 +1924,7 @@ static inline int security_inode_permiss
 }
 
 static inline int security_inode_setattr (struct dentry *dentry,
+ struct vfsmount *mnt,
  struct iattr *attr)
 {
return 0;
--- a/security/dummy.c
+++ b/security/dummy.c
@@ -353,7 +353,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 dentry *dentry, struct vfsmount *mnt,
+   struct iattr *iattr)
 {
return 0;
 }
--- a/security/security.c
+++ b/security/security.c
@@ -431,11 +431,12 @@ int security_inode_permission(struct ino
return security_ops-inode_permission(inode, mask, nd);
 }
 
-int security_inode_setattr(struct dentry *dentry, struct iattr *attr)
+int security_inode_setattr(struct dentry *dentry, struct vfsmount *mnt,
+  struct iattr *attr)
 {
if (unlikely(IS_PRIVATE(dentry-d_inode)))
return 0;
-   return security_ops-inode_setattr(dentry, attr);
+   return security_ops-inode_setattr(dentry, mnt, attr);
 }
 
 int security_inode_getattr(struct vfsmount *mnt, struct dentry *dentry)
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -2502,11 +2502,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 dentry *dentry, struct vfsmount *mnt,
+struct iattr *iattr)
 {
int rc;
 
-   rc = secondary_ops-inode_setattr(dentry, iattr);
+   rc = secondary_ops-inode_setattr(dentry, 

[AppArmor 05/47] Add struct vfsmount parameter to vfs_mkdir()

2007-12-20 Thread John
The vfsmount will be passed down to the LSM hook so that LSMs can compute
pathnames.

Signed-off-by: Tony Jones [EMAIL PROTECTED]
Signed-off-by: Andreas Gruenbacher [EMAIL PROTECTED]
Signed-off-by: John Johansen [EMAIL PROTECTED]

---
 fs/ecryptfs/inode.c   |5 -
 fs/namei.c|5 +++--
 fs/nfsd/nfs4recover.c |3 ++-
 fs/nfsd/vfs.c |9 ++---
 fs/unionfs/copyup.c   |5 -
 fs/unionfs/inode.c|3 ++-
 fs/unionfs/sioq.c |2 +-
 fs/unionfs/sioq.h |1 +
 include/linux/fs.h|2 +-
 9 files changed, 24 insertions(+), 11 deletions(-)

--- a/fs/ecryptfs/inode.c
+++ b/fs/ecryptfs/inode.c
@@ -499,11 +499,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_dentry, lower_mnt,
+  mode);
if (rc || !lower_dentry-d_inode)
goto out;
rc = ecryptfs_interpose(lower_dentry, dentry, dir-i_sb, 0);
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -2107,7 +2107,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 dentry *dentry, struct vfsmount *mnt,
+ int mode)
 {
int error = may_create(dir, dentry, NULL);
 
@@ -2154,7 +2155,7 @@ asmlinkage long sys_mkdirat(int dfd, con
error = mnt_want_write(nd.path.mnt);
if (error)
goto out_dput;
-   error = vfs_mkdir(nd.path.dentry-d_inode, dentry, mode);
+   error = vfs_mkdir(nd.path.dentry-d_inode, dentry, nd.path.mnt, mode);
mnt_drop_write(nd.path.mnt);
 out_dput:
dput(dentry);
--- a/fs/nfsd/nfs4recover.c
+++ b/fs/nfsd/nfs4recover.c
@@ -158,7 +158,8 @@ nfsd4_create_clid_dir(struct nfs4_client
status = mnt_want_write(rec_dir.path.mnt);
if (status)
goto out_put;
-   status = vfs_mkdir(rec_dir.path.dentry-d_inode, dentry, S_IRWXU);
+   status = vfs_mkdir(rec_dir.path.dentry-d_inode, dentry,
+  rec_dir.path.mnt, S_IRWXU);
mnt_drop_write(rec_dir.path.mnt);
 out_put:
dput(dentry);
--- a/fs/nfsd/vfs.c
+++ b/fs/nfsd/vfs.c
@@ -1166,6 +1166,7 @@ nfsd_create(struct svc_rqst *rqstp, stru
int type, dev_t rdev, struct svc_fh *resfhp)
 {
struct dentry   *dentry, *dchild = NULL;
+   struct svc_export *exp;
struct inode*dirp;
__be32  err;
int host_err;
@@ -1182,6 +1183,7 @@ nfsd_create(struct svc_rqst *rqstp, stru
goto out;
 
dentry = fhp-fh_dentry;
+   exp = fhp-fh_export;
dirp = dentry-d_inode;
 
err = nfserr_notdir;
@@ -1198,7 +1200,7 @@ nfsd_create(struct svc_rqst *rqstp, stru
host_err = PTR_ERR(dchild);
if (IS_ERR(dchild))
goto out_nfserr;
-   err = fh_compose(resfhp, fhp-fh_export, dchild, fhp);
+   err = fh_compose(resfhp, exp, dchild, fhp);
if (err)
goto out;
} else {
@@ -1237,7 +1239,8 @@ 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, dchild, exp-ex_path.mnt,
+iap-ia_mode);
break;
case S_IFCHR:
case S_IFBLK:
@@ -1256,7 +1259,7 @@ nfsd_create(struct svc_rqst *rqstp, stru
if (host_err  0)
goto out_nfserr;
 
-   if (EX_ISSYNC(fhp-fh_export)) {
+   if (EX_ISSYNC(exp)) {
err = nfserrno(nfsd_sync_dir(dentry));
write_inode_now(dchild-d_inode, 1);
}
--- a/fs/unionfs/copyup.c
+++ b/fs/unionfs/copyup.c
@@ -165,6 +165,7 @@ out:
  */
 static int __copyup_ndentry(struct dentry *old_lower_dentry,
struct dentry *new_lower_dentry,
+   struct vfsmount *new_lower_mnt,
struct dentry *new_lower_parent_dentry,
char *symbuf)
 {
@@ -175,6 +176,7 @@ static int __copyup_ndentry(struct dentr
if (S_ISDIR(old_mode)) {
args.mkdir.parent = new_lower_parent_dentry-d_inode;
args.mkdir.dentry = new_lower_dentry;
+   args.mkdir.mnt = new_lower_mnt;
args.mkdir.mode = old_mode;
 
run_sioq(__unionfs_mkdir, args);

[AppArmor 06/47] Pass struct vfsmount to the inode_mkdir LSM hook

2007-12-20 Thread John
This is needed for computing pathnames in the AppArmor LSM.

Signed-off-by: Tony Jones [EMAIL PROTECTED]
Signed-off-by: Andreas Gruenbacher [EMAIL PROTECTED]
Signed-off-by: John Johansen [EMAIL PROTECTED]

---
 fs/namei.c   |2 +-
 include/linux/security.h |8 ++--
 security/dummy.c |2 +-
 security/security.c  |5 +++--
 security/selinux/hooks.c |3 ++-
 5 files changed, 13 insertions(+), 7 deletions(-)

--- a/fs/namei.c
+++ b/fs/namei.c
@@ -2119,7 +2119,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, dentry, mnt, mode);
if (error)
return error;
 
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -339,6 +339,7 @@ struct request_sock;
  * associated with inode strcture @dir. 
  * @dir containst the inode structure of parent of the directory to be 
created.
  * @dentry contains the dentry structure of new directory.
+ * @mnt is the vfsmount corresponding to @dentry (may be NULL).
  * @mode contains the mode of new directory.
  * Return 0 if permission is granted.
  * @inode_rmdir:
@@ -1281,7 +1282,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 dentry *dentry,
+   struct vfsmount *mnt, 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);
@@ -1546,7 +1548,8 @@ int security_inode_link(struct dentry *o
 int security_inode_unlink(struct inode *dir, struct dentry *dentry);
 int security_inode_symlink(struct inode *dir, struct dentry *dentry,
const char *old_name);
-int security_inode_mkdir(struct inode *dir, struct dentry *dentry, int mode);
+int security_inode_mkdir(struct inode *dir, struct dentry *dentry,
+struct vfsmount *mnt, int mode);
 int security_inode_rmdir(struct inode *dir, struct dentry *dentry);
 int security_inode_mknod(struct inode *dir, struct dentry *dentry, int mode, 
dev_t dev);
 int security_inode_rename(struct inode *old_dir, struct dentry *old_dentry,
@@ -1880,6 +1883,7 @@ static inline int security_inode_symlink
 
 static inline int security_inode_mkdir (struct inode *dir,
struct dentry *dentry,
+   struct vfsmount *mnt,
int mode)
 {
return 0;
--- a/security/dummy.c
+++ b/security/dummy.c
@@ -313,7 +313,7 @@ static int dummy_inode_symlink (struct i
 }
 
 static int dummy_inode_mkdir (struct inode *inode, struct dentry *dentry,
- int mask)
+ struct vfsmount *mnt, int mask)
 {
return 0;
 }
--- a/security/security.c
+++ b/security/security.c
@@ -379,11 +379,12 @@ int security_inode_symlink(struct inode 
return security_ops-inode_symlink(dir, dentry, old_name);
 }
 
-int security_inode_mkdir(struct inode *dir, struct dentry *dentry, int mode)
+int security_inode_mkdir(struct inode *dir, struct dentry *dentry,
+struct vfsmount *mnt, int mode)
 {
if (unlikely(IS_PRIVATE(dir)))
return 0;
-   return security_ops-inode_mkdir(dir, dentry, mode);
+   return security_ops-inode_mkdir(dir, dentry, mnt, mode);
 }
 
 int security_inode_rmdir(struct inode *dir, struct dentry *dentry)
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -2442,7 +2442,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 dentry *dentry,
+  struct vfsmount *mnt, int mask)
 {
return may_create(dir, dentry, SECCLASS_DIR);
 }

-- 

-
To unsubscribe from this list: send the line unsubscribe 
linux-security-module in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[AppArmor 07/47] Add a struct vfsmount parameter to vfs_mknod()

2007-12-20 Thread John
The vfsmount will be passed down to the LSM hook so that LSMs can compute
pathnames.

Signed-off-by: Tony Jones [EMAIL PROTECTED]
Signed-off-by: Andreas Gruenbacher [EMAIL PROTECTED]
Signed-off-by: John Johansen [EMAIL PROTECTED]

---
 fs/ecryptfs/inode.c |5 -
 fs/namei.c  |   10 ++
 fs/nfsd/vfs.c   |3 ++-
 fs/unionfs/copyup.c |1 +
 fs/unionfs/inode.c  |3 ++-
 fs/unionfs/sioq.c   |2 +-
 fs/unionfs/sioq.h   |1 +
 include/linux/fs.h  |2 +-
 net/unix/af_unix.c  |3 ++-
 9 files changed, 20 insertions(+), 10 deletions(-)

--- a/fs/ecryptfs/inode.c
+++ b/fs/ecryptfs/inode.c
@@ -550,11 +550,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_dentry, lower_mnt, mode,
+  dev);
if (rc || !lower_dentry-d_inode)
goto out;
rc = ecryptfs_interpose(lower_dentry, dentry, dir-i_sb, 0);
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -2005,7 +2005,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 dentry *dentry, struct vfsmount *mnt,
+ int mode, dev_t dev)
 {
int error = may_create(dir, dentry, NULL);
 
@@ -2082,12 +2083,13 @@ asmlinkage long sys_mknodat(int dfd, con
mode, nd);
break;
case S_IFCHR: case S_IFBLK:
-   error = vfs_mknod(nd.path.dentry-d_inode, dentry, mode,
-   new_decode_dev(dev));
+   error = vfs_mknod(nd.path.dentry-d_inode, dentry,
+ nd.path.mnt, mode,
+ new_decode_dev(dev));
break;
case S_IFIFO: case S_IFSOCK:
error = vfs_mknod(nd.path.dentry-d_inode, dentry,
-   mode, 0);
+ nd.path.mnt, mode, 0);
break;
}
mnt_drop_write(nd.path.mnt);
--- a/fs/nfsd/vfs.c
+++ b/fs/nfsd/vfs.c
@@ -1249,7 +1249,8 @@ nfsd_create(struct svc_rqst *rqstp, stru
host_err = mnt_want_write(fhp-fh_export-ex_path.mnt);
if (host_err)
break;
-   host_err = vfs_mknod(dirp, dchild, iap-ia_mode, rdev);
+   host_err = vfs_mknod(dirp, dchild, exp-ex_path.mnt,
+iap-ia_mode, rdev);
mnt_drop_write(fhp-fh_export-ex_path.mnt);
break;
default:
--- a/fs/unionfs/copyup.c
+++ b/fs/unionfs/copyup.c
@@ -193,6 +193,7 @@ static int __copyup_ndentry(struct dentr
   S_ISFIFO(old_mode) || S_ISSOCK(old_mode)) {
args.mknod.parent = new_lower_parent_dentry-d_inode;
args.mknod.dentry = new_lower_dentry;
+   args.mknod.mnt = new_lower_mnt;
args.mknod.mode = old_mode;
args.mknod.dev = old_lower_dentry-d_inode-i_rdev;
 
--- a/fs/unionfs/inode.c
+++ b/fs/unionfs/inode.c
@@ -760,6 +760,7 @@ static int unionfs_mknod(struct inode *d
continue;
 
lower_dentry = unionfs_lower_dentry_idx(dentry, bindex);
+   lower_mnt = unionfs_lower_mnt_idx(dentry, bindex);
if (!lower_dentry) {
lower_dentry = create_parents(dir, dentry,
  dentry-d_name.name,
@@ -779,7 +780,7 @@ static int unionfs_mknod(struct inode *d
}
 
err = vfs_mknod(lower_parent_dentry-d_inode,
-   lower_dentry, mode, dev);
+   lower_dentry, lower_mnt, mode, dev);
 
if (err) {
unlock_dir(lower_parent_dentry);
--- a/fs/unionfs/sioq.c
+++ b/fs/unionfs/sioq.c
@@ -78,7 +78,7 @@ void __unionfs_mknod(struct work_struct 
struct sioq_args *args = container_of(work, struct sioq_args, work);
struct mknod_args *m = args-mknod;
 
-   args-err = vfs_mknod(m-parent, m-dentry, m-mode, m-dev);
+   args-err = vfs_mknod(m-parent, m-dentry, m-mnt, m-mode, m-dev);
complete(args-comp);
 }
 
--- a/fs/unionfs/sioq.h
+++ b/fs/unionfs/sioq.h
@@ -42,6 +42,7 @@ struct mkdir_args {
 struct mknod_args {
struct inode *parent;
struct dentry *dentry;
+   struct vfsmount *mnt;
umode_t mode;

[AppArmor 08/47] Pass struct vfsmount to the inode_mknod LSM hook

2007-12-20 Thread John
This is needed for computing pathnames in the AppArmor LSM.

Signed-off-by: Tony Jones [EMAIL PROTECTED]
Signed-off-by: Andreas Gruenbacher [EMAIL PROTECTED]
Signed-off-by: John Johansen [EMAIL PROTECTED]

---
 fs/namei.c   |2 +-
 include/linux/security.h |7 +--
 security/dummy.c |2 +-
 security/security.c  |5 +++--
 security/selinux/hooks.c |5 +++--
 5 files changed, 13 insertions(+), 8 deletions(-)

--- a/fs/namei.c
+++ b/fs/namei.c
@@ -2019,7 +2019,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, dentry, mnt, mode, dev);
if (error)
return error;
 
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -354,6 +354,7 @@ struct request_sock;
  * and not this hook.
  * @dir contains the inode structure of parent of the new file.
  * @dentry contains the dentry structure of the new file.
+ * @mnt is the vfsmount corresponding to @dentry (may be NULL).
  * @mode contains the mode of the new file.
  * @dev contains the device number.
  * Return 0 if permission is granted.
@@ -1286,7 +1287,7 @@ struct security_operations {
struct vfsmount *mnt, 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);
+   struct vfsmount *mnt, 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);
@@ -1551,7 +1552,8 @@ int security_inode_symlink(struct inode 
 int security_inode_mkdir(struct inode *dir, struct dentry *dentry,
 struct vfsmount *mnt, int mode);
 int security_inode_rmdir(struct inode *dir, struct dentry *dentry);
-int security_inode_mknod(struct inode *dir, struct dentry *dentry, int mode, 
dev_t dev);
+int security_inode_mknod(struct inode *dir, struct dentry *dentry,
+struct vfsmount *mnt, int mode, dev_t dev);
 int security_inode_rename(struct inode *old_dir, struct dentry *old_dentry,
   struct inode *new_dir, struct dentry *new_dentry);
 int security_inode_readlink(struct dentry *dentry);
@@ -1897,6 +1899,7 @@ static inline int security_inode_rmdir (
 
 static inline int security_inode_mknod (struct inode *dir,
struct dentry *dentry,
+   struct vfsmount *mnt,
int mode, dev_t dev)
 {
return 0;
--- a/security/dummy.c
+++ b/security/dummy.c
@@ -324,7 +324,7 @@ static int dummy_inode_rmdir (struct ino
 }
 
 static int dummy_inode_mknod (struct inode *inode, struct dentry *dentry,
- int mode, dev_t dev)
+ struct vfsmount *mnt, int mode, dev_t dev)
 {
return 0;
 }
--- a/security/security.c
+++ b/security/security.c
@@ -394,11 +394,12 @@ int security_inode_rmdir(struct inode *d
return security_ops-inode_rmdir(dir, dentry);
 }
 
-int security_inode_mknod(struct inode *dir, struct dentry *dentry, int mode, 
dev_t dev)
+int security_inode_mknod(struct inode *dir, struct dentry *dentry,
+struct vfsmount *mnt, 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, dentry, mnt, mode, dev);
 }
 
 int security_inode_rename(struct inode *old_dir, struct dentry *old_dentry,
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -2453,11 +2453,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 dentry *dentry,
+  struct vfsmount *mnt, int mode, dev_t dev)
 {
int rc;
 
-   rc = secondary_ops-inode_mknod(dir, dentry, mode, dev);
+   rc = secondary_ops-inode_mknod(dir, dentry, mnt, mode, dev);
if (rc)
return rc;
 

-- 

-
To unsubscribe from this list: send the line unsubscribe 
linux-security-module in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[AppArmor 09/47] Add a struct vfsmount parameter to vfs_symlink()

2007-12-20 Thread John
The vfsmount will be passed down to the LSM hook so that LSMs can compute
pathnames.

Signed-off-by: Tony Jones [EMAIL PROTECTED]
Signed-off-by: Andreas Gruenbacher [EMAIL PROTECTED]
Signed-off-by: John Johansen [EMAIL PROTECTED]

---
 fs/ecryptfs/inode.c |4 +++-
 fs/namei.c  |6 --
 fs/nfsd/vfs.c   |   13 +
 fs/unionfs/copyup.c |1 +
 fs/unionfs/inode.c  |4 +++-
 fs/unionfs/sioq.c   |3 ++-
 fs/unionfs/sioq.h   |1 +
 include/linux/fs.h  |2 +-
 8 files changed, 24 insertions(+), 10 deletions(-)

--- a/fs/ecryptfs/inode.c
+++ b/fs/ecryptfs/inode.c
@@ -460,6 +460,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;
@@ -468,6 +469,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,
@@ -477,7 +479,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_dentry, lower_mnt,
 encoded_symname, mode);
kfree(encoded_symname);
if (rc || !lower_dentry-d_inode)
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -2391,7 +2391,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 dentry *dentry, struct vfsmount *mnt,
+   const char *oldname, int mode)
 {
int error = may_create(dir, dentry, NULL);
 
@@ -2440,7 +2441,8 @@ asmlinkage long sys_symlinkat(const char
error = mnt_want_write(nd.path.mnt);
if (error)
goto out_dput;
-   error = vfs_symlink(nd.path.dentry-d_inode, dentry, from, S_IALLUGO);
+   error = vfs_symlink(nd.path.dentry-d_inode, dentry, nd.path.mnt, from,
+   S_IALLUGO);
mnt_drop_write(nd.path.mnt);
 out_dput:
dput(dentry);
--- a/fs/nfsd/vfs.c
+++ b/fs/nfsd/vfs.c
@@ -1495,6 +1495,7 @@ nfsd_symlink(struct svc_rqst *rqstp, str
struct iattr *iap)
 {
struct dentry   *dentry, *dnew;
+   struct svc_export *exp;
__be32  err, cerr;
int host_err;
umode_t mode;
@@ -1521,6 +1522,7 @@ nfsd_symlink(struct svc_rqst *rqstp, str
if (iap  (iap-ia_valid  ATTR_MODE))
mode = iap-ia_mode  S_IALLUGO;
 
+   exp = fhp-fh_export;
if (unlikely(path[plen] != 0)) {
char *path_alloced = kmalloc(plen+1, GFP_KERNEL);
if (path_alloced == NULL)
@@ -1528,20 +1530,23 @@ 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, dnew,
+  exp-ex_path.mnt, path_alloced,
+  mode);
kfree(path_alloced);
}
} else
-   host_err = vfs_symlink(dentry-d_inode, dnew, path, mode);
+   host_err = vfs_symlink(dentry-d_inode, dnew, exp-ex_path.mnt,
+  path, mode);
 
if (!host_err) {
-   if (EX_ISSYNC(fhp-fh_export))
+   if (EX_ISSYNC(exp))
host_err = nfsd_sync_dir(dentry);
}
err = nfserrno(host_err);
fh_unlock(fhp);
 
-   cerr = fh_compose(resfhp, fhp-fh_export, dnew, fhp);
+   cerr = fh_compose(resfhp, exp, dnew, fhp);
dput(dnew);
if (err==0) err = cerr;
 out:
--- a/fs/unionfs/copyup.c
+++ b/fs/unionfs/copyup.c
@@ -184,6 +184,7 @@ static int __copyup_ndentry(struct dentr
} else if (S_ISLNK(old_mode)) {
args.symlink.parent = new_lower_parent_dentry-d_inode;
args.symlink.dentry = new_lower_dentry;
+   args.symlink.mnt = new_lower_mnt;
args.symlink.symbuf = symbuf;
args.symlink.mode = old_mode;
 
--- a/fs/unionfs/inode.c
+++ b/fs/unionfs/inode.c
@@ -452,6 +452,7 @@ static int unionfs_symlink(struct inode 
 */
for (bindex = bstart; bindex = 0; bindex--) {
lower_dentry = unionfs_lower_dentry_idx(dentry, bindex);
+   

[AppArmor 11/47] Pass struct vfsmount to the inode_readlink LSM hook

2007-12-20 Thread John
This is needed for computing pathnames in the AppArmor LSM.

Signed-off-by: Tony Jones [EMAIL PROTECTED]
Signed-off-by: Andreas Gruenbacher [EMAIL PROTECTED]
Signed-off-by: John Johansen [EMAIL PROTECTED]

---
 fs/stat.c|3 ++-
 include/linux/security.h |8 +---
 security/dummy.c |2 +-
 security/security.c  |4 ++--
 security/selinux/hooks.c |2 +-
 5 files changed, 11 insertions(+), 8 deletions(-)

--- a/fs/stat.c
+++ b/fs/stat.c
@@ -306,7 +306,8 @@ asmlinkage long sys_readlinkat(int dfd, 
 
error = -EINVAL;
if (inode-i_op  inode-i_op-readlink) {
-   error = security_inode_readlink(nd.path.dentry);
+   error = security_inode_readlink(nd.path.dentry,
+   nd.path.mnt);
if (!error) {
touch_atime(nd.path.mnt, nd.path.dentry);
error = inode-i_op-readlink(nd.path.dentry,
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -369,6 +369,7 @@ struct request_sock;
  * @inode_readlink:
  * Check the permission to read the symbolic link.
  * @dentry contains the dentry structure for the file link.
+ * @mnt is the vfsmount corresponding to @dentry (may be NULL).
  * Return 0 if permission is granted.
  * @inode_follow_link:
  * Check permission to follow a symbolic link when looking up a pathname.
@@ -1291,7 +1292,7 @@ struct security_operations {
struct vfsmount *mnt, 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 dentry *dentry, struct vfsmount *mnt);
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 vfsmount *mnt,
@@ -1557,7 +1558,7 @@ int security_inode_mknod(struct inode *d
 struct vfsmount *mnt, int mode, dev_t dev);
 int security_inode_rename(struct inode *old_dir, struct dentry *old_dentry,
   struct inode *new_dir, struct dentry *new_dentry);
-int security_inode_readlink(struct dentry *dentry);
+int security_inode_readlink(struct dentry *dentry, struct vfsmount *mnt);
 int security_inode_follow_link(struct dentry *dentry, struct nameidata *nd);
 int security_inode_permission(struct inode *inode, int mask, struct nameidata 
*nd);
 int security_inode_setattr(struct dentry *dentry, struct vfsmount *mnt,
@@ -1915,7 +1916,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 dentry *dentry,
+  struct vfsmount *mnt)
 {
return 0;
 }
--- a/security/dummy.c
+++ b/security/dummy.c
@@ -337,7 +337,7 @@ static int dummy_inode_rename (struct in
return 0;
 }
 
-static int dummy_inode_readlink (struct dentry *dentry)
+static int dummy_inode_readlink (struct dentry *dentry, struct vfsmount *mnt)
 {
return 0;
 }
--- a/security/security.c
+++ b/security/security.c
@@ -412,11 +412,11 @@ int security_inode_rename(struct inode *
   new_dir, new_dentry);
 }
 
-int security_inode_readlink(struct dentry *dentry)
+int security_inode_readlink(struct dentry *dentry, struct vfsmount *mnt)
 {
if (unlikely(IS_PRIVATE(dentry-d_inode)))
return 0;
-   return security_ops-inode_readlink(dentry);
+   return security_ops-inode_readlink(dentry, mnt);
 }
 
 int security_inode_follow_link(struct dentry *dentry, struct nameidata *nd)
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -2472,7 +2472,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 dentry *dentry, struct vfsmount *mnt)
 {
return dentry_has_perm(current, NULL, dentry, FILE__READ);
 }

-- 

-
To unsubscribe from this list: send the line unsubscribe 
linux-security-module in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[AppArmor 12/47] Add struct vfsmount parameters to vfs_link()

2007-12-20 Thread John
The vfsmount will be passed down to the LSM hook so that LSMs can compute
pathnames.

Signed-off-by: Tony Jones [EMAIL PROTECTED]
Signed-off-by: Andreas Gruenbacher [EMAIL PROTECTED]
Signed-off-by: John Johansen [EMAIL PROTECTED]

---
 fs/ecryptfs/inode.c |9 +++--
 fs/namei.c  |5 +++--
 fs/nfsd/vfs.c   |3 ++-
 fs/unionfs/inode.c  |   14 +++---
 include/linux/fs.h  |2 +-
 5 files changed, 24 insertions(+), 9 deletions(-)

--- a/fs/ecryptfs/inode.c
+++ b/fs/ecryptfs/inode.c
@@ -401,19 +401,24 @@ 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,
- lower_new_dentry);
+   rc = vfs_link(lower_old_dentry, lower_old_mnt,
+ lower_dir_dentry-d_inode, lower_new_dentry,
+ lower_new_mnt);
if (rc || !lower_new_dentry-d_inode)
goto out_lock;
rc = ecryptfs_interpose(lower_new_dentry, new_dentry, dir-i_sb, 0);
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -2461,7 +2461,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 dentry *old_dentry, struct vfsmount *old_mnt, struct inode 
*dir, struct dentry *new_dentry, struct vfsmount *new_mnt)
 {
struct inode *inode = old_dentry-d_inode;
int error;
@@ -2542,7 +2542,8 @@ asmlinkage long sys_linkat(int olddfd, c
error = mnt_want_write(nd.path.mnt);
if (error)
goto out_dput;
-   error = vfs_link(old_nd.path.dentry, nd.path.dentry-d_inode, 
new_dentry);
+   error = vfs_link(old_nd.path.dentry, old_nd.path.mnt,
+nd.path.dentry-d_inode, new_dentry, nd.path.mnt);
mnt_drop_write(nd.path.mnt);
 out_dput:
dput(new_dentry);
--- a/fs/nfsd/vfs.c
+++ b/fs/nfsd/vfs.c
@@ -1596,7 +1596,8 @@ 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(dold, tfhp-fh_export-ex_path.mnt, dirp,
+   dnew, ffhp-fh_export-ex_path.mnt);
if (!host_err) {
if (EX_ISSYNC(ffhp-fh_export)) {
err = nfserrno(nfsd_sync_dir(ddir));
--- a/fs/unionfs/inode.c
+++ b/fs/unionfs/inode.c
@@ -222,6 +222,7 @@ static int unionfs_link(struct dentry *o
 {
int err = 0;
struct dentry *lower_old_dentry = NULL;
+   struct vfsmount *lower_old_mnt = NULL;
struct dentry *lower_new_dentry = NULL;
struct vfsmount *lower_new_mnt = NULL;
struct dentry *lower_dir_dentry = NULL;
@@ -293,14 +294,17 @@ static int unionfs_link(struct dentry *o
goto out;
}
lower_new_dentry = unionfs_lower_dentry(new_dentry);
+   lower_new_mnt = unionfs_lower_mnt(new_dentry);
lower_old_dentry = unionfs_lower_dentry(old_dentry);
+   lower_old_mnt = unionfs_lower_mnt(old_dentry);
 
BUG_ON(dbstart(old_dentry) != dbstart(new_dentry));
lower_dir_dentry = lock_parent(lower_new_dentry);
err = is_robranch(old_dentry);
if (!err)
-   err = vfs_link(lower_old_dentry, lower_dir_dentry-d_inode,
-  lower_new_dentry);
+   err = vfs_link(lower_old_dentry, lower_old_mnt,
+  lower_dir_dentry-d_inode,
+  lower_new_dentry, lower_new_mnt);
unlock_dir(lower_dir_dentry);
 
 docopyup:
@@ -321,12 +325,16 @@ docopyup:
   bindex, lower_new_mnt);
lower_old_dentry =
unionfs_lower_dentry(old_dentry);
+   lower_old_mnt =
+   unionfs_lower_mnt(old_dentry);
lower_dir_dentry =
lock_parent(lower_new_dentry);
/* do vfs_link */
err = vfs_link(lower_old_dentry,
+ 

[AppArmor 13/47] Pass the struct vfsmounts to the inode_link LSM hook

2007-12-20 Thread John
This is needed for computing pathnames in the AppArmor LSM.

Signed-off-by: Tony Jones [EMAIL PROTECTED]
Signed-off-by: Andreas Gruenbacher [EMAIL PROTECTED]
Signed-off-by: John Johansen [EMAIL PROTECTED]

---
 fs/namei.c   |3 ++-
 include/linux/security.h |   16 +++-
 security/dummy.c |6 --
 security/security.c  |8 +---
 security/selinux/hooks.c |9 +++--
 5 files changed, 29 insertions(+), 13 deletions(-)

--- a/fs/namei.c
+++ b/fs/namei.c
@@ -2486,7 +2486,8 @@ int vfs_link(struct dentry *old_dentry, 
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_dentry, old_mnt, dir, new_dentry,
+   new_mnt);
if (error)
return error;
 
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -320,8 +320,10 @@ struct request_sock;
  * @inode_link:
  * Check permission before creating a new hard link to a file.
  * @old_dentry contains the dentry structure for an existing link to the 
file.
+ * @old_mnt is the vfsmount corresponding to @old_dentry (may be NULL).
  * @dir contains the inode structure of the parent directory of the new 
link.
  * @new_dentry contains the dentry structure for the new link.
+ * @new_mnt is the vfsmount corresponding to @new_dentry (may be NULL).
  * Return 0 if permission is granted.
  * @inode_unlink:
  * Check the permission to remove a hard link to a file. 
@@ -1280,8 +1282,9 @@ struct security_operations {
char **name, void **value, size_t *len);
int (*inode_create) (struct inode *dir, struct dentry *dentry,
 struct vfsmount *mnt, int mode);
-   int (*inode_link) (struct dentry *old_dentry,
-  struct inode *dir, struct dentry *new_dentry);
+   int (*inode_link) (struct dentry *old_dentry, struct vfsmount *old_mnt,
+  struct inode *dir, struct dentry *new_dentry,
+  struct vfsmount *new_mnt);
int (*inode_unlink) (struct inode *dir, struct dentry *dentry);
int (*inode_symlink) (struct inode *dir, struct dentry *dentry,
  struct vfsmount *mnt, const char *old_name);
@@ -1546,8 +1549,9 @@ int security_inode_init_security(struct 
  char **name, void **value, size_t *len);
 int security_inode_create(struct inode *dir, struct dentry *dentry,
  struct vfsmount *mnt, int mode);
-int security_inode_link(struct dentry *old_dentry, struct inode *dir,
-struct dentry *new_dentry);
+int security_inode_link(struct dentry *old_dentry, struct vfsmount *old_mnt,
+   struct inode *dir, struct dentry *new_dentry,
+   struct vfsmount *new_mnt);
 int security_inode_unlink(struct inode *dir, struct dentry *dentry);
 int security_inode_symlink(struct inode *dir, struct dentry *dentry,
   struct vfsmount *mnt, const char *old_name);
@@ -1866,8 +1870,10 @@ static inline int security_inode_create 
 }
 
 static inline int security_inode_link (struct dentry *old_dentry,
+  struct vfsmount *old_mnt,
   struct inode *dir,
-  struct dentry *new_dentry)
+  struct dentry *new_dentry,
+  struct vfsmount *new_mnt)
 {
return 0;
 }
--- a/security/dummy.c
+++ b/security/dummy.c
@@ -295,8 +295,10 @@ static int dummy_inode_create (struct in
return 0;
 }
 
-static int dummy_inode_link (struct dentry *old_dentry, struct inode *inode,
-struct dentry *new_dentry)
+static int dummy_inode_link (struct dentry *old_dentry,
+struct vfsmount *old_mnt, struct inode *inode,
+struct dentry *new_dentry,
+struct vfsmount *new_mnt)
 {
return 0;
 }
--- a/security/security.c
+++ b/security/security.c
@@ -356,12 +356,14 @@ int security_inode_create(struct inode *
return security_ops-inode_create(dir, dentry, mnt, mode);
 }
 
-int security_inode_link(struct dentry *old_dentry, struct inode *dir,
-struct dentry *new_dentry)
+int security_inode_link(struct dentry *old_dentry, struct vfsmount *old_mnt,
+   struct inode *dir, struct dentry *new_dentry,
+   struct vfsmount *new_mnt)
 {
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_dentry, old_mnt, dir,
+

[AppArmor 17/47] Add a struct vfsmount parameter to vfs_unlink()

2007-12-20 Thread John
The vfsmount will be passed down to the LSM hook so that LSMs can compute
pathnames.

Signed-off-by: Tony Jones [EMAIL PROTECTED]
Signed-off-by: Andreas Gruenbacher [EMAIL PROTECTED]
Signed-off-by: John Johansen [EMAIL PROTECTED]

---
 fs/ecryptfs/inode.c |3 ++-
 fs/namei.c  |5 +++--
 fs/nfsd/nfs4recover.c   |2 +-
 fs/nfsd/vfs.c   |2 +-
 fs/unionfs/commonfops.c |4 +++-
 fs/unionfs/copyup.c |3 ++-
 fs/unionfs/dirhelper.c  |5 -
 fs/unionfs/inode.c  |   22 --
 fs/unionfs/rename.c |8 ++--
 fs/unionfs/sioq.c   |2 +-
 fs/unionfs/sioq.h   |1 +
 fs/unionfs/unlink.c |5 -
 include/linux/fs.h  |2 +-
 ipc/mqueue.c|2 +-
 14 files changed, 46 insertions(+), 20 deletions(-)

--- a/fs/ecryptfs/inode.c
+++ b/fs/ecryptfs/inode.c
@@ -443,10 +443,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_dentry, lower_mnt);
if (rc) {
printk(KERN_ERR Error in vfs_unlink; rc = [%d]\n, rc);
goto out_unlock;
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -2288,7 +2288,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 dentry *dentry, struct vfsmount *mnt)
 {
int error = may_delete(dir, dentry, 0);
 
@@ -2356,7 +2356,8 @@ static long do_unlinkat(int dfd, const c
error = mnt_want_write(nd.path.mnt);
if (error)
goto exit2;
-   error = vfs_unlink(nd.path.dentry-d_inode, dentry);
+   error = vfs_unlink(nd.path.dentry-d_inode, dentry,
+  nd.path.mnt);
mnt_drop_write(nd.path.mnt);
exit2:
dput(dentry);
--- a/fs/nfsd/nfs4recover.c
+++ b/fs/nfsd/nfs4recover.c
@@ -264,7 +264,7 @@ nfsd4_remove_clid_file(struct dentry *di
return -EINVAL;
}
mutex_lock_nested(dir-d_inode-i_mutex, I_MUTEX_PARENT);
-   status = vfs_unlink(dir-d_inode, dentry);
+   status = vfs_unlink(dir-d_inode, dentry, rec_dir.path.mnt);
mutex_unlock(dir-d_inode-i_mutex);
return status;
 }
--- a/fs/nfsd/vfs.c
+++ b/fs/nfsd/vfs.c
@@ -1772,7 +1772,7 @@ nfsd_unlink(struct svc_rqst *rqstp, stru
host_err = -EPERM;
} else
 #endif
-   host_err = vfs_unlink(dirp, rdentry);
+   host_err = vfs_unlink(dirp, rdentry, exp-ex_path.mnt);
} else { /* It's RMDIR */
host_err = vfs_rmdir(dirp, rdentry, exp-ex_path.mnt);
}
--- a/fs/unionfs/commonfops.c
+++ b/fs/unionfs/commonfops.c
@@ -34,6 +34,7 @@ static int copyup_deleted_file(struct fi
int err;
struct dentry *tmp_dentry = NULL;
struct dentry *lower_dentry;
+   struct vfsmount *lower_mnt;
struct dentry *lower_dir_dentry = NULL;
 
lower_dentry = unionfs_lower_dentry_idx(dentry, bstart);
@@ -82,13 +83,14 @@ retry:
 
/* bring it to the same state as an unlinked file */
lower_dentry = unionfs_lower_dentry_idx(dentry, dbstart(dentry));
+   lower_mnt = unionfs_lower_mnt_idx(dentry, dbstart(dentry));
if (!unionfs_lower_inode_idx(dentry-d_inode, bindex)) {
atomic_inc(lower_dentry-d_inode-i_count);
unionfs_set_lower_inode_idx(dentry-d_inode, bindex,
lower_dentry-d_inode);
}
lower_dir_dentry = lock_parent(lower_dentry);
-   err = vfs_unlink(lower_dir_dentry-d_inode, lower_dentry);
+   err = vfs_unlink(lower_dir_dentry-d_inode, lower_dentry, lower_mnt);
unlock_dir(lower_dir_dentry);
 
 out:
--- a/fs/unionfs/copyup.c
+++ b/fs/unionfs/copyup.c
@@ -491,7 +491,8 @@ out_unlink:
 * quota, or something else happened so let's unlink; we don't
 * really care about the return value of vfs_unlink
 */
-   vfs_unlink(new_lower_parent_dentry-d_inode, new_lower_dentry);
+   vfs_unlink(new_lower_parent_dentry-d_inode, new_lower_dentry,
+  new_lower_mnt);
 
if (copyup_file) {
/* need to close the file */
--- a/fs/unionfs/dirhelper.c
+++ b/fs/unionfs/dirhelper.c
@@ -29,6 +29,7 @@ int do_delete_whiteouts(struct dentry *d
int err = 0;
struct dentry *lower_dir_dentry = NULL;
struct dentry *lower_dentry;
+   struct vfsmount *lower_mnt;
char *name = NULL, *p;
struct inode *lower_dir;
int i;
@@ 

[AppArmor 18/47] Pass struct vfsmount to the inode_unlink LSM hook

2007-12-20 Thread John
This is needed for computing pathnames in the AppArmor LSM.

Signed-off-by: Tony Jones [EMAIL PROTECTED]
Signed-off-by: Andreas Gruenbacher [EMAIL PROTECTED]
Signed-off-by: John Johansen [EMAIL PROTECTED]

---
 fs/namei.c   |2 +-
 include/linux/security.h |   10 +++---
 security/dummy.c |3 ++-
 security/security.c  |5 +++--
 security/selinux/hooks.c |5 +++--
 5 files changed, 16 insertions(+), 9 deletions(-)

--- a/fs/namei.c
+++ b/fs/namei.c
@@ -2304,7 +2304,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, dentry, mnt);
if (!error)
error = dir-i_op-unlink(dir, dentry);
}
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -329,6 +329,7 @@ struct request_sock;
  * Check the permission to remove a hard link to a file. 
  * @dir contains the inode structure of parent directory of the file.
  * @dentry contains the dentry structure for file to be unlinked.
+ * @mnt is the vfsmount corresponding to @dentry (may be NULL).
  * Return 0 if permission is granted.
  * @inode_symlink:
  * Check the permission to create a symbolic link to a file.
@@ -1286,7 +1287,8 @@ struct security_operations {
int (*inode_link) (struct dentry *old_dentry, struct vfsmount *old_mnt,
   struct inode *dir, struct dentry *new_dentry,
   struct vfsmount *new_mnt);
-   int (*inode_unlink) (struct inode *dir, struct dentry *dentry);
+   int (*inode_unlink) (struct inode *dir, struct dentry *dentry,
+struct vfsmount *mnt);
int (*inode_symlink) (struct inode *dir, struct dentry *dentry,
  struct vfsmount *mnt, const char *old_name);
int (*inode_mkdir) (struct inode *dir, struct dentry *dentry,
@@ -1554,7 +1556,8 @@ int security_inode_create(struct inode *
 int security_inode_link(struct dentry *old_dentry, struct vfsmount *old_mnt,
struct inode *dir, struct dentry *new_dentry,
struct vfsmount *new_mnt);
-int security_inode_unlink(struct inode *dir, struct dentry *dentry);
+int security_inode_unlink(struct inode *dir, struct dentry *dentry,
+ struct vfsmount *mnt);
 int security_inode_symlink(struct inode *dir, struct dentry *dentry,
   struct vfsmount *mnt, const char *old_name);
 int security_inode_mkdir(struct inode *dir, struct dentry *dentry,
@@ -1882,7 +1885,8 @@ static inline int security_inode_link (s
 }
 
 static inline int security_inode_unlink (struct inode *dir,
-struct dentry *dentry)
+struct dentry *dentry,
+struct vfsmount *mnt)
 {
return 0;
 }
--- a/security/dummy.c
+++ b/security/dummy.c
@@ -303,7 +303,8 @@ static int dummy_inode_link (struct dent
return 0;
 }
 
-static int dummy_inode_unlink (struct inode *inode, struct dentry *dentry)
+static int dummy_inode_unlink (struct inode *inode, struct dentry *dentry,
+  struct vfsmount *mnt)
 {
return 0;
 }
--- a/security/security.c
+++ b/security/security.c
@@ -366,11 +366,12 @@ int security_inode_link(struct dentry *o
 new_dentry, new_mnt);
 }
 
-int security_inode_unlink(struct inode *dir, struct dentry *dentry)
+int security_inode_unlink(struct inode *dir, struct dentry *dentry,
+ struct vfsmount *mnt)
 {
if (unlikely(IS_PRIVATE(dentry-d_inode)))
return 0;
-   return security_ops-inode_unlink(dir, dentry);
+   return security_ops-inode_unlink(dir, dentry, mnt);
 }
 
 int security_inode_symlink(struct inode *dir, struct dentry *dentry,
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -2432,11 +2432,12 @@ static int selinux_inode_link(struct den
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 dentry *dentry,
+   struct vfsmount *mnt)
 {
int rc;
 
-   rc = secondary_ops-inode_unlink(dir, dentry);
+   rc = secondary_ops-inode_unlink(dir, dentry, mnt);
if (rc)
return rc;
return may_link(dir, dentry, MAY_UNLINK);

-- 

-
To unsubscribe from this list: send the line unsubscribe 
linux-security-module in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[AppArmor 19/47] Add struct vfsmount parameters to vfs_rename()

2007-12-20 Thread John
The vfsmount will be passed down to the LSM hook so that LSMs can compute
pathnames.

Signed-off-by: Tony Jones [EMAIL PROTECTED]
Signed-off-by: Andreas Gruenbacher [EMAIL PROTECTED]
Signed-off-by: John Johansen [EMAIL PROTECTED]

---
 fs/ecryptfs/inode.c |7 ++-
 fs/namei.c  |   19 ---
 fs/nfsd/vfs.c   |3 ++-
 fs/unionfs/rename.c |6 +-
 include/linux/fs.h  |2 +-
 5 files changed, 26 insertions(+), 11 deletions(-)

--- a/fs/ecryptfs/inode.c
+++ b/fs/ecryptfs/inode.c
@@ -588,19 +588,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);
+   lower_old_mnt, lower_new_dir_dentry-d_inode,
+   lower_new_dentry, lower_new_mnt);
if (rc)
goto out_lock;
fsstack_copy_attr_all(new_dir, lower_new_dir_dentry-d_inode);
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -2600,7 +2600,8 @@ asmlinkage long sys_link(const char __us
  *locking].
  */
 static int vfs_rename_dir(struct inode *old_dir, struct dentry *old_dentry,
- struct inode *new_dir, struct dentry *new_dentry)
+ struct vfsmount *old_mnt, struct inode *new_dir,
+ struct dentry *new_dentry, struct vfsmount *new_mnt)
 {
int error = 0;
struct inode *target;
@@ -2643,7 +2644,8 @@ static int vfs_rename_dir(struct inode *
 }
 
 static int vfs_rename_other(struct inode *old_dir, struct dentry *old_dentry,
-   struct inode *new_dir, struct dentry *new_dentry)
+   struct vfsmount *old_mnt, struct inode *new_dir,
+   struct dentry *new_dentry, struct vfsmount *new_mnt)
 {
struct inode *target;
int error;
@@ -2671,7 +2673,8 @@ static int vfs_rename_other(struct inode
 }
 
 int vfs_rename(struct inode *old_dir, struct dentry *old_dentry,
-  struct inode *new_dir, struct dentry *new_dentry)
+   struct vfsmount *old_mnt, struct inode *new_dir,
+   struct dentry *new_dentry, struct vfsmount *new_mnt)
 {
int error;
int is_dir = S_ISDIR(old_dentry-d_inode-i_mode);
@@ -2700,9 +2703,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_dentry, old_mnt,
+  new_dir, new_dentry, new_mnt);
else
-   error = vfs_rename_other(old_dir,old_dentry,new_dir,new_dentry);
+   error = vfs_rename_other(old_dir, old_dentry, old_mnt,
+new_dir, new_dentry, new_mnt);
if (!error) {
const char *new_name = old_dentry-d_name.name;
fsnotify_move(old_dir, new_dir, old_name, new_name, is_dir,
@@ -2777,8 +2782,8 @@ static int do_rename(int olddfd, const c
error = mnt_want_write(oldnd.path.mnt);
if (error)
goto exit5;
-   error = vfs_rename(old_dir-d_inode, old_dentry,
-  new_dir-d_inode, new_dentry);
+   error = vfs_rename(old_dir-d_inode, old_dentry, oldnd.path.mnt,
+  new_dir-d_inode, new_dentry, newnd.path.mnt);
mnt_drop_write(oldnd.path.mnt);
 exit5:
dput(new_dentry);
--- a/fs/nfsd/vfs.c
+++ b/fs/nfsd/vfs.c
@@ -1697,7 +1697,8 @@ nfsd_rename(struct svc_rqst *rqstp, stru
if (host_err)
goto out_dput_new;
 
-   host_err = vfs_rename(fdir, odentry, tdir, ndentry);
+   host_err = vfs_rename(fdir, odentry, ffhp-fh_export-ex_path.mnt,
+ tdir, ndentry, tfhp-fh_export-ex_path.mnt);
if (!host_err  EX_ISSYNC(tfhp-fh_export)) {
host_err = nfsd_sync_dir(tdentry);
if (!host_err)
--- a/fs/unionfs/rename.c
+++ b/fs/unionfs/rename.c
@@ -24,6 +24,7 @@ static int __unionfs_rename(struct inode
 {
int err = 

[AppArmor 20/47] Pass struct vfsmount to the inode_rename LSM hook

2007-12-20 Thread John
This is needed for computing pathnames in the AppArmor LSM.

Signed-off-by: Tony Jones [EMAIL PROTECTED]
Signed-off-by: Andreas Gruenbacher [EMAIL PROTECTED]
Signed-off-by: John Johansen [EMAIL PROTECTED]

---
 fs/namei.c   |6 --
 include/linux/security.h |   13 ++---
 security/dummy.c |4 +++-
 security/security.c  |7 ---
 security/selinux/hooks.c |8 ++--
 5 files changed, 27 insertions(+), 11 deletions(-)

--- a/fs/namei.c
+++ b/fs/namei.c
@@ -2616,7 +2616,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_dentry, old_mnt,
+ new_dir, new_dentry, new_mnt);
if (error)
return error;
 
@@ -2650,7 +2651,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_dentry, old_mnt,
+ new_dir, new_dentry, new_mnt);
if (error)
return error;
 
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -367,8 +367,10 @@ struct request_sock;
  * Check for permission to rename a file or directory.
  * @old_dir contains the inode structure for parent of the old link.
  * @old_dentry contains the dentry structure of the old link.
+ * @old_mnt is the vfsmount corresponding to @old_dentry (may be NULL).
  * @new_dir contains the inode structure for parent of the new link.
  * @new_dentry contains the dentry structure of the new link.
+ * @new_mnt is the vfsmount corresponding to @new_dentry (may be NULL).
  * Return 0 if permission is granted.
  * @inode_readlink:
  * Check the permission to read the symbolic link.
@@ -1298,7 +1300,9 @@ struct security_operations {
int (*inode_mknod) (struct inode *dir, struct dentry *dentry,
struct vfsmount *mnt, int mode, dev_t dev);
int (*inode_rename) (struct inode *old_dir, struct dentry *old_dentry,
-struct inode *new_dir, struct dentry *new_dentry);
+struct vfsmount *old_mnt,
+struct inode *new_dir, struct dentry *new_dentry,
+struct vfsmount *new_mnt);
int (*inode_readlink) (struct dentry *dentry, struct vfsmount *mnt);
int (*inode_follow_link) (struct dentry *dentry, struct nameidata *nd);
int (*inode_permission) (struct inode *inode, int mask, struct 
nameidata *nd);
@@ -1567,7 +1571,8 @@ int security_inode_rmdir(struct inode *d
 int security_inode_mknod(struct inode *dir, struct dentry *dentry,
 struct vfsmount *mnt, int mode, dev_t dev);
 int security_inode_rename(struct inode *old_dir, struct dentry *old_dentry,
-  struct inode *new_dir, struct dentry *new_dentry);
+ struct vfsmount *old_mnt, struct inode *new_dir,
+ struct dentry *new_dentry, struct vfsmount *new_mnt);
 int security_inode_readlink(struct dentry *dentry, struct vfsmount *mnt);
 int security_inode_follow_link(struct dentry *dentry, struct nameidata *nd);
 int security_inode_permission(struct inode *inode, int mask, struct nameidata 
*nd);
@@ -1924,8 +1929,10 @@ static inline int security_inode_mknod (
 
 static inline int security_inode_rename (struct inode *old_dir,
 struct dentry *old_dentry,
+struct vfsmount *old_mnt,
 struct inode *new_dir,
-struct dentry *new_dentry)
+struct dentry *new_dentry,
+struct vfsmount *new_mnt)
 {
return 0;
 }
--- a/security/dummy.c
+++ b/security/dummy.c
@@ -335,8 +335,10 @@ static int dummy_inode_mknod (struct ino
 
 static int dummy_inode_rename (struct inode *old_inode,
   struct dentry *old_dentry,
+  struct vfsmount *old_mnt,
   struct inode *new_inode,
-  struct dentry *new_dentry)
+  struct dentry *new_dentry,
+  struct vfsmount *new_mnt)
 {
return 0;
 }
--- a/security/security.c
+++ b/security/security.c
@@ -407,13 +407,14 @@ int security_inode_mknod(struct inode *d
 }
 
 int security_inode_rename(struct inode *old_dir, struct dentry *old_dentry,
-  struct inode *new_dir, struct dentry *new_dentry)
+ struct vfsmount *old_mnt, struct inode *new_dir,
+ 

[AppArmor 21/47] Add a struct vfsmount parameter to vfs_setxattr()

2007-12-20 Thread John
The vfsmount will be passed down to the LSM hook so that LSMs can compute
pathnames.

Signed-off-by: Tony Jones [EMAIL PROTECTED]
Signed-off-by: Andreas Gruenbacher [EMAIL PROTECTED]
Signed-off-by: John Johansen [EMAIL PROTECTED]

---
 fs/nfsd/vfs.c |   16 +++-
 fs/unionfs/copyup.c   |   18 --
 fs/unionfs/xattr.c|7 +--
 fs/xattr.c|   16 
 include/linux/xattr.h |3 ++-
 5 files changed, 38 insertions(+), 22 deletions(-)

--- a/fs/nfsd/vfs.c
+++ b/fs/nfsd/vfs.c
@@ -426,7 +426,8 @@ static ssize_t nfsd_getxattr(struct dent
 
 #if defined(CONFIG_NFSD_V4)
 static int
-set_nfsv4_acl_one(struct dentry *dentry, struct posix_acl *pacl, char *key)
+set_nfsv4_acl_one(struct dentry *dentry, struct vfsmount *mnt,
+ struct posix_acl *pacl, char *key)
 {
int len;
size_t buflen;
@@ -445,7 +446,7 @@ set_nfsv4_acl_one(struct dentry *dentry,
goto out;
}
 
-   error = vfs_setxattr(dentry, key, buf, len, 0);
+   error = vfs_setxattr(dentry, mnt, key, buf, len, 0);
 out:
kfree(buf);
return error;
@@ -458,6 +459,7 @@ nfsd4_set_nfs4_acl(struct svc_rqst *rqst
__be32 error;
int host_error;
struct dentry *dentry;
+   struct vfsmount *mnt;
struct inode *inode;
struct posix_acl *pacl = NULL, *dpacl = NULL;
unsigned int flags = 0;
@@ -468,6 +470,7 @@ nfsd4_set_nfs4_acl(struct svc_rqst *rqst
return error;
 
dentry = fhp-fh_dentry;
+   mnt = fhp-fh_export-ex_path.mnt;
inode = dentry-d_inode;
if (S_ISDIR(inode-i_mode))
flags = NFS4_ACL_DIR;
@@ -478,12 +481,14 @@ nfsd4_set_nfs4_acl(struct svc_rqst *rqst
} else if (host_error  0)
goto out_nfserr;
 
-   host_error = set_nfsv4_acl_one(dentry, pacl, POSIX_ACL_XATTR_ACCESS);
+   host_error = set_nfsv4_acl_one(dentry, mnt, pacl,
+  POSIX_ACL_XATTR_ACCESS);
if (host_error  0)
goto out_release;
 
if (S_ISDIR(inode-i_mode))
-   host_error = set_nfsv4_acl_one(dentry, dpacl, 
POSIX_ACL_XATTR_DEFAULT);
+   host_error = set_nfsv4_acl_one(dentry, mnt, dpacl,
+  POSIX_ACL_XATTR_DEFAULT);
 
 out_release:
posix_acl_release(pacl);
@@ -2057,7 +2062,8 @@ 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(fhp-fh_dentry, 
fhp-fh_export-ex_path.mnt,
+name, value, size,0);
else {
if (!S_ISDIR(inode-i_mode)  type == ACL_TYPE_DEFAULT)
error = 0;
--- a/fs/unionfs/copyup.c
+++ b/fs/unionfs/copyup.c
@@ -26,7 +26,9 @@
 #ifdef CONFIG_UNION_FS_XATTR
 /* copyup all extended attrs for a given dentry */
 static int copyup_xattrs(struct dentry *old_lower_dentry,
-struct dentry *new_lower_dentry)
+struct vfsmount *old_lower_mnt,
+struct dentry *new_lower_dentry,
+struct vfsmount *new_lower_mnt)
 {
int err = 0;
ssize_t list_size = -1;
@@ -82,8 +84,8 @@ static int copyup_xattrs(struct dentry *
goto out;
}
/* Don't lock here since vfs_setxattr does it for us. */
-   err = vfs_setxattr(new_lower_dentry, name_list, attr_value,
-  size, 0);
+   err = vfs_setxattr(new_lower_dentry, new_lower_mnt, name_list,
+  attr_value, size, 0);
/*
 * Selinux depends on security.* xattrs, so to maintain
 * the security of copied-up files, if Selinux is active,
@@ -93,8 +95,8 @@ static int copyup_xattrs(struct dentry *
 */
if (err == -EPERM  !capable(CAP_FOWNER)) {
cap_raise(current-cap_effective, CAP_FOWNER);
-   err = vfs_setxattr(new_lower_dentry, name_list,
-  attr_value, size, 0);
+   err = vfs_setxattr(new_lower_dentry, new_lower_mnt,
+  name_list, attr_value, size, 0);
cap_lower(current-cap_effective, CAP_FOWNER);
}
if (err  0)
@@ -380,6 +382,7 @@ int copyup_dentry(struct inode *dir, str
struct dentry *new_lower_dentry;
struct vfsmount *new_lower_mnt;
struct dentry *old_lower_dentry = NULL;
+   struct vfsmount *old_lower_mnt;
struct super_block *sb;
int err = 0;
int old_bindex;
@@ -413,6 +416,8 @@ int copyup_dentry(struct inode *dir, str
}
 
old_lower_dentry = 

[AppArmor 22/47] Pass struct vfsmount to the inode_setxattr LSM hook

2007-12-20 Thread John
This is needed for computing pathnames in the AppArmor LSM.

Signed-off-by: Tony Jones [EMAIL PROTECTED]
Signed-off-by: Andreas Gruenbacher [EMAIL PROTECTED]
Signed-off-by: John Johansen [EMAIL PROTECTED]

---
 fs/xattr.c   |4 ++--
 include/linux/security.h |   35 +--
 security/commoncap.c |4 ++--
 security/dummy.c |9 ++---
 security/security.c  |   14 --
 security/selinux/hooks.c |8 ++--
 6 files changed, 45 insertions(+), 29 deletions(-)

--- a/fs/xattr.c
+++ b/fs/xattr.c
@@ -78,7 +78,7 @@ vfs_setxattr(struct dentry *dentry, stru
return error;
 
mutex_lock(inode-i_mutex);
-   error = security_inode_setxattr(dentry, name, value, size, flags);
+   error = security_inode_setxattr(dentry, mnt, name, value, size, flags);
if (error)
goto out;
error = -EOPNOTSUPP;
@@ -86,7 +86,7 @@ vfs_setxattr(struct dentry *dentry, stru
error = inode-i_op-setxattr(dentry, name, value, size, flags);
if (!error) {
fsnotify_xattr(dentry);
-   security_inode_post_setxattr(dentry, name, value,
+   security_inode_post_setxattr(dentry, mnt, name, value,
 size, flags);
}
} else if (!strncmp(name, XATTR_SECURITY_PREFIX,
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -57,7 +57,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 dentry *dentry, struct vfsmount *mnt, 
char *name, void *value, size_t size, int flags);
 extern int cap_inode_removexattr(struct dentry *dentry, char *name);
 extern int cap_inode_need_killpriv(struct dentry *dentry);
 extern int cap_inode_killpriv(struct dentry *dentry);
@@ -415,11 +415,11 @@ struct request_sock;
  * inode.
  * @inode_setxattr:
  * Check permission before setting the extended attributes
- * @value identified by @name for @dentry.
+ * @value identified by @name for @dentry and @mnt.
  * Return 0 if permission is granted.
  * @inode_post_setxattr:
  * Update inode security field after successful setxattr operation.
- * @value identified by @name for @dentry.
+ * @value identified by @name for @dentry and @mnt.
  * @inode_getxattr:
  * Check permission before obtaining the extended attributes
  * identified by @name for @dentry.
@@ -1310,9 +1310,11 @@ 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);
-   void (*inode_post_setxattr) (struct dentry *dentry, char *name, void 
*value,
+   int (*inode_setxattr) (struct dentry *dentry, struct vfsmount *mnt,
+  char *name, void *value, size_t size, int flags);
+   void (*inode_post_setxattr) (struct dentry *dentry,
+struct vfsmount *mnt,
+char *name, void *value,
 size_t size, int flags);
int (*inode_getxattr) (struct dentry *dentry, char *name);
int (*inode_listxattr) (struct dentry *dentry);
@@ -1580,10 +1582,11 @@ int security_inode_setattr(struct dentry
   struct iattr *attr);
 int security_inode_getattr(struct vfsmount *mnt, struct dentry *dentry);
 void security_inode_delete(struct inode *inode);
-int security_inode_setxattr(struct dentry *dentry, char *name,
-void *value, size_t size, int flags);
-void security_inode_post_setxattr(struct dentry *dentry, char *name,
-  void *value, size_t size, int flags);
+int security_inode_setxattr(struct dentry *dentry, struct vfsmount *mnt,
+   char *name, void *value, size_t size, int flags);
+void security_inode_post_setxattr(struct dentry *dentry, struct vfsmount *mnt,
+ char *name, void *value, size_t size,
+ int flags);
 int security_inode_getxattr(struct dentry *dentry, char *name);
 int security_inode_listxattr(struct dentry *dentry);
 int security_inode_removexattr(struct dentry *dentry, char *name);
@@ -1971,14 +1974,18 @@ static inline int security_inode_getattr
 static inline void security_inode_delete (struct inode *inode)
 { }
 
-static inline int 

[AppArmor 23/47] Add a struct vfsmount parameter to vfs_getxattr()

2007-12-20 Thread John
The vfsmount will be passed down to the LSM hook so that LSMs can compute
pathnames.

Signed-off-by: Tony Jones [EMAIL PROTECTED]
Signed-off-by: Andreas Gruenbacher [EMAIL PROTECTED]
Signed-off-by: John Johansen [EMAIL PROTECTED]

---
 fs/nfsd/nfs4xdr.c |2 +-
 fs/nfsd/vfs.c |   21 -
 fs/unionfs/copyup.c   |2 +-
 fs/unionfs/xattr.c|4 +++-
 fs/xattr.c|   14 --
 include/linux/nfsd/nfsd.h |3 ++-
 include/linux/xattr.h |2 +-
 7 files changed, 28 insertions(+), 20 deletions(-)

--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -1501,7 +1501,7 @@ nfsd4_encode_fattr(struct svc_fh *fhp, s
}
if (bmval0  (FATTR4_WORD0_ACL | FATTR4_WORD0_ACLSUPPORT
| FATTR4_WORD0_SUPPORTED_ATTRS)) {
-   err = nfsd4_get_nfs4_acl(rqstp, dentry, acl);
+   err = nfsd4_get_nfs4_acl(rqstp, dentry, exp-ex_path.mnt, acl);
aclsupport = (err == 0);
if (bmval0  FATTR4_WORD0_ACL) {
if (err == -EOPNOTSUPP)
--- a/fs/nfsd/vfs.c
+++ b/fs/nfsd/vfs.c
@@ -408,11 +408,12 @@ out_nfserr:
 #if defined(CONFIG_NFSD_V2_ACL) || \
 defined(CONFIG_NFSD_V3_ACL) || \
 defined(CONFIG_NFSD_V4)
-static ssize_t nfsd_getxattr(struct dentry *dentry, char *key, void **buf)
+static ssize_t nfsd_getxattr(struct dentry *dentry, struct vfsmount *mnt,
+char *key, void **buf)
 {
ssize_t buflen;
 
-   buflen = vfs_getxattr(dentry, key, NULL, 0);
+   buflen = vfs_getxattr(dentry, mnt, key, NULL, 0);
if (buflen = 0)
return buflen;
 
@@ -420,7 +421,7 @@ static ssize_t nfsd_getxattr(struct dent
if (!*buf)
return -ENOMEM;
 
-   return vfs_getxattr(dentry, key, *buf, buflen);
+   return vfs_getxattr(dentry, mnt, key, *buf, buflen);
 }
 #endif
 
@@ -501,13 +502,13 @@ out_nfserr:
 }
 
 static struct posix_acl *
-_get_posix_acl(struct dentry *dentry, char *key)
+_get_posix_acl(struct dentry *dentry, struct vfsmount *mnt, char *key)
 {
void *buf = NULL;
struct posix_acl *pacl = NULL;
int buflen;
 
-   buflen = nfsd_getxattr(dentry, key, buf);
+   buflen = nfsd_getxattr(dentry, mnt, key, buf);
if (!buflen)
buflen = -ENODATA;
if (buflen = 0)
@@ -519,14 +520,15 @@ _get_posix_acl(struct dentry *dentry, ch
 }
 
 int
-nfsd4_get_nfs4_acl(struct svc_rqst *rqstp, struct dentry *dentry, struct 
nfs4_acl **acl)
+nfsd4_get_nfs4_acl(struct svc_rqst *rqstp, struct dentry *dentry,
+  struct vfsmount *mnt, struct nfs4_acl **acl)
 {
struct inode *inode = dentry-d_inode;
int error = 0;
struct posix_acl *pacl = NULL, *dpacl = NULL;
unsigned int flags = 0;
 
-   pacl = _get_posix_acl(dentry, POSIX_ACL_XATTR_ACCESS);
+   pacl = _get_posix_acl(dentry, mnt, POSIX_ACL_XATTR_ACCESS);
if (IS_ERR(pacl)  PTR_ERR(pacl) == -ENODATA)
pacl = posix_acl_from_mode(inode-i_mode, GFP_KERNEL);
if (IS_ERR(pacl)) {
@@ -536,7 +538,7 @@ nfsd4_get_nfs4_acl(struct svc_rqst *rqst
}
 
if (S_ISDIR(inode-i_mode)) {
-   dpacl = _get_posix_acl(dentry, POSIX_ACL_XATTR_DEFAULT);
+   dpacl = _get_posix_acl(dentry, mnt, POSIX_ACL_XATTR_DEFAULT);
if (IS_ERR(dpacl)  PTR_ERR(dpacl) == -ENODATA)
dpacl = NULL;
else if (IS_ERR(dpacl)) {
@@ -2017,7 +2019,8 @@ nfsd_get_posix_acl(struct svc_fh *fhp, i
return ERR_PTR(-EOPNOTSUPP);
}
 
-   size = nfsd_getxattr(fhp-fh_dentry, name, value);
+   size = nfsd_getxattr(fhp-fh_dentry, fhp-fh_export-ex_path.mnt, name,
+value);
if (size  0)
return ERR_PTR(size);
 
--- a/fs/unionfs/copyup.c
+++ b/fs/unionfs/copyup.c
@@ -72,7 +72,7 @@ static int copyup_xattrs(struct dentry *
 
/* Lock here since vfs_getxattr doesn't lock for us */
mutex_lock(old_lower_dentry-d_inode-i_mutex);
-   size = vfs_getxattr(old_lower_dentry, name_list,
+   size = vfs_getxattr(old_lower_dentry, old_lower_mnt, name_list,
attr_value, XATTR_SIZE_MAX);
mutex_unlock(old_lower_dentry-d_inode-i_mutex);
if (size  0) {
--- a/fs/unionfs/xattr.c
+++ b/fs/unionfs/xattr.c
@@ -43,6 +43,7 @@ ssize_t unionfs_getxattr(struct dentry *
 size_t size)
 {
struct dentry *lower_dentry = NULL;
+   struct vfsmount *lower_mnt;
int err = -EOPNOTSUPP;
 
unionfs_read_lock(dentry-d_sb);
@@ -54,8 +55,9 @@ ssize_t unionfs_getxattr(struct dentry *
}
 
lower_dentry = unionfs_lower_dentry(dentry);
+   lower_mnt = unionfs_lower_mnt(dentry);
 
-   err = vfs_getxattr(lower_dentry, (char *) name, value, size);
+   err = 

[AppArmor 24/47] Pass struct vfsmount to the inode_getxattr LSM hook

2007-12-20 Thread John
This is needed for computing pathnames in the AppArmor LSM.

Signed-off-by: Tony Jones [EMAIL PROTECTED]
Signed-off-by: Andreas Gruenbacher [EMAIL PROTECTED]
Signed-off-by: John Johansen [EMAIL PROTECTED]

---
 fs/xattr.c   |2 +-
 include/linux/security.h |   11 +++
 security/dummy.c |3 ++-
 security/security.c  |5 +++--
 security/selinux/hooks.c |3 ++-
 5 files changed, 15 insertions(+), 9 deletions(-)

--- a/fs/xattr.c
+++ b/fs/xattr.c
@@ -141,7 +141,7 @@ vfs_getxattr(struct dentry *dentry, stru
if (error)
return error;
 
-   error = security_inode_getxattr(dentry, name);
+   error = security_inode_getxattr(dentry, mnt, name);
if (error)
return error;
 
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -422,7 +422,7 @@ struct request_sock;
  * @value identified by @name for @dentry and @mnt.
  * @inode_getxattr:
  * Check permission before obtaining the extended attributes
- * identified by @name for @dentry.
+ * identified by @name for @dentry and @mnt.
  * Return 0 if permission is granted.
  * @inode_listxattr:
  * Check permission before obtaining the list of extended attribute 
@@ -1316,7 +1316,8 @@ struct security_operations {
 struct vfsmount *mnt,
 char *name, void *value,
 size_t size, int flags);
-   int (*inode_getxattr) (struct dentry *dentry, char *name);
+   int (*inode_getxattr) (struct dentry *dentry, struct vfsmount *mnt,
+  char *name);
int (*inode_listxattr) (struct dentry *dentry);
int (*inode_removexattr) (struct dentry *dentry, char *name);
int (*inode_need_killpriv) (struct dentry *dentry);
@@ -1587,7 +1588,8 @@ int security_inode_setxattr(struct dentr
 void security_inode_post_setxattr(struct dentry *dentry, struct vfsmount *mnt,
  char *name, void *value, size_t size,
  int flags);
-int security_inode_getxattr(struct dentry *dentry, char *name);
+int security_inode_getxattr(struct dentry *dentry, struct vfsmount *mnt,
+   char *name);
 int security_inode_listxattr(struct dentry *dentry);
 int security_inode_removexattr(struct dentry *dentry, char *name);
 int security_inode_need_killpriv(struct dentry *dentry);
@@ -1988,7 +1990,8 @@ static inline void security_inode_post_s
 int flags)
 { }
 
-static inline int security_inode_getxattr (struct dentry *dentry, char *name)
+static inline int security_inode_getxattr (struct dentry *dentry,
+   struct vfsmount *mnt, char *name)
 {
return 0;
 }
--- a/security/dummy.c
+++ b/security/dummy.c
@@ -393,7 +393,8 @@ static void dummy_inode_post_setxattr (s
 {
 }
 
-static int dummy_inode_getxattr (struct dentry *dentry, char *name)
+static int dummy_inode_getxattr (struct dentry *dentry,
+ struct vfsmount *mnt, char *name)
 {
return 0;
 }
--- a/security/security.c
+++ b/security/security.c
@@ -478,11 +478,12 @@ void security_inode_post_setxattr(struct
security_ops-inode_post_setxattr(dentry, mnt, name, value, size, 
flags);
 }
 
-int security_inode_getxattr(struct dentry *dentry, char *name)
+int security_inode_getxattr(struct dentry *dentry, struct vfsmount *mnt,
+   char *name)
 {
if (unlikely(IS_PRIVATE(dentry-d_inode)))
return 0;
-   return security_ops-inode_getxattr(dentry, name);
+   return security_ops-inode_getxattr(dentry, mnt, name);
 }
 
 int security_inode_listxattr(struct dentry *dentry)
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -2636,7 +2636,8 @@ static void selinux_inode_post_setxattr(
return;
 }
 
-static int selinux_inode_getxattr (struct dentry *dentry, char *name)
+static int selinux_inode_getxattr (struct dentry *dentry, struct vfsmount *mnt,
+  char *name)
 {
return dentry_has_perm(current, NULL, dentry, FILE__GETATTR);
 }

-- 

-
To unsubscribe from this list: send the line unsubscribe 
linux-security-module in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[AppArmor 25/47] Add a struct vfsmount parameter to vfs_listxattr()

2007-12-20 Thread John
The vfsmount will be passed down to the LSM hook so that LSMs can compute
pathnames.

Signed-off-by: Tony Jones [EMAIL PROTECTED]
Signed-off-by: Andreas Gruenbacher [EMAIL PROTECTED]
Signed-off-by: John Johansen [EMAIL PROTECTED]

---
 fs/unionfs/copyup.c   |5 +++--
 fs/unionfs/xattr.c|4 +++-
 fs/xattr.c|   25 ++---
 include/linux/xattr.h |2 +-
 4 files changed, 21 insertions(+), 15 deletions(-)

--- a/fs/unionfs/copyup.c
+++ b/fs/unionfs/copyup.c
@@ -37,7 +37,7 @@ static int copyup_xattrs(struct dentry *
char *name_list_buf = NULL;
 
/* query the actual size of the xattr list */
-   list_size = vfs_listxattr(old_lower_dentry, NULL, 0);
+   list_size = vfs_listxattr(old_lower_dentry, old_lower_mnt, NULL, 0);
if (list_size = 0) {
err = list_size;
goto out;
@@ -53,7 +53,8 @@ static int copyup_xattrs(struct dentry *
name_list_buf = name_list; /* save for kfree at end */
 
/* now get the actual xattr list of the source file */
-   list_size = vfs_listxattr(old_lower_dentry, name_list, list_size);
+   list_size = vfs_listxattr(old_lower_dentry, old_lower_mnt, name_list,
+ list_size);
if (list_size = 0) {
err = list_size;
goto out;
--- a/fs/unionfs/xattr.c
+++ b/fs/unionfs/xattr.c
@@ -134,6 +134,7 @@ out:
 ssize_t unionfs_listxattr(struct dentry *dentry, char *list, size_t size)
 {
struct dentry *lower_dentry = NULL;
+   struct vfsmount *lower_mnt;
int err = -EOPNOTSUPP;
char *encoded_list = NULL;
 
@@ -146,9 +147,10 @@ ssize_t unionfs_listxattr(struct dentry 
}
 
lower_dentry = unionfs_lower_dentry(dentry);
+   lower_mnt = unionfs_lower_mnt(dentry);
 
encoded_list = list;
-   err = vfs_listxattr(lower_dentry, encoded_list, size);
+   err = vfs_listxattr(lower_dentry, lower_mnt, encoded_list, size);
 
 out:
unionfs_check_dentry(dentry);
--- a/fs/xattr.c
+++ b/fs/xattr.c
@@ -168,18 +168,20 @@ nolsm:
 EXPORT_SYMBOL_GPL(vfs_getxattr);
 
 ssize_t
-vfs_listxattr(struct dentry *d, char *list, size_t size)
+vfs_listxattr(struct dentry *dentry, struct vfsmount *mnt, 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;
}
@@ -400,7 +402,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 dentry *dentry, struct vfsmount *mnt, char __user *list,
+ size_t size)
 {
ssize_t error;
char *klist = NULL;
@@ -413,7 +416,7 @@ listxattr(struct dentry *d, char __user 
return -ENOMEM;
}
 
-   error = vfs_listxattr(d, klist, size);
+   error = vfs_listxattr(dentry, mnt, klist, size);
if (error  0) {
if (size  copy_to_user(list, klist, error))
error = -EFAULT;
@@ -435,7 +438,7 @@ sys_listxattr(char __user *path, char __
error = user_path_walk(path, nd);
if (error)
return error;
-   error = listxattr(nd.path.dentry, list, size);
+   error = listxattr(nd.path.dentry, nd.path.mnt, list, size);
path_put(nd.path);
return error;
 }
@@ -449,7 +452,7 @@ sys_llistxattr(char __user *path, char _
error = user_path_walk_link(path, nd);
if (error)
return error;
-   error = listxattr(nd.path.dentry, list, size);
+   error = listxattr(nd.path.dentry, nd.path.mnt, list, size);
path_put(nd.path);
return error;
 }
@@ -464,7 +467,7 @@ sys_flistxattr(int fd, char __user *list
if (!f)
return error;
audit_inode(NULL, f-f_path.dentry);
-   error = listxattr(f-f_path.dentry, list, size);
+   error = listxattr(f-f_path.dentry, f-f_path.mnt, list, size);
fput(f);
return error;
 }
--- a/include/linux/xattr.h
+++ b/include/linux/xattr.h
@@ -48,7 +48,7 @@ struct xattr_handler {
 
 ssize_t xattr_getsecurity(struct inode *, const char *, void *, size_t);
 ssize_t vfs_getxattr(struct dentry *, struct vfsmount *, char *, void *, 
size_t);
-ssize_t vfs_listxattr(struct 

[AppArmor 40/47] Export audit subsystem for use by modules

2007-12-20 Thread John
Update kenel audit range comments to show AppArmor's registered range of
1500-1599.  This range used to be reserved for LSPP but LSPP uses the
SE Linux range and the range was given to AppArmor.
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

Signed-off-by: Andreas Gruenbacher [EMAIL PROTECTED]
Signed-off-by: John Johansen [EMAIL PROTECTED]

---
 include/linux/audit.h |   12 +++-
 kernel/audit.c|6 --
 2 files changed, 15 insertions(+), 3 deletions(-)

--- a/include/linux/audit.h
+++ b/include/linux/audit.h
@@ -33,7 +33,7 @@
  * 1200 - 1299 messages internal to the audit daemon
  * 1300 - 1399 audit event messages
  * 1400 - 1499 SE Linux use
- * 1500 - 1599 kernel LSPP events
+ * 1500 - 1599 AppArmor use
  * 1600 - 1699 kernel crypto events
  * 1700 - 1799 kernel anomaly records
  * 1800 - 1999 future kernel use (maybe integrity labels and related events)
@@ -118,6 +118,13 @@
 #define AUDIT_MAC_UNLBL_STCADD 1416/* NetLabel: add a static label */
 #define AUDIT_MAC_UNLBL_STCDEL 1417/* NetLabel: del a static label */
 
+#define AUDIT_APPARMOR_AUDIT   1501/* AppArmor audited grants */
+#define AUDIT_APPARMOR_ALLOWED 1502/* Allowed Access for learning */
+#define AUDIT_APPARMOR_DENIED  1503
+#define AUDIT_APPARMOR_HINT1504/* Process Tracking information */
+#define AUDIT_APPARMOR_STATUS  1505/* Changes in config */
+#define AUDIT_APPARMOR_ERROR   1506/* Internal AppArmor Errors */
+
 #define AUDIT_FIRST_KERN_ANOM_MSG   1700
 #define AUDIT_LAST_KERN_ANOM_MSG1799
 #define AUDIT_ANOM_PROMISCUOUS  1700 /* Device changed promiscuous mode */
@@ -515,6 +522,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 voidaudit_log_vformat(struct audit_buffer *ab,
+ const char *fmt, va_list args)
+   __attribute__((format(printf,2,0)));
 extern voidaudit_log_format(struct audit_buffer *ab,
 const char *fmt, ...)
__attribute__((format(printf,2,3)));
--- a/kernel/audit.c
+++ b/kernel/audit.c
@@ -1215,8 +1215,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;
@@ -1472,3 +1471,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);

-- 

-
To unsubscribe from this list: send the line unsubscribe 
linux-security-module in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[AppArmor 41/47] AppArmor: Main Part

2007-12-20 Thread John
The underlying functions by which the AppArmor LSM hooks are implemented.

Signed-off-by: John Johansen [EMAIL PROTECTED]
Signed-off-by: Andreas Gruenbacher [EMAIL PROTECTED]

---
 security/apparmor/main.c | 1357 +++
 1 file changed, 1357 insertions(+)

--- /dev/null
+++ b/security/apparmor/main.c
@@ -0,0 +1,1357 @@
+/*
+ * Copyright (C) 2002-2007 Novell/SUSE
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, version 2 of the
+ * License.
+ *
+ * AppArmor Core
+ */
+
+#include linux/security.h
+#include linux/namei.h
+#include linux/audit.h
+#include linux/mount.h
+#include linux/ptrace.h
+
+#include apparmor.h
+
+#include inline.h
+
+/*
+ * Table of capability names: we generate it from capabilities.h.
+ */
+static const char *capability_names[] = {
+#include capability_names.h
+};
+
+struct aa_namespace *default_namespace;
+
+static int aa_inode_mode(struct inode *inode)
+{
+   /* if the inode doesn't exist the user is creating it */
+   if (!inode || current-fsuid == inode-i_uid)
+   return AA_USER_SHIFT;
+   return AA_OTHER_SHIFT;
+}
+
+/**
+ * aa_file_denied - check for @mask access on a file
+ * @profile: profile to check against
+ * @name: pathname of file
+ * @mask: permission mask requested for file
+ *
+ * Return %0 on success, or else the permissions in @mask that the
+ * profile denies.
+ */
+static int aa_file_denied(struct aa_profile *profile, const char *name,
+ int mask)
+{
+   return (mask  ~aa_match(profile-file_rules, name));
+}
+
+/**
+ * aa_link_denied - check for permission to link a file
+ * @profile: profile to check against
+ * @link: pathname of link being created
+ * @target: pathname of target to be linked to
+ * @target_mode: UGO shift for target inode
+ * @request_mask: the permissions subset valid only if link succeeds
+ * Return %0 on success, or else the permissions that the profile denies.
+ */
+static int aa_link_denied(struct aa_profile *profile, const char *link,
+ const char *target, int target_mode,
+ int *request_mask)
+{
+   unsigned int state;
+   int l_mode, t_mode, denied_mask = 0;
+   int link_mask = AA_MAY_LINK  target_mode;
+
+   *request_mask = link_mask;
+
+   l_mode = aa_match_state(profile-file_rules, DFA_START, link, state);
+   if (l_mode  link_mask) {
+   int mode;
+   /* test to see if target can be paired with link */
+   state = aa_dfa_null_transition(profile-file_rules, state);
+   mode = aa_match_state(profile-file_rules, state, target,
+ NULL);
+
+   if (!(mode  link_mask))
+   denied_mask |= link_mask;
+   if (!(mode  (AA_LINK_SUBSET_TEST  target_mode)))
+   return denied_mask;
+   }
+
+   /* do link perm subset test */
+   t_mode = aa_match(profile-file_rules, target);
+
+   /* Ignore valid-profile-transition flags. */
+   l_mode = ~AA_SHARED_PERMS;
+   t_mode = ~AA_SHARED_PERMS;
+
+   *request_mask = l_mode | link_mask;
+
+   /* Link always requires 'l' on the link for both parts of the pair.
+* If a subset test is required a permission subset test of the
+* perms for the link are done against the user:group:other of the
+* target's 'r', 'w', 'x', 'a', 'z', and 'm' permissions.
+*
+* If the link has 'x', an exact match of all the execute flags
+* ('i', 'u', 'p').  safe exec is treated as a subset of unsafe exec
+*/
+#define SUBSET_PERMS (AA_FILE_PERMS  ~AA_LINK_BITS)
+   denied_mask |= ~l_mode  link_mask;
+   if (l_mode  SUBSET_PERMS) {
+   denied_mask |= (l_mode  SUBSET_PERMS)  ~t_mode;
+   if (denied_mask  AA_EXEC_BITS)
+   denied_mask |= l_mode  AA_ALL_EXEC_MODS;
+   else if (l_mode  AA_EXEC_BITS) {
+   if (!(l_mode  AA_USER_EXEC_UNSAFE))
+   l_mode |= t_mode  AA_USER_EXEC_UNSAFE;
+   if (l_mode  AA_USER_EXEC 
+   (l_mode  AA_USER_EXEC_MODS) !=
+   (t_mode  AA_USER_EXEC_MODS))
+   denied_mask |= AA_USER_EXEC |
+   (l_mode  AA_USER_EXEC_MODS);
+   if (!(l_mode  AA_OTHER_EXEC_UNSAFE))
+   l_mode |= t_mode  AA_OTHER_EXEC_UNSAFE;
+   if (l_mode  AA_OTHER_EXEC 
+   (l_mode  AA_OTHER_EXEC_MODS) !=
+   (t_mode  AA_OTHER_EXEC_MODS))
+   denied_mask |= AA_OTHER_EXEC |
+   (l_mode  

[AppArmor 43/47] AppArmor: Profile loading and manipulation, pathname matching

2007-12-20 Thread John
Pathname matching, transition table loading, profile loading and
manipulation.

Signed-off-by: John Johansen [EMAIL PROTECTED]
Signed-off-by: Andreas Gruenbacher [EMAIL PROTECTED]

---
 security/apparmor/match.c|  299 +
 security/apparmor/match.h|   85 +++
 security/apparmor/module_interface.c |  805 +++
 3 files changed, 1189 insertions(+)

--- /dev/null
+++ b/security/apparmor/match.c
@@ -0,0 +1,299 @@
+/*
+ * Copyright (C) 2007 Novell/SUSE
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, version 2 of the
+ * License.
+ *
+ * Regular expression transition table matching
+ */
+
+#include linux/kernel.h
+#include linux/slab.h
+#include linux/errno.h
+#include apparmor.h
+#include match.h
+
+static struct table_header *unpack_table(void *blob, size_t bsize)
+{
+   struct table_header *table = NULL;
+   struct table_header th;
+   size_t tsize;
+
+   if (bsize  sizeof(struct table_header))
+   goto out;
+
+   th.td_id = be16_to_cpu(*(u16 *) (blob));
+   th.td_flags = be16_to_cpu(*(u16 *) (blob + 2));
+   th.td_lolen = be32_to_cpu(*(u32 *) (blob + 8));
+   blob += sizeof(struct table_header);
+
+   if (!(th.td_flags == YYTD_DATA16 || th.td_flags == YYTD_DATA32 ||
+   th.td_flags == YYTD_DATA8))
+   goto out;
+
+   tsize = table_size(th.td_lolen, th.td_flags);
+   if (bsize  tsize)
+   goto out;
+
+   table = kmalloc(tsize, GFP_KERNEL);
+   if (table) {
+   *table = th;
+   if (th.td_flags == YYTD_DATA8)
+   UNPACK_ARRAY(table-td_data, blob, th.td_lolen,
+u8, byte_to_byte);
+   else if (th.td_flags == YYTD_DATA16)
+   UNPACK_ARRAY(table-td_data, blob, th.td_lolen,
+u16, be16_to_cpu);
+   else
+   UNPACK_ARRAY(table-td_data, blob, th.td_lolen,
+u32, be32_to_cpu);
+   }
+
+out:
+   return table;
+}
+
+int unpack_dfa(struct aa_dfa *dfa, void *blob, size_t size)
+{
+   int hsize, i;
+   int error = -ENOMEM;
+
+   /* get dfa table set header */
+   if (size  sizeof(struct table_set_header))
+   goto fail;
+
+   if (ntohl(*(u32 *)blob) != YYTH_MAGIC)
+   goto fail;
+
+   hsize = ntohl(*(u32 *)(blob + 4));
+   if (size  hsize)
+   goto fail;
+
+   blob += hsize;
+   size -= hsize;
+
+   error = -EPROTO;
+   while (size  0) {
+   struct table_header *table;
+   table = unpack_table(blob, size);
+   if (!table)
+   goto fail;
+
+   switch(table-td_id) {
+   case YYTD_ID_ACCEPT:
+   case YYTD_ID_BASE:
+   dfa-tables[table-td_id - 1] = table;
+   if (table-td_flags != YYTD_DATA32)
+   goto fail;
+   break;
+   case YYTD_ID_DEF:
+   case YYTD_ID_NXT:
+   case YYTD_ID_CHK:
+   dfa-tables[table-td_id - 1] = table;
+   if (table-td_flags != YYTD_DATA16)
+   goto fail;
+   break;
+   case YYTD_ID_EC:
+   dfa-tables[table-td_id - 1] = table;
+   if (table-td_flags != YYTD_DATA8)
+   goto fail;
+   break;
+   default:
+   kfree(table);
+   goto fail;
+   }
+
+   blob += table_size(table-td_lolen, table-td_flags);
+   size -= table_size(table-td_lolen, table-td_flags);
+   }
+
+   return 0;
+
+fail:
+   for (i = 0; i  ARRAY_SIZE(dfa-tables); i++) {
+   if (dfa-tables[i]) {
+   kfree(dfa-tables[i]);
+   dfa-tables[i] = NULL;
+   }
+   }
+   return error;
+}
+
+/**
+ * verify_dfa - verify that all the transitions and states in the dfa tables
+ *  are in bounds.
+ * @dfa: dfa to test
+ *
+ * assumes dfa has gone through the verification done by unpacking
+ */
+int verify_dfa(struct aa_dfa *dfa)
+{
+   size_t i, state_count, trans_count;
+   int error = -EPROTO;
+
+   /* check that required tables exist */
+   if (!(dfa-tables[YYTD_ID_ACCEPT -1 ] 
+ dfa-tables[YYTD_ID_DEF - 1] 
+ dfa-tables[YYTD_ID_BASE - 1] 
+ dfa-tables[YYTD_ID_NXT - 1] 
+ dfa-tables[YYTD_ID_CHK - 1]))
+   goto out;
+
+   /* accept.size == default.size == base.size */
+   state_count = 

[AppArmor 44/47] AppArmor: all the rest

2007-12-20 Thread John
All the things that didn't nicely fit in a category on their own: kbuild
code, declararions and inline functions, /sys/kernel/security/apparmor
filesystem for controlling apparmor from user space, profile list
functions, locking documentation, /proc/$pid/task/$tid/attr/current
access.

Signed-off-by: John Johansen [EMAIL PROTECTED]
Signed-off-by: Andreas Gruenbacher [EMAIL PROTECTED]

---
 security/apparmor/Kconfig  |9 +
 security/apparmor/Makefile |   13 +
 security/apparmor/apparmor.h   |  323 +
 security/apparmor/apparmorfs.c |  252 +++
 security/apparmor/inline.h |  240 ++
 security/apparmor/list.c   |  156 +++
 security/apparmor/locking.txt  |   68 
 security/apparmor/procattr.c   |  194 
 8 files changed, 1255 insertions(+)

--- /dev/null
+++ b/security/apparmor/Kconfig
@@ -0,0 +1,9 @@
+config SECURITY_APPARMOR
+   tristate AppArmor support
+   depends on SECURITY!=n
+   help
+ This enables the AppArmor security module.
+ 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
+ If you are unsure how to answer this question, answer N.
--- /dev/null
+++ b/security/apparmor/Makefile
@@ -0,0 +1,13 @@
+# Makefile for AppArmor Linux Security Module
+#
+obj-$(CONFIG_SECURITY_APPARMOR) += apparmor.o
+
+apparmor-y := main.o list.o procattr.o lsm.o apparmorfs.o \
+ module_interface.o match.o
+
+quiet_cmd_make-caps = GEN $@
+cmd_make-caps = sed -n -e /CAP_FS_MASK/d -e s/^\#define[ 
\\t]\\+CAP_\\([A-Z0-9_]\\+\\)[ \\t]\\+\\([0-9]\\+\\)\$$/[\\2]  = \\\1\,/p $ 
| tr A-Z a-z  $@
+
+$(obj)/main.o : $(obj)/capability_names.h
+$(obj)/capability_names.h : $(srctree)/include/linux/capability.h
+   $(call cmd,make-caps)
--- /dev/null
+++ b/security/apparmor/apparmor.h
@@ -0,0 +1,323 @@
+/*
+ * Copyright (C) 1998-2007 Novell/SUSE
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, version 2 of the
+ * License.
+ *
+ * AppArmor internal prototypes
+ */
+
+#ifndef __APPARMOR_H
+#define __APPARMOR_H
+
+#include linux/sched.h
+#include linux/fs.h
+#include linux/binfmts.h
+#include linux/rcupdate.h
+
+/*
+ * We use MAY_READ, MAY_WRITE, MAY_EXEC, MAY_APPEND and the following flags
+ * for profile permissions
+ */
+#define AA_MAY_LINK0x0010
+#define AA_MAY_LOCK0x0020
+#define AA_EXEC_MMAP   0x0040
+#define AA_EXEC_UNSAFE 0x0080
+#define AA_EXEC_MOD_0  0x0100
+#define AA_EXEC_MOD_1  0x0200
+#define AA_BASE_PERMS  (MAY_READ | MAY_WRITE | MAY_EXEC | \
+MAY_APPEND | AA_MAY_LINK | \
+AA_MAY_LOCK | AA_EXEC_MMAP | \
+AA_EXEC_UNSAFE | AA_EXEC_MOD_0 | \
+AA_EXEC_MOD_1)
+#define AA_LINK_SUBSET_TEST0x0020
+
+#define AA_EXEC_UNCONFINED 0
+#define AA_EXEC_INHERITAA_EXEC_MOD_0
+#define AA_EXEC_PROFILEAA_EXEC_MOD_1
+#define AA_EXEC_PIX(AA_EXEC_MOD_0 | AA_EXEC_MOD_1)
+
+#define AA_EXEC_MODIFIERS  (AA_EXEC_MOD_0 | AA_EXEC_MOD_1)
+
+#define AA_USER_SHIFT  0
+#define AA_OTHER_SHIFT 10
+
+#define AA_USER_PERMS  (AA_BASE_PERMS  AA_USER_SHIFT)
+#define AA_OTHER_PERMS (AA_BASE_PERMS  AA_OTHER_SHIFT)
+
+#define AA_FILE_PERMS  (AA_USER_PERMS | AA_OTHER_PERMS)
+
+#define AA_LINK_BITS   ((AA_MAY_LINK  AA_USER_SHIFT) | \
+(AA_MAY_LINK  AA_OTHER_SHIFT))
+
+#define AA_USER_EXEC   (MAY_EXEC  AA_USER_SHIFT)
+#define AA_OTHER_EXEC  (MAY_EXEC  AA_OTHER_SHIFT)
+
+#define AA_USER_EXEC_MODS  (AA_EXEC_MODIFIERS  AA_USER_SHIFT)
+#define AA_OTHER_EXEC_MODS (AA_EXEC_MODIFIERS  AA_OTHER_SHIFT)
+
+#define AA_USER_EXEC_UNSAFE(AA_EXEC_UNSAFE  AA_USER_SHIFT)
+#define AA_OTHER_EXEC_UNSAFE   (AA_EXEC_UNSAFE  AA_OTHER_SHIFT)
+
+#define AA_EXEC_BITS   (AA_USER_EXEC | AA_OTHER_EXEC)
+
+#define AA_ALL_EXEC_MODS   (AA_USER_EXEC_MODS | \
+AA_OTHER_EXEC_MODS)
+
+/* shared permissions that are not duplicated in user:group:other */
+#define AA_CHANGE_PROFILE  0x4000
+
+#define AA_SHARED_PERMS(AA_CHANGE_PROFILE)
+
+#define AA_VALID_PERM_MASK (AA_FILE_PERMS | AA_SHARED_PERMS)
+

[AppArmor 45/47] Add AppArmor LSM to security/Makefile

2007-12-20 Thread John
Signed-off-by: John Johansen [EMAIL PROTECTED]
Signed-off-by: Andreas Gruenbacher [EMAIL PROTECTED]

---
 security/Kconfig  |1 +
 security/Makefile |1 +
 security/apparmor/Kconfig |   22 --
 3 files changed, 22 insertions(+), 2 deletions(-)

--- a/security/Kconfig
+++ b/security/Kconfig
@@ -105,6 +105,7 @@ config SECURITY_ROOTPLUG
 
 source security/selinux/Kconfig
 source security/smack/Kconfig
+source security/apparmor/Kconfig
 
 endmenu
 
--- a/security/Makefile
+++ b/security/Makefile
@@ -16,5 +16,6 @@ obj-$(CONFIG_SECURITY)+= security.o d
 # Must precede capability.o in order to stack properly.
 obj-$(CONFIG_SECURITY_SELINUX) += selinux/built-in.o
 obj-$(CONFIG_SECURITY_SMACK)   += commoncap.o smack/built-in.o
+obj-$(CONFIG_SECURITY_APPARMOR)+= commoncap.o apparmor/
 obj-$(CONFIG_SECURITY_CAPABILITIES)+= commoncap.o capability.o
 obj-$(CONFIG_SECURITY_ROOTPLUG)+= commoncap.o root_plug.o
--- a/security/apparmor/Kconfig
+++ b/security/apparmor/Kconfig
@@ -1,9 +1,27 @@
 config SECURITY_APPARMOR
-   tristate AppArmor support
-   depends on SECURITY!=n
+   bool AppArmor support
+   depends on SECURITY
+   select AUDIT
help
  This enables the AppArmor security module.
  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
+
  If you are unsure how to answer this question, answer N.
+
+config SECURITY_APPARMOR_BOOTPARAM_VALUE
+   int AppArmor boot parameter default value
+   depends on SECURITY_APPARMOR
+   range 0 1
+   default 1
+   help
+ This option sets the default value for the kernel parameter
+ 'apparmor', which allows AppArmor to be enabled or disabled
+  at boot.  If this option is set to 0 (zero), the AppArmor
+ kernel parameter will default to 0, disabling AppArmor at
+ bootup.  If this option is set to 1 (one), the AppArmor
+ kernel parameter will default to 1, enabling AppArmor at
+ bootup.
+
+ If you are unsure how to answer this question, answer 1.

-- 

-
To unsubscribe from this list: send the line unsubscribe 
linux-security-module in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[AppArmor 37/47] Switch to vfs_permission() in do_path_lookup()

2007-12-20 Thread John
Switch from file_permission() to vfs_permission() in do_path_lookup():
this avoids calling permission() with a NULL nameidata here.

Signed-off-by: Andreas Gruenbacher [EMAIL PROTECTED]
Signed-off-by: John Johansen [EMAIL PROTECTED]

---
 fs/namei.c |9 +++--
 1 file changed, 3 insertions(+), 6 deletions(-)

--- a/fs/namei.c
+++ b/fs/namei.c
@@ -1150,24 +1150,21 @@ static int fastcall do_path_lookup(int d
path_get(fs-pwd);
read_unlock(fs-lock);
} else {
-   struct dentry *dentry;
-
file = fget_light(dfd, fput_needed);
retval = -EBADF;
if (!file)
goto out_fail;
 
-   dentry = file-f_path.dentry;
+   nd-path = file-f_path;
 
retval = -ENOTDIR;
-   if (!S_ISDIR(dentry-d_inode-i_mode))
+   if (!S_ISDIR(nd-path.dentry-d_inode-i_mode))
goto fput_fail;
 
-   retval = file_permission(file, MAY_EXEC);
+   retval = vfs_permission(nd, MAY_EXEC);
if (retval)
goto fput_fail;
 
-   nd-path = file-f_path;
path_get(file-f_path);
 
fput_light(file, fput_needed);

-- 

-
To unsubscribe from this list: send the line unsubscribe 
linux-security-module in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[AppArmor 36/47] Allow permission functions to tell between parent and leaf checks

2007-12-20 Thread John
Set the LOOKUP_CONTINUE flag when checking parent permissions. This allows
permission functions to tell between parent and leaf checks.

Signed-off-by: Andreas Gruenbacher [EMAIL PROTECTED]
Signed-off-by: John Johansen [EMAIL PROTECTED]

---
 fs/namei.c |2 ++
 1 file changed, 2 insertions(+)

--- a/fs/namei.c
+++ b/fs/namei.c
@@ -1511,6 +1511,8 @@ static inline int may_create(struct inod
return -EEXIST;
if (IS_DEADDIR(dir))
return -ENOENT;
+   if (nd)
+   nd-flags |= LOOKUP_CONTINUE;
return permission(dir,MAY_WRITE | MAY_EXEC, nd);
 }
 

-- 

-
To unsubscribe from this list: send the line unsubscribe 
linux-security-module in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[AppArmor 31/47] Add d_namespace_path() to compute namespace relative pathnames

2007-12-20 Thread John
In AppArmor, we are interested in pathnames relative to the namespace root.
This is the same as d_path() except for the root where the search ends. Add
a function for computing the namespace-relative path.

Signed-off-by: Andreas Gruenbacher [EMAIL PROTECTED]
Signed-off-by: John Johansen [EMAIL PROTECTED]

---
 fs/dcache.c|4 ++--
 fs/namespace.c |   26 ++
 include/linux/dcache.h |1 +
 include/linux/mount.h  |3 +++
 4 files changed, 32 insertions(+), 2 deletions(-)

--- a/fs/dcache.c
+++ b/fs/dcache.c
@@ -1763,8 +1763,8 @@ shouldnt_be_hashed:
  *
  * Returns the buffer or an error code.
  */
-static char *__d_path(struct path *path, struct path *root,
- char *buffer, int buflen, int fail_deleted)
+char *__d_path(struct path *path, struct path *root, char *buffer, int buflen,
+  int fail_deleted)
 {
 int namelen, is_slash, vfsmount_locked = 0;
struct dentry *dentry = path-dentry;
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -26,6 +26,7 @@
 #include linux/security.h
 #include linux/mount.h
 #include linux/ramfs.h
+#include linux/path.h
 #include asm/uaccess.h
 #include asm/unistd.h
 #include pnode.h
@@ -2167,3 +2168,28 @@ void __put_mnt_ns(struct mnt_namespace *
release_mounts(umount_list);
kfree(ns);
 }
+
+char *d_namespace_path(struct path *path, char *buf, int buflen)
+{
+   struct path root = { NULL, NULL };
+   struct vfsmount *rootmnt;
+   char *res;
+
+   read_lock(current-fs-lock);
+   rootmnt = mntget(current-fs-root.mnt);
+   read_unlock(current-fs-lock);
+   spin_lock(vfsmount_lock);
+   if (rootmnt-mnt_ns)
+   root.mnt = mntget(rootmnt-mnt_ns-root);
+   spin_unlock(vfsmount_lock);
+   mntput(rootmnt);
+   if (root.mnt)
+   root.dentry = dget(root.mnt-mnt_root);
+   res = __d_path(path, root, buf, buflen, 1);
+   path_put(root);
+   /* Prevent empty path for lazily unmounted filesystems. */
+   if (!IS_ERR(res)  *res == '\0')
+   *--res = '.';
+   return res;
+}
+EXPORT_SYMBOL(d_namespace_path);
--- a/include/linux/dcache.h
+++ b/include/linux/dcache.h
@@ -302,6 +302,7 @@ extern int d_validate(struct dentry *, s
 extern char *dynamic_dname(struct dentry *, char *, int, const char *, ...);
 
 extern char *d_path(struct path *, char *, int);
+extern char *__d_path(struct path *, struct path *, char *, int, int);
 
 /* Allocation counts.. */
 
--- a/include/linux/mount.h
+++ b/include/linux/mount.h
@@ -16,6 +16,7 @@
 #include linux/list.h
 #include linux/nodemask.h
 #include linux/spinlock.h
+#include linux/path.h
 #include asm/atomic.h
 
 struct super_block;
@@ -114,5 +115,7 @@ extern void shrink_submounts(struct vfsm
 extern spinlock_t vfsmount_lock;
 extern dev_t name_to_dev_t(char *name);
 
+extern char *d_namespace_path(struct path *, char *, int);
+
 #endif
 #endif /* _LINUX_MOUNT_H */

-- 

-
To unsubscribe from this list: send the line unsubscribe 
linux-security-module in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[AppArmor 30/47] Make d_path() consistent across mount operations

2007-12-20 Thread John
The path that __d_path() computes can become slightly inconsistent when it
races with mount operations: it grabs the vfsmount_lock when traversing mount
points but immediately drops it again, only to re-grab it when it reaches the
next mount point.  The result is that the filename computed is not always
consisent, and the file may never have had that name. (This is unlikely, but
still possible.)

Fix this by grabbing the vfsmount_lock when the first mount point is reached,
and holding onto it until the d_cache lookup is completed.

Signed-off-by: Andreas Gruenbacher [EMAIL PROTECTED]
Signed-off-by: John Johansen [EMAIL PROTECTED]

---
 fs/dcache.c |   14 --
 1 file changed, 8 insertions(+), 6 deletions(-)

--- a/fs/dcache.c
+++ b/fs/dcache.c
@@ -1766,7 +1766,7 @@ shouldnt_be_hashed:
 static char *__d_path(struct path *path, struct path *root,
  char *buffer, int buflen, int fail_deleted)
 {
-   int namelen, is_slash;
+int namelen, is_slash, vfsmount_locked = 0;
struct dentry *dentry = path-dentry;
struct vfsmount *vfsmnt = path-mnt;
 
@@ -1791,14 +1791,14 @@ static char *__d_path(struct path *path,
struct dentry * parent;
 
if (dentry == vfsmnt-mnt_root || IS_ROOT(dentry)) {
-   spin_lock(vfsmount_lock);
-   if (vfsmnt-mnt_parent == vfsmnt) {
-   spin_unlock(vfsmount_lock);
-   goto global_root;
+   if (!vfsmount_locked) {
+   spin_lock(vfsmount_lock);
+   vfsmount_locked = 1;
}
+   if (vfsmnt-mnt_parent == vfsmnt)
+   goto global_root;
dentry = vfsmnt-mnt_mountpoint;
vfsmnt = vfsmnt-mnt_parent;
-   spin_unlock(vfsmount_lock);
continue;
}
parent = dentry-d_parent;
@@ -1817,6 +1817,8 @@ static char *__d_path(struct path *path,
*--buffer = '/';
 
 out:
+   if (vfsmount_locked)
+   spin_unlock(vfsmount_lock);
spin_unlock(dcache_lock);
return buffer;
 

-- 

-
To unsubscribe from this list: send the line unsubscribe 
linux-security-module in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[AppArmor 29/47] Fix __d_path() for lazy unmounts and make it unambiguous

2007-12-20 Thread John
First, when __d_path() hits a lazily unmounted mount point, it tries to prepend
the name of the lazily unmounted dentry to the path name.  It gets this wrong,
and also overwrites the slash that separates the name from the following
pathname component. This patch fixes that; if a process was in directory
/foo/bar and /foo got lazily unmounted, the old result was ``foobar'' (note the
missing slash), while the new result with this patch is ``foo/bar''.

Second, it isn't always possible to tell from the __d_path() result whether the
specified root and rootmnt (i.e., the chroot) was reached.  We need an
unambiguous result for AppArmor at least though, so we make sure that paths
will only start with a slash if the path leads all the way up to the root.

We also add a @fail_deleted argument, which allows to get rid of some of the
mess in sys_getcwd().

This patch leaves getcwd() and d_path() as they were before for everything
except for bind-mounted directories; for them, it reports ``/foo/bar'' instead
of ``foobar'' in the example described above.

Signed-off-by: Andreas Gruenbacher [EMAIL PROTECTED]
Signed-off-by: John Johansen [EMAIL PROTECTED]
Acked-by: Alan Cox [EMAIL PROTECTED]

---
 fs/dcache.c |  166 ++--
 1 file changed, 96 insertions(+), 70 deletions(-)

--- a/fs/dcache.c
+++ b/fs/dcache.c
@@ -1748,51 +1748,49 @@ shouldnt_be_hashed:
 }
 
 /**
- * d_path - return the path of a dentry
- * @dentry: dentry to report
- * @vfsmnt: vfsmnt to which the dentry belongs
- * @root: root dentry
- * @rootmnt: vfsmnt to which the root dentry belongs
+ * __d_path - return the path of a dentry
+ * @path: path to report
+ * @root: root path
  * @buffer: buffer to return value in
  * @buflen: buffer length
+ * @fail_deleted: what to return for deleted files
  *
- * Convert a dentry into an ASCII path name. If the entry has been deleted
+ * If @path is not connected to @root, the path returned will be relative
+ * (i.e., it will not start with a slash).
  * the string  (deleted) is appended. Note that this is ambiguous.
  *
  * Returns the buffer or an error code if the path was too long.
  *
- * buflen should be positive. Caller holds the dcache_lock.
+ * Returns the buffer or an error code.
  */
-static char *__d_path(struct dentry *dentry, struct vfsmount *vfsmnt,
-  struct path *root, char *buffer, int buflen)
+static char *__d_path(struct path *path, struct path *root,
+ char *buffer, int buflen, int fail_deleted)
 {
-   char * end = buffer+buflen;
-   char * retval;
-   int namelen;
+   int namelen, is_slash;
+   struct dentry *dentry = path-dentry;
+   struct vfsmount *vfsmnt = path-mnt;
+
+   if (buflen  2)
+   return ERR_PTR(-ENAMETOOLONG);
+   buffer += --buflen;
+   *buffer = '\0';
 
-   *--end = '\0';
-   buflen--;
+   spin_lock(dcache_lock);
if (!IS_ROOT(dentry)  d_unhashed(dentry)) {
-   buflen -= 10;
-   end -= 10;
-   if (buflen  0)
+   if (fail_deleted) {
+   buffer = ERR_PTR(-ENOENT);
+   goto out;
+   }
+   if (buflen  10)
goto Elong;
-   memcpy(end,  (deleted), 10);
+   buflen -= 10;
+   buffer -= 10;
+   memcpy(buffer,  (deleted), 10);
}
-
-   if (buflen  1)
-   goto Elong;
-   /* Get '/' right */
-   retval = end-1;
-   *retval = '/';
-
-   for (;;) {
+   while (dentry != root-dentry || vfsmnt != root-mnt) {
struct dentry * parent;
 
-   if (dentry == root-dentry  vfsmnt == root-mnt)
-   break;
if (dentry == vfsmnt-mnt_root || IS_ROOT(dentry)) {
-   /* Global root? */
spin_lock(vfsmount_lock);
if (vfsmnt-mnt_parent == vfsmnt) {
spin_unlock(vfsmount_lock);
@@ -1806,28 +1804,67 @@ static char *__d_path(struct dentry *den
parent = dentry-d_parent;
prefetch(parent);
namelen = dentry-d_name.len;
-   buflen -= namelen + 1;
-   if (buflen  0)
+   if (buflen  namelen + 1)
goto Elong;
-   end -= namelen;
-   memcpy(end, dentry-d_name.name, namelen);
-   *--end = '/';
-   retval = end;
+   buflen -= namelen + 1;
+   buffer -= namelen;
+   memcpy(buffer, dentry-d_name.name, namelen);
+   *--buffer = '/';
dentry = parent;
}
+   /* Get '/' right. */
+   if (*buffer != '/')
+   *--buffer = '/';
 
-   return retval;
+out:
+   spin_unlock(dcache_lock);
+   return buffer;
 
 global_root:
+   /*
+* We went 

[AppArmor 32/47] From: Miklos Szeredi [EMAIL PROTECTED]

2007-12-20 Thread John
Add a new file operation: f_op-fgetattr(), that is invoked by
fstat().  Fall back to i_op-getattr() if it is not defined.

We need this because fstat() semantics can in some cases be better
implemented if the filesystem has the open file available.

Let's take the following example: we have a network filesystem, with
the server implemented as an unprivileged userspace process running on
a UNIX system (this is basically what sshfs does).

We want the filesystem to follow the familiar UNIX file semantics as
closely as possible.  If for example we have this sequence of events,
we still would like fstat to work correctly:

 1) file X is opened on client
 2) file X is renamed to Y on server
 3) fstat() is performed on open file descriptor on client

This is only possible if the filesystem server acutally uses fstat()
on a file descriptor obtained when the file was opened.  Which means,
the filesystem client needs a way to get this information from the
VFS.

Even if we assume, that the remote filesystem never changes, it is
difficult to implement open-unlink-fstat semantics correctly in the
client, without having this information.

Signed-off-by: Miklos Szeredi [EMAIL PROTECTED]
Signed-off-by: John Johansen [EMAIL PROTECTED]

---

---
 fs/fuse/file.c |   13 +
 fs/stat.c  |   29 -
 include/linux/fs.h |1 +
 3 files changed, 42 insertions(+), 1 deletion(-)

--- a/fs/fuse/file.c
+++ b/fs/fuse/file.c
@@ -871,6 +871,17 @@ static int fuse_file_flock(struct file *
return err;
 }
 
+static int fuse_file_fgetattr(struct file *file, struct kstat *stat)
+{
+   struct inode *inode = file-f_dentry-d_inode;
+   struct fuse_conn *fc = get_fuse_conn(inode);
+
+   if (!fuse_allow_task(fc, current))
+   return -EACCES;
+
+   return fuse_update_attributes(inode, stat, file, NULL);
+}
+
 static sector_t fuse_bmap(struct address_space *mapping, sector_t block)
 {
struct inode *inode = mapping-host;
@@ -920,6 +931,7 @@ static const struct file_operations fuse
.fsync  = fuse_fsync,
.lock   = fuse_file_lock,
.flock  = fuse_file_flock,
+   .fgetattr   = fuse_file_fgetattr,
.splice_read= generic_file_splice_read,
 };
 
@@ -933,6 +945,7 @@ static const struct file_operations fuse
.fsync  = fuse_fsync,
.lock   = fuse_file_lock,
.flock  = fuse_file_flock,
+   .fgetattr   = fuse_file_fgetattr,
/* no mmap and splice_read */
 };
 
--- a/fs/stat.c
+++ b/fs/stat.c
@@ -55,6 +55,33 @@ int vfs_getattr(struct vfsmount *mnt, st
 
 EXPORT_SYMBOL(vfs_getattr);
 
+/*
+ * Perform getattr on an open file
+ *
+ * Fall back to i_op-getattr (or generic_fillattr) if the filesystem
+ * doesn't define an f_op-fgetattr operation.
+ */
+static int vfs_fgetattr(struct file *file, struct kstat *stat)
+{
+   struct vfsmount *mnt = file-f_path.mnt;
+   struct dentry *dentry = file-f_path.dentry;
+   struct inode *inode = dentry-d_inode;
+   int retval;
+
+   retval = security_inode_getattr(mnt, dentry);
+   if (retval)
+   return retval;
+
+   if (file-f_op  file-f_op-fgetattr) {
+   return file-f_op-fgetattr(file, stat);
+   } else if (inode-i_op-getattr) {
+   return inode-i_op-getattr(mnt, dentry, stat);
+   } else {
+   generic_fillattr(inode, stat);
+   return 0;
+   }
+}
+
 int vfs_stat_fd(int dfd, char __user *name, struct kstat *stat)
 {
struct nameidata nd;
@@ -101,7 +128,7 @@ int vfs_fstat(unsigned int fd, struct ks
int error = -EBADF;
 
if (f) {
-   error = vfs_getattr(f-f_path.mnt, f-f_path.dentry, stat);
+   error = vfs_fgetattr(f, stat);
fput(f);
}
return error;
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -1190,6 +1190,7 @@ struct file_operations {
ssize_t (*splice_write)(struct pipe_inode_info *, struct file *, loff_t 
*, size_t, unsigned int);
ssize_t (*splice_read)(struct file *, loff_t *, struct pipe_inode_info 
*, size_t, unsigned int);
int (*setlease)(struct file *, long, struct file_lock **);
+   int (*fgetattr)(struct file *, struct kstat *);
 };
 
 struct inode_operations {

-- 

-
To unsubscribe from this list: send the line unsubscribe 
linux-security-module in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[AppArmor 38/47] Switch to vfs_permission() in sys_fchdir()

2007-12-20 Thread John
Switch from file_permission() to vfs_permission() in sys_fchdir(): this
avoids calling permission() with a NULL nameidata here.

Signed-off-by: Andreas Gruenbacher [EMAIL PROTECTED]
Signed-off-by: John Johansen [EMAIL PROTECTED]

---
 fs/open.c |   11 ++-
 1 file changed, 6 insertions(+), 5 deletions(-)

--- a/fs/open.c
+++ b/fs/open.c
@@ -512,8 +512,8 @@ out:
 
 asmlinkage long sys_fchdir(unsigned int fd)
 {
+   struct nameidata nd;
struct file *file;
-   struct inode *inode;
int error;
 
error = -EBADF;
@@ -521,15 +521,16 @@ asmlinkage long sys_fchdir(unsigned int 
if (!file)
goto out;
 
-   inode = file-f_path.dentry-d_inode;
+   nd.path = file-f_path;
+   nd.flags = 0;
 
error = -ENOTDIR;
-   if (!S_ISDIR(inode-i_mode))
+   if (!S_ISDIR(nd.path.dentry-d_inode-i_mode))
goto out_putf;
 
-   error = file_permission(file, MAY_EXEC);
+   error = vfs_permission(nd, MAY_EXEC);
if (!error)
-   set_fs_pwd(current-fs, file-f_path);
+   set_fs_pwd(current-fs, nd.path);
 out_putf:
fput(file);
 out:

-- 

-
To unsubscribe from this list: send the line unsubscribe 
linux-security-module in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [patch, rfc] mm.h, security.h, key.h and preventing namespace poisoning

2007-12-20 Thread Eric Paris

On Thu, 2007-12-20 at 11:07 +1100, James Morris wrote:
 On Wed, 19 Dec 2007, David Chinner wrote:
 
  Folks,
  
  I just updated a git tree and started getting errors on a
  copy_keys macro warning.
  
  The code I've been working on uses a -copy_keys() method for
  copying the keys in a btree block from one place to another. I've
  been working on this code for a while
  (http://oss.sgi.com/archives/xfs/2007-11/msg00046.html) and keep the
  tree I'm working in reletively up to date (lags linus by a couple of
  weeks at most). The update I did this afternoon gave a conflict
  warning with the macro in include/linux/key.h.
  
  Given that I'm not directly including key.h anywhere in the XFS
  code, I'm getting the namespace polluted indirectly from some other
  include that is necessary.
  
  As it turns out, this commit from 13 days ago:
  
  http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=7cd94146cd504016315608e297219f9fb7b1413b
  
  included security.h in mm.h and that is how I'm seeing the namespace
  poisoning coming from key.h when !CONFIG_KEY.
  
  Including security.h in mm.h means much wider includes for pretty
  much the entire kernel, and it opens up namespace issues like this
  that never previously existed.
  
  The patch below (only tested for !CONFIG_KEYS  !CONFIG_SECURITY)
  moves security.h into the mmap.c and nommu.c files that need it so
  it doesn't end up with kernel wide scope.
  
  Comments?
 
 The idea with this placement was to keep memory management code with other 
 similar code, rather than pushing it into security.h, where it does not 
 functionally belong.
 
 Something to not also is that you can't depend on security.h not being 
 included all over the place, as LSM does touch a lot of the kernel.  
 Unecessarily including it is bad, of course.
 
 I'm not sure I understand your namespace pollution issue, either.
 
 In any case, I think the right solution is not to include security.h at 
 all in mm.h, as it is only being done to get a declaration for 
 mmap_min_addr.
 
 How about this, instead ?
 
 Signed-off-by: James Morris [EMAIL PROTECTED]
Acked-by: Eric Paris [EMAIL PROTECTED]
 ---
 
  mm.h |5 -
  1 file changed, 4 insertions(+), 1 deletion(-)
 
 diff --git a/include/linux/mm.h b/include/linux/mm.h
 index 1b7b95c..02fbac7 100644
 --- a/include/linux/mm.h
 +++ b/include/linux/mm.h
 @@ -12,7 +12,6 @@
  #include linux/prio_tree.h
  #include linux/debug_locks.h
  #include linux/mm_types.h
 -#include linux/security.h
  
  struct mempolicy;
  struct anon_vma;
 @@ -34,6 +33,10 @@ extern int sysctl_legacy_va_layout;
  #define sysctl_legacy_va_layout 0
  #endif
  
 +#ifdef CONFIG_SECURITY
 +extern unsigned long mmap_min_addr;
 +#endif
 +
  #include asm/page.h
  #include asm/pgtable.h
  #include asm/processor.h
 
 

-
To unsubscribe from this list: send the line unsubscribe 
linux-security-module in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 10/28] FS-Cache: Recruit a couple of page flags for cache management [try #2]

2007-12-20 Thread David Howells
Nick Piggin [EMAIL PROTECTED] wrote:

   I'd much prefer if you would handle this in the filesystem, and have it
   set PG_private whenever fscache needs to receive a callback, and DTRT
   depending on whether PG_fscache etc. is set or not.
 
  That's tricky and slower[*].  One of the things I want to do is to modify
  iso9660 to do be able to do caching, but PG_private is 'owned' by the
  generic buffer cache code.
 
 Maybe it is harder, but it is the right way to do it.

You're wrong.  It would mean that PG_private is the logical disjunction of
PG_fscache and some condition not otherwise explicitly stored.  I tried that
with NFS and it was nasty.

As you can no doubt see, it means that you can't distinguish all the states
you used to be able to.

 So you should modify the filesystems rather than core code.

I think you missed what I said:

but PG_private is 'owned' by the generic buffer cache code.

That means more of the core code would have to change - or, at least, change
more.

David
-
To unsubscribe from this list: send the line unsubscribe 
linux-security-module in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html