Merge master.kernel.org:/pub/scm/linux/kernel/git/dwmw2/audit-2.6
authorLinus Torvalds <torvalds@g5.osdl.org>
Tue, 13 Sep 2005 16:47:30 +0000 (09:47 -0700)
committerLinus Torvalds <torvalds@g5.osdl.org>
Tue, 13 Sep 2005 16:47:30 +0000 (09:47 -0700)
1  2 
MAINTAINERS
arch/ppc64/kernel/asm-offsets.c
arch/ppc64/kernel/entry.S
fs/namei.c
kernel/audit.c
security/selinux/avc.c
security/selinux/hooks.c
security/selinux/ss/services.c

diff --combined MAINTAINERS
index a67bf7d315d7ee14923789fc66eb08649178f4ce,1c5a8a5e65048968ac4b8702c9d1a56bac9899b2..d1e0eb46d201fb8574625f587159fe991ff6e609
@@@ -116,12 -116,6 +116,12 @@@ M:       ajk@iehk.rwth-aachen.d
  L:    linux-hams@vger.kernel.org
  S:    Maintained
  
 +YEALINK PHONE DRIVER
 +P:    Henk Vergonet
 +M:    Henk.Vergonet@gmail.com
 +L:    usbb2k-api-dev@nongnu.org
 +S:    Maintained
 +
  8139CP 10/100 FAST ETHERNET DRIVER
  P:    Jeff Garzik
  M:    jgarzik@pobox.com
@@@ -208,6 -202,13 +208,6 @@@ P:        Colin Lero
  M:    colin@colino.net
  S:    Maintained
  
 -ADVANSYS SCSI DRIVER
 -P:    Bob Frey
 -M:    linux@advansys.com
 -W:    http://www.advansys.com/linux.html
 -L:    linux-scsi@vger.kernel.org
 -S:    Maintained
 -
  AEDSP16 DRIVER
  P:    Riccardo Facchetti
  M:    fizban@tin.it
@@@ -370,7 -371,10 +370,10 @@@ W:       http://atmelwlandriver.sourceforge.n
  S:    Maintained
  
  AUDIT SUBSYSTEM
- L:    linux-audit@redhat.com (subscribers-only)
+ P:    David Woodhouse
+ M:    dwmw2@infradead.org
+ L:    linux-audit@redhat.com
+ W:    http://people.redhat.com/sgrubb/audit/
  S:    Maintained
  
  AX.25 NETWORK LAYER
@@@ -626,12 -630,6 +629,12 @@@ M:       rmk@arm.linux.org.u
  W:    http://www.arm.linux.org.uk/
  S:    Maintained
  
 +CYBLAFB FRAMEBUFFER DRIVER
 +P:    Knut Petersen
 +M:    Knut_Petersen@t-online.de
 +L:    linux-fbdev-devel@lists.sourceforge.net
 +S:    Maintained
 +
  CYCLADES 2X SYNC CARD DRIVER
  P:    Arnaldo Carvalho de Melo
  M:    acme@conectiva.com.br
@@@ -701,11 -699,6 +704,11 @@@ M:       dz@debian.or
  W:    http://www.debian.org/~dz/i8k/
  S:    Maintained
  
 +DELL SYSTEMS MANAGEMENT BASE DRIVER (dcdbas)
 +P:    Doug Warzecha
 +M:    Douglas_Warzecha@dell.com
 +S:    Maintained
 +
  DEVICE-MAPPER
  P:    Alasdair Kergon
  L:    dm-devel@redhat.com
@@@ -834,13 -827,6 +837,13 @@@ L:       emu10k1-devel@lists.sourceforge.ne
  W:    http://sourceforge.net/projects/emu10k1/
  S:    Maintained
  
 +EMULEX LPFC FC SCSI DRIVER
 +P:      James Smart
 +M:      james.smart@emulex.com
 +L:      linux-scsi@vger.kernel.org
 +W:      http://sourceforge.net/projects/lpfcxxxx
 +S:      Supported
 +
  EPSON 1355 FRAMEBUFFER DRIVER
  P:    Christopher Hoover
  M:    ch@murgatroid.com, ch@hpl.hp.com
@@@ -896,7 -882,7 +899,7 @@@ S: Maintaine
  
  FILESYSTEMS (VFS and infrastructure)
  P:    Alexander Viro
 -M:    viro@parcelfarce.linux.theplanet.co.uk
 +M:    viro@zeniv.linux.org.uk
  S:    Maintained
  
  FIRMWARE LOADER (request_firmware)
@@@ -931,13 -917,6 +934,13 @@@ L:       linux-tape@vger.kernel.or
  W:    http://sourceforge.net/projects/ftape
  S:    Orphan
  
 +FUSE: FILESYSTEM IN USERSPACE
 +P:    Miklos Szeredi
 +M:    miklos@szeredi.hu
 +L:    fuse-devel@lists.sourceforge.net
 +W:    http://fuse.sourceforge.net/
 +S:    Maintained
 +
  FUTURE DOMAIN TMC-16x0 SCSI DRIVER (16-bit)
  P:    Rik Faith
  M:    faith@cs.unc.edu
@@@ -957,20 -936,6 +960,20 @@@ M:       khc@pm.waw.p
  W:    http://www.kernel.org/pub/linux/utils/net/hdlc/
  S:    Maintained
  
 +HARDWARE MONITORING
 +P:    Jean Delvare
 +M:    khali@linux-fr.org
 +L:    lm-sensors@lm-sensors.org
 +W:    http://www.lm-sensors.nu/
 +S:    Maintained
 +
 +HARD DRIVE ACTIVE PROTECTION SYSTEM (HDAPS) DRIVER
 +P:    Robert Love
 +M:    rlove@rlove.org
 +M:    linux-kernel@vger.kernel.org
 +W:    http://www.kernel.org/pub/linux/kernel/people/rml/hdaps/
 +S:    Maintained
 +
  HARMONY SOUND DRIVER
  P:    Kyle McMartin
  M:    kyle@parisc-linux.org
@@@ -1029,13 -994,6 +1032,13 @@@ M:     mike.miller@hp.co
  L:    iss_storagedev@hp.com
  S:    Supported
   
 +HOST AP DRIVER
 +P:    Jouni Malinen
 +M:    jkmaline@cc.hut.fi
 +L:    hostap@shmoo.com
 +W:    http://hostap.epitest.fi/
 +S:    Maintained
 +
  HP100:        Driver for HP 10/100 Mbit/s Voice Grade Network Adapter Series
  P:    Jaroslav Kysela
  M:    perex@suse.cz
@@@ -1052,7 -1010,7 +1055,7 @@@ P:      William Irwi
  M:    wli@holomorphy.com
  S:    Maintained
  
 -I2C AND SENSORS DRIVERS
 +I2C SUBSYSTEM
  P:    Greg Kroah-Hartman
  M:    greg@kroah.com
  P:    Jean Delvare
@@@ -1839,6 -1797,13 +1842,6 @@@ M:     hch@infradead.or
  L:    linux-abi-devel@lists.sourceforge.net
  S:    Maintained
  
 -PCI ID DATABASE
 -P:    Martin Mares
 -M:    mj@ucw.cz
 -L:    pciids-devel@lists.sourceforge.net
 -W:    http://pciids.sourceforge.net/
 -S:    Maintained
 -
  PCI SOUND DRIVERS (ES1370, ES1371 and SONICVIBES)
  P:    Thomas Sailer
  M:    sailer@ife.ee.ethz.ch
@@@ -1991,6 -1956,7 +1994,6 @@@ S:      Supporte
  
  ROCKETPORT DRIVER
  P:    Comtrol Corp.
 -M:    support@comtrol.com
  W:    http://www.comtrol.com
  S:    Maintained
  
@@@ -2129,12 -2095,6 +2132,12 @@@ M:    support@simtec.co.u
  W:    http://www.simtec.co.uk/products/EB2410ITX/
  S:    Supported
  
 +SIS 190 ETHERNET DRIVER
 +P:    Francois Romieu
 +M:    romieu@fr.zoreil.com
 +L:    netdev@vger.kernel.org
 +S:    Maintained
 +
  SIS 5513 IDE CONTROLLER DRIVER
  P:    Lionel Bouton
  M:    Lionel.Bouton@inet6.fr
@@@ -2680,6 -2640,11 +2683,6 @@@ S:     Maintaine
  UCLINUX (AND M68KNOMMU)
  P:    Greg Ungerer
  M:    gerg@uclinux.org
 -M:    gerg@snapgear.com
 -P:    David McCullough
 -M:    davidm@snapgear.com
 -P:    D. Jeff Dionne (created first uClinux port)
 -M:    jeff@uclinux.org
  W:    http://www.uclinux.org/
  L:    uclinux-dev@uclinux.org  (subscribers-only)
  S:    Maintained
@@@ -2704,17 -2669,6 +2707,17 @@@ L:    rio500-users@lists.sourceforge.ne
  W:    http://rio500.sourceforge.net
  S:    Maintained
  
 +V9FS FILE SYSTEM
 +P:      Eric Van Hensbergen
 +M:      ericvh@gmail.com
 +P:      Ron Minnich
 +M:      rminnich@lanl.gov
 +P:      Latchesar Ionkov
 +M:      lucho@ionkov.net
 +L:      v9fs-developer@lists.sourceforge.net
 +W:      http://v9fs.sf.net
 +S:      Maintained
 +
  VIDEO FOR LINUX
  P:    Mauro Carvalho Chehab
  M:    mchehab@brturbo.com.br
index 17e35d0fed09ff87d7eeb0d49e30b02d8e9f139d,6f910fa2746f090eed0cbfd73c4348e10f29e7eb..1ff4fa05a97329f1a7c5217a7e8737f6f49421e5
@@@ -68,6 -68,7 +68,7 @@@ int main(void
        DEFINE(THREAD_USED_VR, offsetof(struct thread_struct, used_vr));
  #endif /* CONFIG_ALTIVEC */
        DEFINE(MM, offsetof(struct task_struct, mm));
+       DEFINE(AUDITCONTEXT, offsetof(struct task_struct, audit_context));
  
        DEFINE(DCACHEL1LINESIZE, offsetof(struct ppc64_caches, dline_size));
        DEFINE(DCACHEL1LOGLINESIZE, offsetof(struct ppc64_caches, log_dline_size));
@@@ -94,8 -95,7 +95,8 @@@
        DEFINE(PACASLBCACHEPTR, offsetof(struct paca_struct, slb_cache_ptr));
        DEFINE(PACACONTEXTID, offsetof(struct paca_struct, context.id));
  #ifdef CONFIG_HUGETLB_PAGE
 -      DEFINE(PACAHTLBSEGS, offsetof(struct paca_struct, context.htlb_segs));
 +      DEFINE(PACALOWHTLBAREAS, offsetof(struct paca_struct, context.low_htlb_areas));
 +      DEFINE(PACAHIGHHTLBAREAS, offsetof(struct paca_struct, context.high_htlb_areas));
  #endif /* CONFIG_HUGETLB_PAGE */
        DEFINE(PACADEFAULTDECR, offsetof(struct paca_struct, default_decr));
          DEFINE(PACA_EXGEN, offsetof(struct paca_struct, exgen));
index d133a49cdf8972270fcd1f668f1d43cbea1a6766,14cd56ac40dd706d15f3cdd6f6ea922ca15490a6..e8c0bbf4d000353c176b55d4da7c36b628b19b65
@@@ -28,7 -28,7 +28,7 @@@
  #include <asm/mmu.h>
  #include <asm/thread_info.h>
  #include <asm/ppc_asm.h>
 -#include <asm/offsets.h>
 +#include <asm/asm-offsets.h>
  #include <asm/cputable.h>
  
  #ifdef CONFIG_PPC_ISERIES
@@@ -276,12 -276,22 +276,22 @@@ _GLOBAL(ppc64_rt_sigsuspend
  _GLOBAL(ppc32_rt_sigsuspend)
        bl      .save_nvgprs
        bl      .sys32_rt_sigsuspend
-       /* If sigsuspend() returns zero, we are going into a signal handler */
  70:   cmpdi   0,r3,0
-       beq     .ret_from_except
-       /* If it returned -EINTR, we need to return via syscall_exit to set
+       /* If it returned an error, we need to return via syscall_exit to set
           the SO bit in cr0 and potentially stop for ptrace. */
-       b       syscall_exit
+       bne     syscall_exit
+       /* If sigsuspend() returns zero, we are going into a signal handler. We
+          may need to call audit_syscall_exit() to mark the exit from sigsuspend() */
+ #ifdef CONFIG_AUDIT
+       ld      r3,PACACURRENT(r13)
+       ld      r4,AUDITCONTEXT(r3)
+       cmpdi   0,r4,0
+       beq     .ret_from_except        /* No audit_context: Leave immediately. */
+       li      r4, 2                   /* AUDITSC_FAILURE */
+       li      r5,-4                   /* It's always -EINTR */
+       bl      .audit_syscall_exit
+ #endif
+       b       .ret_from_except
  
  _GLOBAL(ppc_fork)
        bl      .save_nvgprs
@@@ -400,14 -410,15 +410,14 @@@ BEGIN_FTR_SECTIO
        cmpd    cr1,r6,r9       /* or is new ESID the same as current ESID? */
        cror    eq,4*cr1+eq,eq
        beq     2f              /* if yes, don't slbie it */
 -      oris    r0,r6,0x0800    /* set C (class) bit */
  
        /* Bolt in the new stack SLB entry */
        ld      r7,KSP_VSID(r4) /* Get new stack's VSID */
 -      oris    r6,r6,(SLB_ESID_V)@h
 -      ori     r6,r6,(SLB_NUM_BOLTED-1)@l
 -      slbie   r0
 -      slbie   r0              /* Workaround POWER5 < DD2.1 issue */
 -      slbmte  r7,r6
 +      oris    r0,r6,(SLB_ESID_V)@h
 +      ori     r0,r0,(SLB_NUM_BOLTED-1)@l
 +      slbie   r6
 +      slbie   r6              /* Workaround POWER5 < DD2.1 issue */
 +      slbmte  r7,r0
        isync
  
  2:
diff --combined fs/namei.c
index 21d85f1ac8395f82376e2dd5073494d568080e78,91ce1f24bbb635b8d7922541be0df37419c203eb..043d587216b5a3f3354a75878827df61956facc4
@@@ -525,22 -525,6 +525,22 @@@ static inline int __do_follow_link(stru
        return error;
  }
  
 +static inline void dput_path(struct path *path, struct nameidata *nd)
 +{
 +      dput(path->dentry);
 +      if (path->mnt != nd->mnt)
 +              mntput(path->mnt);
 +}
 +
 +static inline void path_to_nameidata(struct path *path, struct nameidata *nd)
 +{
 +      dput(nd->dentry);
 +      if (nd->mnt != path->mnt)
 +              mntput(nd->mnt);
 +      nd->mnt = path->mnt;
 +      nd->dentry = path->dentry;
 +}
 +
  /*
   * This limits recursive symlink follows to 8, while
   * limiting consecutive symlinks to 40.
@@@ -568,7 -552,9 +568,7 @@@ static inline int do_follow_link(struc
        nd->depth--;
        return err;
  loop:
 -      dput(path->dentry);
 -      if (path->mnt != nd->mnt)
 -              mntput(path->mnt);
 +      dput_path(path, nd);
        path_release(nd);
        return err;
  }
@@@ -827,8 -813,13 +827,8 @@@ static fastcall int __link_path_walk(co
                        err = -ENOTDIR; 
                        if (!inode->i_op)
                                break;
 -              } else {
 -                      dput(nd->dentry);
 -                      if (nd->mnt != next.mnt)
 -                              mntput(nd->mnt);
 -                      nd->mnt = next.mnt;
 -                      nd->dentry = next.dentry;
 -              }
 +              } else
 +                      path_to_nameidata(&next, nd);
                err = -ENOTDIR; 
                if (!inode->i_op->lookup)
                        break;
@@@ -868,8 -859,13 +868,8 @@@ last_component
                        if (err)
                                goto return_err;
                        inode = nd->dentry->d_inode;
 -              } else {
 -                      dput(nd->dentry);
 -                      if (nd->mnt != next.mnt)
 -                              mntput(nd->mnt);
 -                      nd->mnt = next.mnt;
 -                      nd->dentry = next.dentry;
 -              }
 +              } else
 +                      path_to_nameidata(&next, nd);
                err = -ENOENT;
                if (!inode)
                        break;
@@@ -905,7 -901,9 +905,7 @@@ return_reval
  return_base:
                return 0;
  out_dput:
 -              dput(next.dentry);
 -              if (nd->mnt != next.mnt)
 -                      mntput(next.mnt);
 +              dput_path(&next, nd);
                break;
        }
        path_release(nd);
@@@ -1048,7 -1046,7 +1048,7 @@@ int fastcall path_lookup(const char *na
  out:
        if (unlikely(current->audit_context
                     && nd && nd->dentry && nd->dentry->d_inode))
-               audit_inode(name, nd->dentry->d_inode);
+               audit_inode(name, nd->dentry->d_inode, flags);
        return retval;
  }
  
@@@ -1316,8 -1314,10 +1316,8 @@@ int vfs_create(struct inode *dir, struc
                return error;
        DQUOT_INIT(dir);
        error = dir->i_op->create(dir, dentry, mode, nd);
 -      if (!error) {
 +      if (!error)
                fsnotify_create(dir, dentry->d_name.name);
 -              security_inode_post_create(dir, dentry, mode);
 -      }
        return error;
  }
  
@@@ -1507,7 -1507,11 +1507,7 @@@ do_last
        if (path.dentry->d_inode->i_op && path.dentry->d_inode->i_op->follow_link)
                goto do_link;
  
 -      dput(nd->dentry);
 -      nd->dentry = path.dentry;
 -      if (nd->mnt != path.mnt)
 -              mntput(nd->mnt);
 -      nd->mnt = path.mnt;
 +      path_to_nameidata(&path, nd);
        error = -EISDIR;
        if (path.dentry->d_inode && S_ISDIR(path.dentry->d_inode->i_mode))
                goto exit;
@@@ -1518,7 -1522,9 +1518,7 @@@ ok
        return 0;
  
  exit_dput:
 -      dput(path.dentry);
 -      if (nd->mnt != path.mnt)
 -              mntput(path.mnt);
 +      dput_path(&path, nd);
  exit:
        path_release(nd);
        return error;
@@@ -1633,8 -1639,10 +1633,8 @@@ int vfs_mknod(struct inode *dir, struc
  
        DQUOT_INIT(dir);
        error = dir->i_op->mknod(dir, dentry, mode, dev);
 -      if (!error) {
 +      if (!error)
                fsnotify_create(dir, dentry->d_name.name);
 -              security_inode_post_mknod(dir, dentry, mode, dev);
 -      }
        return error;
  }
  
@@@ -1704,8 -1712,10 +1704,8 @@@ int vfs_mkdir(struct inode *dir, struc
  
        DQUOT_INIT(dir);
        error = dir->i_op->mkdir(dir, dentry, mode);
 -      if (!error) {
 +      if (!error)
                fsnotify_mkdir(dir, dentry->d_name.name);
 -              security_inode_post_mkdir(dir,dentry, mode);
 -      }
        return error;
  }
  
@@@ -1941,8 -1951,10 +1941,8 @@@ int vfs_symlink(struct inode *dir, stru
  
        DQUOT_INIT(dir);
        error = dir->i_op->symlink(dir, dentry, oldname);
 -      if (!error) {
 +      if (!error)
                fsnotify_create(dir, dentry->d_name.name);
 -              security_inode_post_symlink(dir, dentry, oldname);
 -      }
        return error;
  }
  
@@@ -2012,8 -2024,10 +2012,8 @@@ int vfs_link(struct dentry *old_dentry
        DQUOT_INIT(dir);
        error = dir->i_op->link(old_dentry, dir, new_dentry);
        up(&old_dentry->d_inode->i_sem);
 -      if (!error) {
 +      if (!error)
                fsnotify_create(dir, new_dentry->d_name.name);
 -              security_inode_post_link(old_dentry, dir, new_dentry);
 -      }
        return error;
  }
  
@@@ -2132,8 -2146,11 +2132,8 @@@ static int vfs_rename_dir(struct inode 
                        d_rehash(new_dentry);
                dput(new_dentry);
        }
 -      if (!error) {
 +      if (!error)
                d_move(old_dentry,new_dentry);
 -              security_inode_post_rename(old_dir, old_dentry,
 -                                         new_dir, new_dentry);
 -      }
        return error;
  }
  
@@@ -2159,6 -2176,7 +2159,6 @@@ static int vfs_rename_other(struct inod
                /* The following d_move() should become unconditional */
                if (!(old_dir->i_sb->s_type->fs_flags & FS_ODD_RENAME))
                        d_move(old_dentry, new_dentry);
 -              security_inode_post_rename(old_dir, old_dentry, new_dir, new_dentry);
        }
        if (target)
                up(&target->i_sem);
diff --combined kernel/audit.c
index 7f0699790d469ce218ff4ec91967608275871fb7,8376ec10cf2468848d355b6f4c14a252a102b623..83096b67510aea1e6c40147a9b1f2b73752218b5
@@@ -79,6 -79,8 +79,8 @@@ static int    audit_rate_limit
  
  /* Number of outstanding audit_buffers allowed. */
  static int    audit_backlog_limit = 64;
+ static int    audit_backlog_wait_time = 60 * HZ;
+ static int    audit_backlog_wait_overflow = 0;
  
  /* The identity of the user shutting down the audit system. */
  uid_t         audit_sig_uid = -1;
@@@ -106,18 -108,12 +108,12 @@@ static LIST_HEAD(audit_freelist)
  static struct sk_buff_head audit_skb_queue;
  static struct task_struct *kauditd_task;
  static DECLARE_WAIT_QUEUE_HEAD(kauditd_wait);
- /* There are three lists of rules -- one to search at task creation
-  * time, one to search at syscall entry time, and another to search at
-  * syscall exit time. */
- static LIST_HEAD(audit_tsklist);
- static LIST_HEAD(audit_entlist);
- static LIST_HEAD(audit_extlist);
+ static DECLARE_WAIT_QUEUE_HEAD(audit_backlog_wait);
  
  /* The netlink socket is only to be read by 1 CPU, which lets us assume
   * that list additions and deletions never happen simultaneously in
   * auditsc.c */
static DECLARE_MUTEX(audit_netlink_sem);
+ DECLARE_MUTEX(audit_netlink_sem);
  
  /* AUDIT_BUFSIZ is the size of the temporary buffer used for formatting
   * audit records.  Since printk uses a 1024 byte buffer, this buffer
@@@ -137,6 -133,7 +133,7 @@@ struct audit_buffer 
        struct list_head     list;
        struct sk_buff       *skb;      /* formatted skb ready to send */
        struct audit_context *ctx;      /* NULL or associated context */
+       int                  gfp_mask;
  };
  
  static void audit_set_pid(struct audit_buffer *ab, pid_t pid)
        nlh->nlmsg_pid = pid;
  }
  
- struct audit_entry {
-       struct list_head  list;
-       struct audit_rule rule;
- };
  static void audit_panic(const char *message)
  {
        switch (audit_failure)
@@@ -233,7 -225,7 +225,7 @@@ static int audit_set_rate_limit(int lim
  {
        int old          = audit_rate_limit;
        audit_rate_limit = limit;
-       audit_log(NULL, AUDIT_CONFIG_CHANGE, 
+       audit_log(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE, 
                        "audit_rate_limit=%d old=%d by auid=%u",
                        audit_rate_limit, old, loginuid);
        return old;
@@@ -243,7 -235,7 +235,7 @@@ static int audit_set_backlog_limit(int 
  {
        int old          = audit_backlog_limit;
        audit_backlog_limit = limit;
-       audit_log(NULL, AUDIT_CONFIG_CHANGE,
+       audit_log(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE,
                        "audit_backlog_limit=%d old=%d by auid=%u",
                        audit_backlog_limit, old, loginuid);
        return old;
@@@ -255,7 -247,7 +247,7 @@@ static int audit_set_enabled(int state
        if (state != 0 && state != 1)
                return -EINVAL;
        audit_enabled = state;
-       audit_log(NULL, AUDIT_CONFIG_CHANGE,
+       audit_log(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE,
                        "audit_enabled=%d old=%d by auid=%u",
                        audit_enabled, old, loginuid);
        return old;
@@@ -269,7 -261,7 +261,7 @@@ static int audit_set_failure(int state
            && state != AUDIT_FAIL_PANIC)
                return -EINVAL;
        audit_failure = state;
-       audit_log(NULL, AUDIT_CONFIG_CHANGE,
+       audit_log(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE,
                        "audit_failure=%d old=%d by auid=%u",
                        audit_failure, old, loginuid);
        return old;
@@@ -281,6 -273,7 +273,7 @@@ int kauditd_thread(void *dummy
  
        while (1) {
                skb = skb_dequeue(&audit_skb_queue);
+               wake_up(&audit_backlog_wait);
                if (skb) {
                        if (audit_pid) {
                                int err = netlink_unicast(audit_sock, skb, audit_pid, 0);
                                        audit_pid = 0;
                                }
                        } else {
-                               printk(KERN_ERR "%s\n", skb->data + NLMSG_SPACE(0));
+                               printk(KERN_NOTICE "%s\n", skb->data + NLMSG_SPACE(0));
                                kfree_skb(skb);
                        }
                } else {
@@@ -423,7 -416,7 +416,7 @@@ static int audit_receive_msg(struct sk_
                if (status_get->mask & AUDIT_STATUS_PID) {
                        int old   = audit_pid;
                        audit_pid = status_get->pid;
-                       audit_log(NULL, AUDIT_CONFIG_CHANGE,
+                       audit_log(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE,
                                "audit_pid=%d old=%d by auid=%u",
                                  audit_pid, old, loginuid);
                }
                break;
        case AUDIT_USER:
        case AUDIT_FIRST_USER_MSG...AUDIT_LAST_USER_MSG:
-               ab = audit_log_start(NULL, msg_type);
-               if (!ab)
-                       break;  /* audit_panic has been called */
-               audit_log_format(ab,
-                                "user pid=%d uid=%u auid=%u"
-                                " msg='%.1024s'",
-                                pid, uid, loginuid, (char *)data);
-               audit_set_pid(ab, pid);
-               audit_log_end(ab);
+               if (!audit_enabled && msg_type != AUDIT_USER_AVC)
+                       return 0;
+               err = audit_filter_user(&NETLINK_CB(skb), msg_type);
+               if (err == 1) {
+                       err = 0;
+                       ab = audit_log_start(NULL, GFP_KERNEL, msg_type);
+                       if (ab) {
+                               audit_log_format(ab,
+                                                "user pid=%d uid=%u auid=%u msg='%.1024s'",
+                                                pid, uid, loginuid, (char *)data);
+                               audit_set_pid(ab, pid);
+                               audit_log_end(ab);
+                       }
+               }
                break;
        case AUDIT_ADD:
        case AUDIT_DEL:
@@@ -514,8 -513,7 +513,8 @@@ static int __init audit_init(void
  {
        printk(KERN_INFO "audit: initializing netlink socket (%s)\n",
               audit_default ? "enabled" : "disabled");
 -      audit_sock = netlink_kernel_create(NETLINK_AUDIT, audit_receive);
 +      audit_sock = netlink_kernel_create(NETLINK_AUDIT, 0, audit_receive,
 +                                         THIS_MODULE);
        if (!audit_sock)
                audit_panic("cannot initialize netlink socket");
  
        skb_queue_head_init(&audit_skb_queue);
        audit_initialized = 1;
        audit_enabled = audit_default;
-       audit_log(NULL, AUDIT_KERNEL, "initialized");
+       audit_log(NULL, GFP_KERNEL, AUDIT_KERNEL, "initialized");
        return 0;
  }
  __initcall(audit_init);
@@@ -561,7 -559,7 +560,7 @@@ static void audit_buffer_free(struct au
  }
  
  static struct audit_buffer * audit_buffer_alloc(struct audit_context *ctx,
-                                               int gfp_mask, int type)
+                                               unsigned int __nocast gfp_mask, int type)
  {
        unsigned long flags;
        struct audit_buffer *ab = NULL;
                goto err;
  
        ab->ctx = ctx;
+       ab->gfp_mask = gfp_mask;
        nlh = (struct nlmsghdr *)skb_put(ab->skb, NLMSG_SPACE(0));
        nlh->nlmsg_type = type;
        nlh->nlmsg_flags = 0;
@@@ -606,26 -605,27 +606,27 @@@ err
   * (timestamp,serial) tuple is unique for each syscall and is live from
   * syscall entry to syscall exit.
   *
-  * Atomic values are only guaranteed to be 24-bit, so we count down.
-  *
   * NOTE: Another possibility is to store the formatted records off the
   * audit context (for those records that have a context), and emit them
   * all at syscall exit.  However, this could delay the reporting of
   * significant errors until syscall exit (or never, if the system
   * halts). */
  unsigned int audit_serial(void)
  {
-       static atomic_t serial = ATOMIC_INIT(0xffffff);
-       unsigned int a, b;
+       static spinlock_t serial_lock = SPIN_LOCK_UNLOCKED;
+       static unsigned int serial = 0;
+       unsigned long flags;
+       unsigned int ret;
  
+       spin_lock_irqsave(&serial_lock, flags);
        do {
-               a = atomic_read(&serial);
-               if (atomic_dec_and_test(&serial))
-                       atomic_set(&serial, 0xffffff);
-               b = atomic_read(&serial);
-       } while (b != a - 1);
+               ret = ++serial;
+       } while (unlikely(!ret));
+       spin_unlock_irqrestore(&serial_lock, flags);
  
-       return 0xffffff - b;
+       return ret;
  }
  
  static inline void audit_get_stamp(struct audit_context *ctx, 
   * syscall, then the syscall is marked as auditable and an audit record
   * will be written at syscall exit.  If there is no associated task, tsk
   * should be NULL. */
- struct audit_buffer *audit_log_start(struct audit_context *ctx, int type)
+ struct audit_buffer *audit_log_start(struct audit_context *ctx, int gfp_mask,
+                                    int type)
  {
        struct audit_buffer     *ab     = NULL;
        struct timespec         t;
        unsigned int            serial;
+       int reserve;
+       unsigned long timeout_start = jiffies;
  
        if (!audit_initialized)
                return NULL;
  
-       if (audit_backlog_limit
-           && skb_queue_len(&audit_skb_queue) > audit_backlog_limit) {
+       if (gfp_mask & __GFP_WAIT)
+               reserve = 0;
+       else
+               reserve = 5; /* Allow atomic callers to go up to five 
+                               entries over the normal backlog limit */
+       while (audit_backlog_limit
+              && skb_queue_len(&audit_skb_queue) > audit_backlog_limit + reserve) {
+               if (gfp_mask & __GFP_WAIT && audit_backlog_wait_time
+                   && time_before(jiffies, timeout_start + audit_backlog_wait_time)) {
+                       /* Wait for auditd to drain the queue a little */
+                       DECLARE_WAITQUEUE(wait, current);
+                       set_current_state(TASK_INTERRUPTIBLE);
+                       add_wait_queue(&audit_backlog_wait, &wait);
+                       if (audit_backlog_limit &&
+                           skb_queue_len(&audit_skb_queue) > audit_backlog_limit)
+                               schedule_timeout(timeout_start + audit_backlog_wait_time - jiffies);
+                       __set_current_state(TASK_RUNNING);
+                       remove_wait_queue(&audit_backlog_wait, &wait);
+                       continue;
+               }
                if (audit_rate_check())
                        printk(KERN_WARNING
                               "audit: audit_backlog=%d > "
                               skb_queue_len(&audit_skb_queue),
                               audit_backlog_limit);
                audit_log_lost("backlog limit exceeded");
+               audit_backlog_wait_time = audit_backlog_wait_overflow;
+               wake_up(&audit_backlog_wait);
                return NULL;
        }
  
-       ab = audit_buffer_alloc(ctx, GFP_ATOMIC, type);
+       ab = audit_buffer_alloc(ctx, gfp_mask, type);
        if (!ab) {
                audit_log_lost("out of memory in audit_log_start");
                return NULL;
@@@ -690,7 -718,7 +719,7 @@@ static inline int audit_expand(struct a
  {
        struct sk_buff *skb = ab->skb;
        int ret = pskb_expand_head(skb, skb_headroom(skb), extra,
-                                  GFP_ATOMIC);
+                                  ab->gfp_mask);
        if (ret < 0) {
                audit_log_lost("out of memory in audit_expand");
                return 0;
@@@ -809,7 -837,7 +838,7 @@@ void audit_log_d_path(struct audit_buff
                audit_log_format(ab, " %s", prefix);
  
        /* We will allow 11 spaces for ' (deleted)' to be appended */
-       path = kmalloc(PATH_MAX+11, GFP_KERNEL);
+       path = kmalloc(PATH_MAX+11, ab->gfp_mask);
        if (!path) {
                audit_log_format(ab, "<no memory>");
                return;
@@@ -841,7 -869,7 +870,7 @@@ void audit_log_end(struct audit_buffer 
                        ab->skb = NULL;
                        wake_up_interruptible(&kauditd_wait);
                } else {
-                       printk("%s\n", ab->skb->data + NLMSG_SPACE(0));
+                       printk(KERN_NOTICE "%s\n", ab->skb->data + NLMSG_SPACE(0));
                }
        }
        audit_buffer_free(ab);
  /* Log an audit record.  This is a convenience function that calls
   * audit_log_start, audit_log_vformat, and audit_log_end.  It may be
   * called in any context. */
- void audit_log(struct audit_context *ctx, int type, const char *fmt, ...)
+ void audit_log(struct audit_context *ctx, int gfp_mask, int type, 
+              const char *fmt, ...)
  {
        struct audit_buffer *ab;
        va_list args;
  
-       ab = audit_log_start(ctx, type);
+       ab = audit_log_start(ctx, gfp_mask, type);
        if (ab) {
                va_start(args, fmt);
                audit_log_vformat(ab, fmt, args);
diff --combined security/selinux/avc.c
index cf6020f85403e54e23660e7c86c7e0f30e4750f4,2d088bb65ee8537a5f5751f7ec6890f9b55ab004..12e4fb72bf0f46bfc22a5e1a8a75efd93792d650
@@@ -242,7 -242,7 +242,7 @@@ void __init avc_init(void
        avc_node_cachep = kmem_cache_create("avc_node", sizeof(struct avc_node),
                                             0, SLAB_PANIC, NULL, NULL);
  
-       audit_log(current->audit_context, AUDIT_KERNEL, "AVC INITIALIZED\n");
+       audit_log(current->audit_context, GFP_KERNEL, AUDIT_KERNEL, "AVC INITIALIZED\n");
  }
  
  int avc_get_hash_stats(char *page)
@@@ -490,7 -490,7 +490,7 @@@ out
  }
  
  static inline void avc_print_ipv6_addr(struct audit_buffer *ab,
 -                                     struct in6_addr *addr, u16 port,
 +                                     struct in6_addr *addr, __be16 port,
                                       char *name1, char *name2)
  {
        if (!ipv6_addr_any(addr))
  }
  
  static inline void avc_print_ipv4_addr(struct audit_buffer *ab, u32 addr,
 -                                     u16 port, char *name1, char *name2)
 +                                     __be16 port, char *name1, char *name2)
  {
        if (addr)
                audit_log_format(ab, " %s=%d.%d.%d.%d", name1, NIPQUAD(addr));
@@@ -550,7 -550,7 +550,7 @@@ void avc_audit(u32 ssid, u32 tsid
                        return;
        }
  
-       ab = audit_log_start(current->audit_context, AUDIT_AVC);
+       ab = audit_log_start(current->audit_context, GFP_ATOMIC, AUDIT_AVC);
        if (!ab)
                return;         /* audit_panic has been called */
        audit_log_format(ab, "avc:  %s ", denied ? "denied" : "granted");
diff --combined security/selinux/hooks.c
index f40c8221ec1ba215b9526d74993ad5e8a4ed4256,9f9463000683e94f942dc29bdbadf08087603ecf..6e4937fe062b40f2c4b3c05baaa9cc96f85c4cd8
@@@ -659,7 -659,7 +659,7 @@@ static inline u16 socket_type_to_securi
                        return SECCLASS_NETLINK_ROUTE_SOCKET;
                case NETLINK_FIREWALL:
                        return SECCLASS_NETLINK_FIREWALL_SOCKET;
 -              case NETLINK_TCPDIAG:
 +              case NETLINK_INET_DIAG:
                        return SECCLASS_NETLINK_TCPDIAG_SOCKET;
                case NETLINK_NFLOG:
                        return SECCLASS_NETLINK_NFLOG_SOCKET;
@@@ -1265,6 -1265,85 +1265,6 @@@ static int inode_security_set_sid(struc
        return 0;
  }
  
 -/* Set the security attributes on a newly created file. */
 -static int post_create(struct inode *dir,
 -                     struct dentry *dentry)
 -{
 -
 -      struct task_security_struct *tsec;
 -      struct inode *inode;
 -      struct inode_security_struct *dsec;
 -      struct superblock_security_struct *sbsec;
 -      u32 newsid;
 -      char *context;
 -      unsigned int len;
 -      int rc;
 -
 -      tsec = current->security;
 -      dsec = dir->i_security;
 -      sbsec = dir->i_sb->s_security;
 -
 -      inode = dentry->d_inode;
 -      if (!inode) {
 -              /* Some file system types (e.g. NFS) may not instantiate
 -                 a dentry for all create operations (e.g. symlink),
 -                 so we have to check to see if the inode is non-NULL. */
 -              printk(KERN_WARNING "post_create:  no inode, dir (dev=%s, "
 -                     "ino=%ld)\n", dir->i_sb->s_id, dir->i_ino);
 -              return 0;
 -      }
 -
 -      if (tsec->create_sid && sbsec->behavior != SECURITY_FS_USE_MNTPOINT) {
 -              newsid = tsec->create_sid;
 -      } else {
 -              rc = security_transition_sid(tsec->sid, dsec->sid,
 -                                           inode_mode_to_security_class(inode->i_mode),
 -                                           &newsid);
 -              if (rc) {
 -                      printk(KERN_WARNING "post_create:  "
 -                             "security_transition_sid failed, rc=%d (dev=%s "
 -                             "ino=%ld)\n",
 -                             -rc, inode->i_sb->s_id, inode->i_ino);
 -                      return rc;
 -              }
 -      }
 -
 -      rc = inode_security_set_sid(inode, newsid);
 -      if (rc) {
 -              printk(KERN_WARNING "post_create:  inode_security_set_sid "
 -                     "failed, rc=%d (dev=%s ino=%ld)\n",
 -                     -rc, inode->i_sb->s_id, inode->i_ino);
 -              return rc;
 -      }
 -
 -      if (sbsec->behavior == SECURITY_FS_USE_XATTR &&
 -          inode->i_op->setxattr) {
 -              /* Use extended attributes. */
 -              rc = security_sid_to_context(newsid, &context, &len);
 -              if (rc) {
 -                      printk(KERN_WARNING "post_create:  sid_to_context "
 -                             "failed, rc=%d (dev=%s ino=%ld)\n",
 -                             -rc, inode->i_sb->s_id, inode->i_ino);
 -                      return rc;
 -              }
 -              down(&inode->i_sem);
 -              rc = inode->i_op->setxattr(dentry,
 -                                         XATTR_NAME_SELINUX,
 -                                         context, len, 0);
 -              up(&inode->i_sem);
 -              kfree(context);
 -              if (rc < 0) {
 -                      printk(KERN_WARNING "post_create:  setxattr failed, "
 -                             "rc=%d (dev=%s ino=%ld)\n",
 -                             -rc, inode->i_sb->s_id, inode->i_ino);
 -                      return rc;
 -              }
 -      }
 -
 -      return 0;
 -}
 -
 -
  /* Hook functions begin here. */
  
  static int selinux_ptrace(struct task_struct *parent, struct task_struct *child)
@@@ -1594,7 -1673,6 +1594,7 @@@ static inline void flush_unauthorized_f
        struct avc_audit_data ad;
        struct file *file, *devnull = NULL;
        struct tty_struct *tty = current->signal->tty;
 +      struct fdtable *fdt;
        long j = -1;
  
        if (tty) {
  
                j++;
                i = j * __NFDBITS;
 -              if (i >= files->max_fds || i >= files->max_fdset)
 +              fdt = files_fdtable(files);
 +              if (i >= fdt->max_fds || i >= fdt->max_fdset)
                        break;
 -              set = files->open_fds->fds_bits[j];
 +              set = fdt->open_fds->fds_bits[j];
                if (!set)
                        continue;
                spin_unlock(&files->file_lock);
                                                continue;
                                        }
                                        if (devnull) {
 -                                              atomic_inc(&devnull->f_count);
 +                                              rcuref_inc(&devnull->f_count);
                                        } else {
                                                devnull = dentry_open(dget(selinux_null), mntget(selinuxfs_mount), O_RDWR);
                                                if (!devnull) {
@@@ -1941,64 -2018,14 +1941,64 @@@ static void selinux_inode_free_security
        inode_free_security(inode);
  }
  
 -static int selinux_inode_create(struct inode *dir, struct dentry *dentry, int mask)
 +static int selinux_inode_init_security(struct inode *inode, struct inode *dir,
 +                                     char **name, void **value,
 +                                     size_t *len)
  {
 -      return may_create(dir, dentry, SECCLASS_FILE);
 +      struct task_security_struct *tsec;
 +      struct inode_security_struct *dsec;
 +      struct superblock_security_struct *sbsec;
 +      struct inode_security_struct *isec;
 +      u32 newsid, clen;
 +      int rc;
 +      char *namep = NULL, *context;
 +
 +      tsec = current->security;
 +      dsec = dir->i_security;
 +      sbsec = dir->i_sb->s_security;
 +      isec = inode->i_security;
 +
 +      if (tsec->create_sid && sbsec->behavior != SECURITY_FS_USE_MNTPOINT) {
 +              newsid = tsec->create_sid;
 +      } else {
 +              rc = security_transition_sid(tsec->sid, dsec->sid,
 +                                           inode_mode_to_security_class(inode->i_mode),
 +                                           &newsid);
 +              if (rc) {
 +                      printk(KERN_WARNING "%s:  "
 +                             "security_transition_sid failed, rc=%d (dev=%s "
 +                             "ino=%ld)\n",
 +                             __FUNCTION__,
 +                             -rc, inode->i_sb->s_id, inode->i_ino);
 +                      return rc;
 +              }
 +      }
 +
 +      inode_security_set_sid(inode, newsid);
 +
 +      if (name) {
 +              namep = kstrdup(XATTR_SELINUX_SUFFIX, GFP_KERNEL);
 +              if (!namep)
 +                      return -ENOMEM;
 +              *name = namep;
 +      }
 +
 +      if (value && len) {
 +              rc = security_sid_to_context(newsid, &context, &clen);
 +              if (rc) {
 +                      kfree(namep);
 +                      return rc;
 +              }
 +              *value = context;
 +              *len = clen;
 +      }
 +
 +      return 0;
  }
  
 -static void selinux_inode_post_create(struct inode *dir, struct dentry *dentry, int mask)
 +static int selinux_inode_create(struct inode *dir, struct dentry *dentry, int mask)
  {
 -      post_create(dir, dentry);
 +      return may_create(dir, dentry, SECCLASS_FILE);
  }
  
  static int selinux_inode_link(struct dentry *old_dentry, struct inode *dir, struct dentry *new_dentry)
        return may_link(dir, old_dentry, MAY_LINK);
  }
  
 -static void selinux_inode_post_link(struct dentry *old_dentry, struct inode *inode, struct dentry *new_dentry)
 -{
 -      return;
 -}
 -
  static int selinux_inode_unlink(struct inode *dir, struct dentry *dentry)
  {
        int rc;
@@@ -2026,11 -2058,21 +2026,11 @@@ static int selinux_inode_symlink(struc
        return may_create(dir, dentry, SECCLASS_LNK_FILE);
  }
  
 -static void selinux_inode_post_symlink(struct inode *dir, struct dentry *dentry, const char *name)
 -{
 -      post_create(dir, dentry);
 -}
 -
  static int selinux_inode_mkdir(struct inode *dir, struct dentry *dentry, int mask)
  {
        return may_create(dir, dentry, SECCLASS_DIR);
  }
  
 -static void selinux_inode_post_mkdir(struct inode *dir, struct dentry *dentry, int mask)
 -{
 -      post_create(dir, dentry);
 -}
 -
  static int selinux_inode_rmdir(struct inode *dir, struct dentry *dentry)
  {
        return may_link(dir, dentry, MAY_RMDIR);
@@@ -2047,12 -2089,23 +2047,12 @@@ static int selinux_inode_mknod(struct i
        return may_create(dir, dentry, inode_mode_to_security_class(mode));
  }
  
 -static void selinux_inode_post_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev)
 -{
 -      post_create(dir, dentry);
 -}
 -
  static int selinux_inode_rename(struct inode *old_inode, struct dentry *old_dentry,
                                  struct inode *new_inode, struct dentry *new_dentry)
  {
        return may_rename(old_inode, old_dentry, new_inode, new_dentry);
  }
  
 -static void selinux_inode_post_rename(struct inode *old_inode, struct dentry *old_dentry,
 -                                      struct inode *new_inode, struct dentry *new_dentry)
 -{
 -      return;
 -}
 -
  static int selinux_inode_readlink(struct dentry *dentry)
  {
        return dentry_has_perm(current, NULL, dentry, FILE__READ);
@@@ -3389,7 -3442,7 +3389,7 @@@ static int selinux_nlmsg_perm(struct so
        err = selinux_nlmsg_lookup(isec->sclass, nlh->nlmsg_type, &perm);
        if (err) {
                if (err == -EINVAL) {
-                       audit_log(current->audit_context, AUDIT_SELINUX_ERR,
+                       audit_log(current->audit_context, GFP_KERNEL, AUDIT_SELINUX_ERR,
                                  "SELinux:  unrecognized netlink message"
                                  " type=%hu for sclass=%hu\n",
                                  nlh->nlmsg_type, isec->sclass);
@@@ -4245,15 -4298,20 +4245,15 @@@ static struct security_operations selin
  
        .inode_alloc_security =         selinux_inode_alloc_security,
        .inode_free_security =          selinux_inode_free_security,
 +      .inode_init_security =          selinux_inode_init_security,
        .inode_create =                 selinux_inode_create,
 -      .inode_post_create =            selinux_inode_post_create,
        .inode_link =                   selinux_inode_link,
 -      .inode_post_link =              selinux_inode_post_link,
        .inode_unlink =                 selinux_inode_unlink,
        .inode_symlink =                selinux_inode_symlink,
 -      .inode_post_symlink =           selinux_inode_post_symlink,
        .inode_mkdir =                  selinux_inode_mkdir,
 -      .inode_post_mkdir =             selinux_inode_post_mkdir,
        .inode_rmdir =                  selinux_inode_rmdir,
        .inode_mknod =                  selinux_inode_mknod,
 -      .inode_post_mknod =             selinux_inode_post_mknod,
        .inode_rename =                 selinux_inode_rename,
 -      .inode_post_rename =            selinux_inode_post_rename,
        .inode_readlink =               selinux_inode_readlink,
        .inode_follow_link =            selinux_inode_follow_link,
        .inode_permission =             selinux_inode_permission,
index 92b89dc99bcd72a5e3bc51ee24795b434475317f,45d317044cb2520788504d61c409d77535b9fa31..aecdded55e74aa04d4c2f9bcb05b2f39df8617fe
@@@ -266,11 -266,8 +266,11 @@@ static int context_struct_compute_av(st
        struct constraint_node *constraint;
        struct role_allow *ra;
        struct avtab_key avkey;
 -      struct avtab_datum *avdatum;
 +      struct avtab_node *node;
        struct class_datum *tclass_datum;
 +      struct ebitmap *sattr, *tattr;
 +      struct ebitmap_node *snode, *tnode;
 +      unsigned int i, j;
  
        /*
         * Remap extended Netlink classes for old policy versions.
         * If a specific type enforcement rule was defined for
         * this permission check, then use it.
         */
 -      avkey.source_type = scontext->type;
 -      avkey.target_type = tcontext->type;
        avkey.target_class = tclass;
 -      avdatum = avtab_search(&policydb.te_avtab, &avkey, AVTAB_AV);
 -      if (avdatum) {
 -              if (avdatum->specified & AVTAB_ALLOWED)
 -                      avd->allowed = avtab_allowed(avdatum);
 -              if (avdatum->specified & AVTAB_AUDITDENY)
 -                      avd->auditdeny = avtab_auditdeny(avdatum);
 -              if (avdatum->specified & AVTAB_AUDITALLOW)
 -                      avd->auditallow = avtab_auditallow(avdatum);
 -      }
 +      avkey.specified = AVTAB_AV;
 +      sattr = &policydb.type_attr_map[scontext->type - 1];
 +      tattr = &policydb.type_attr_map[tcontext->type - 1];
 +      ebitmap_for_each_bit(sattr, snode, i) {
 +              if (!ebitmap_node_get_bit(snode, i))
 +                      continue;
 +              ebitmap_for_each_bit(tattr, tnode, j) {
 +                      if (!ebitmap_node_get_bit(tnode, j))
 +                              continue;
 +                      avkey.source_type = i + 1;
 +                      avkey.target_type = j + 1;
 +                      for (node = avtab_search_node(&policydb.te_avtab, &avkey);
 +                           node != NULL;
 +                           node = avtab_search_node_next(node, avkey.specified)) {
 +                              if (node->key.specified == AVTAB_ALLOWED)
 +                                      avd->allowed |= node->datum.data;
 +                              else if (node->key.specified == AVTAB_AUDITALLOW)
 +                                      avd->auditallow |= node->datum.data;
 +                              else if (node->key.specified == AVTAB_AUDITDENY)
 +                                      avd->auditdeny &= node->datum.data;
 +                      }
  
 -      /* Check conditional av table for additional permissions */
 -      cond_compute_av(&policydb.te_cond_avtab, &avkey, avd);
 +                      /* Check conditional av table for additional permissions */
 +                      cond_compute_av(&policydb.te_cond_avtab, &avkey, avd);
 +
 +              }
 +      }
  
        /*
         * Remove any permissions prohibited by a constraint (this includes
@@@ -381,7 -365,7 +381,7 @@@ static int security_validtrans_handle_f
                goto out;
        if (context_struct_to_string(tcontext, &t, &tlen) < 0)
                goto out;
-       audit_log(current->audit_context, AUDIT_SELINUX_ERR,
+       audit_log(current->audit_context, GFP_ATOMIC, AUDIT_SELINUX_ERR,
                  "security_validate_transition:  denied for"
                  " oldcontext=%s newcontext=%s taskcontext=%s tclass=%s",
                  o, n, t, policydb.p_class_val_to_name[tclass-1]);
@@@ -787,7 -771,7 +787,7 @@@ static int compute_sid_handle_invalid_c
                goto out;
        if (context_struct_to_string(newcontext, &n, &nlen) < 0)
                goto out;
-       audit_log(current->audit_context, AUDIT_SELINUX_ERR,
+       audit_log(current->audit_context, GFP_ATOMIC, AUDIT_SELINUX_ERR,
                  "security_compute_sid:  invalid context %s"
                  " for scontext=%s"
                  " tcontext=%s"
@@@ -813,6 -797,7 +813,6 @@@ static int security_compute_sid(u32 ssi
        struct avtab_key avkey;
        struct avtab_datum *avdatum;
        struct avtab_node *node;
 -      unsigned int type_change = 0;
        int rc = 0;
  
        if (!ss_initialized) {
        avkey.source_type = scontext->type;
        avkey.target_type = tcontext->type;
        avkey.target_class = tclass;
 -      avdatum = avtab_search(&policydb.te_avtab, &avkey, AVTAB_TYPE);
 +      avkey.specified = specified;
 +      avdatum = avtab_search(&policydb.te_avtab, &avkey);
  
        /* If no permanent rule, also check for enabled conditional rules */
        if(!avdatum) {
 -              node = avtab_search_node(&policydb.te_cond_avtab, &avkey, specified);
 +              node = avtab_search_node(&policydb.te_cond_avtab, &avkey);
                for (; node != NULL; node = avtab_search_node_next(node, specified)) {
 -                      if (node->datum.specified & AVTAB_ENABLED) {
 +                      if (node->key.specified & AVTAB_ENABLED) {
                                avdatum = &node->datum;
                                break;
                        }
                }
        }
  
 -      type_change = (avdatum && (avdatum->specified & specified));
 -      if (type_change) {
 +      if (avdatum) {
                /* Use the type from the type transition/member/change rule. */
 -              switch (specified) {
 -              case AVTAB_TRANSITION:
 -                      newcontext.type = avtab_transition(avdatum);
 -                      break;
 -              case AVTAB_MEMBER:
 -                      newcontext.type = avtab_member(avdatum);
 -                      break;
 -              case AVTAB_CHANGE:
 -                      newcontext.type = avtab_change(avdatum);
 -                      break;
 -              }
 +              newcontext.type = avdatum->data;
        }
  
        /* Check for class-specific changes. */
@@@ -1507,7 -1502,6 +1507,7 @@@ int security_get_user_sids(u32 fromsid
        struct user_datum *user;
        struct role_datum *role;
        struct av_decision avd;
 +      struct ebitmap_node *rnode, *tnode;
        int rc = 0, i, j;
  
        if (!ss_initialized) {
        }
        memset(mysids, 0, maxnel*sizeof(*mysids));
  
 -      for (i = ebitmap_startbit(&user->roles); i < ebitmap_length(&user->roles); i++) {
 -              if (!ebitmap_get_bit(&user->roles, i))
 +      ebitmap_for_each_bit(&user->roles, rnode, i) {
 +              if (!ebitmap_node_get_bit(rnode, i))
                        continue;
                role = policydb.role_val_to_struct[i];
                usercon.role = i+1;
 -              for (j = ebitmap_startbit(&role->types); j < ebitmap_length(&role->types); j++) {
 -                      if (!ebitmap_get_bit(&role->types, j))
 +              ebitmap_for_each_bit(&role->types, tnode, j) {
 +                      if (!ebitmap_node_get_bit(tnode, j))
                                continue;
                        usercon.type = j+1;