Merge branch 'master' into next
James Morris [Sun, 9 Jan 2011 22:46:24 +0000 (09:46 +1100)]
Conflicts:
security/smack/smack_lsm.c

Verified and added fix by Stephen Rothwell <sfr@canb.auug.org.au>
Ok'd by Casey Schaufler <casey@schaufler-ca.com>

Signed-off-by: James Morris <jmorris@namei.org>

1  2 
MAINTAINERS
drivers/char/tpm/tpm.c
include/linux/security.h
kernel/printk.c
security/smack/smack_lsm.c

diff --combined MAINTAINERS
@@@ -166,9 -166,8 +166,8 @@@ F: drivers/serial/8250
  F:    include/linux/serial_8250.h
  
  8390 NETWORK DRIVERS [WD80x3/SMC-ELITE, SMC-ULTRA, NE2000, 3C503, etc.]
- M:    Paul Gortmaker <p_gortmaker@yahoo.com>
  L:    netdev@vger.kernel.org
- S:    Maintained
+ S:    Orphan / Obsolete
  F:    drivers/net/*8390*
  F:    drivers/net/ax88796.c
  
@@@ -405,7 -404,7 +404,7 @@@ S: Supporte
  F:    drivers/usb/gadget/amd5536udc.*
  
  AMD GEODE PROCESSOR/CHIPSET SUPPORT
- P:    Jordan Crouse
+ P:    Andres Salomon <dilinger@queued.net>
  L:    linux-geode@lists.infradead.org (moderated for non-subscribers)
  W:    http://www.amd.com/us-en/ConnectivitySolutions/TechnicalResources/0,,50_2334_2452_11363,00.html
  S:    Supported
@@@ -559,14 -558,14 +558,14 @@@ W:      http://maxim.org.za/at91_26.htm
  S:    Maintained
  
  ARM/BCMRING ARM ARCHITECTURE
- M:    Leo Chen <leochen@broadcom.com>
+ M:    Jiandong Zheng <jdzheng@broadcom.com>
  M:    Scott Branden <sbranden@broadcom.com>
  L:    linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
  S:    Maintained
  F:    arch/arm/mach-bcmring
  
  ARM/BCMRING MTD NAND DRIVER
- M:    Leo Chen <leochen@broadcom.com>
+ M:    Jiandong Zheng <jdzheng@broadcom.com>
  M:    Scott Branden <sbranden@broadcom.com>
  L:    linux-mtd@lists.infradead.org
  S:    Maintained
@@@ -792,11 -791,14 +791,14 @@@ S:      Maintaine
  
  ARM/NOMADIK ARCHITECTURE
  M:    Alessandro Rubini <rubini@unipv.it>
+ M:    Linus Walleij <linus.walleij@stericsson.com>
  M:    STEricsson <STEricsson_nomadik_linux@list.st.com>
  L:    linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
  S:    Maintained
  F:    arch/arm/mach-nomadik/
  F:    arch/arm/plat-nomadik/
+ F:    drivers/i2c/busses/i2c-nomadik.c
+ T:    git git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-stericsson.git
  
  ARM/OPENMOKO NEO FREERUNNER (GTA02) MACHINE SUPPORT
  M:    Nelson Castillo <arhuaco@freaks-unidos.net>
@@@ -815,7 -817,7 +817,7 @@@ F: drivers/mmc/host/msm_sdcc.
  F:    drivers/mmc/host/msm_sdcc.h
  F:    drivers/serial/msm_serial.h
  F:    drivers/serial/msm_serial.c
- T:    git git://codeaurora.org/quic/kernel/dwalker/linux-msm.git
+ T:    git git://codeaurora.org/quic/kernel/davidb/linux-msm.git
  S:    Maintained
  
  ARM/TOSA MACHINE SUPPORT
@@@ -998,12 -1000,24 +1000,24 @@@ F:    drivers/i2c/busses/i2c-stu300.
  F:    drivers/rtc/rtc-coh901331.c
  F:    drivers/watchdog/coh901327_wdt.c
  F:    drivers/dma/coh901318*
+ F:    drivers/mfd/ab3100*
+ F:    drivers/rtc/rtc-ab3100.c
+ F:    drivers/rtc/rtc-coh901331.c
+ T:    git git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-stericsson.git
  
- ARM/U8500 ARM ARCHITECTURE
+ ARM/Ux500 ARM ARCHITECTURE
  M:    Srinidhi Kasagar <srinidhi.kasagar@stericsson.com>
+ M:    Linus Walleij <linus.walleij@stericsson.com>
  L:    linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
  S:    Maintained
  F:    arch/arm/mach-ux500/
+ F:    drivers/dma/ste_dma40*
+ F:    drivers/mfd/ab3550*
+ F:    drivers/mfd/abx500*
+ F:    drivers/mfd/ab8500*
+ F:    drivers/mfd/stmpe*
+ F:    drivers/rtc/rtc-ab8500.c
+ T:    git git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-stericsson.git
  
  ARM/VFP SUPPORT
  M:    Russell King <linux@arm.linux.org.uk>
@@@ -1080,6 -1094,12 +1094,12 @@@ S:    Supporte
  F:    Documentation/aoe/
  F:    drivers/block/aoe/
  
+ ATHEROS ATH GENERIC UTILITIES
+ M:    "Luis R. Rodriguez" <lrodriguez@atheros.com>
+ L:    linux-wireless@vger.kernel.org
+ S:    Supported
+ F:    drivers/net/wireless/ath/*
  ATHEROS ATH5K WIRELESS DRIVER
  M:    Jiri Slaby <jirislaby@gmail.com>
  M:    Nick Kossifidis <mickflemm@gmail.com>
@@@ -1258,6 -1278,15 +1278,15 @@@ S:    Maintaine
  F:    drivers/video/backlight/
  F:    include/linux/backlight.h
  
+ BATMAN ADVANCED
+ M:    Marek Lindner <lindner_marek@yahoo.de>
+ M:    Simon Wunderlich <siwu@hrz.tu-chemnitz.de>
+ M:    Sven Eckelmann <sven@narfation.org>
+ L:    b.a.t.m.a.n@lists.open-mesh.org
+ W:    http://www.open-mesh.org/
+ S:    Maintained
+ F:    net/batman-adv/
  BAYCOM/HDLCDRV DRIVERS FOR AX.25
  M:    Thomas Sailer <t.sailer@alumni.ethz.ch>
  L:    linux-hams@vger.kernel.org
@@@ -2060,7 -2089,7 +2089,7 @@@ F:      Documentation/blockdev/drbd
  
  DRIVER CORE, KOBJECTS, DEBUGFS AND SYSFS
  M:    Greg Kroah-Hartman <gregkh@suse.de>
- T:    quilt kernel.org/pub/linux/kernel/people/gregkh/gregkh-2.6/
+ T:    git git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core-2.6.git
  S:    Supported
  F:    Documentation/kobject.txt
  F:    drivers/base/
@@@ -2080,7 -2109,7 +2109,7 @@@ F:      include/drm
  
  INTEL DRM DRIVERS (excluding Poulsbo, Moorestown and derivative chipsets)
  M:    Chris Wilson <chris@chris-wilson.co.uk>
- L:    intel-gfx@lists.freedesktop.org
+ L:    intel-gfx@lists.freedesktop.org (subscribers-only)
  L:    dri-devel@lists.freedesktop.org
  T:    git git://git.kernel.org/pub/scm/linux/kernel/git/ickle/drm-intel.git
  S:    Supported
@@@ -2797,6 -2826,10 +2826,10 @@@ M:    Thomas Gleixner <tglx@linutronix.de
  S:    Maintained
  F:    Documentation/timers/
  F:    kernel/hrtimer.c
+ F:    kernel/time/clockevents.c
+ F:    kernel/time/tick*.*
+ F:    kernel/time/timer_*.c
+ F     include/linux/clockevents.h
  F:    include/linux/hrtimer.h
  
  HIGH-SPEED SCC DRIVER FOR AX.25
@@@ -3032,8 -3065,10 +3065,10 @@@ F:    drivers/input
  INPUT MULTITOUCH (MT) PROTOCOL
  M:    Henrik Rydberg <rydberg@euromail.se>
  L:    linux-input@vger.kernel.org
+ T:    git git://git.kernel.org/pub/scm/linux/kernel/git/rydberg/input-mt.git
  S:    Maintained
  F:    Documentation/input/multi-touch-protocol.txt
+ F:    drivers/input/input-mt.c
  K:    \b(ABS|SYN)_MT_
  
  INTEL IDLE DRIVER
@@@ -3120,6 -3155,8 +3155,8 @@@ M:      Alex Duyck <alexander.h.duyck@intel.
  M:    John Ronciak <john.ronciak@intel.com>
  L:    e1000-devel@lists.sourceforge.net
  W:    http://e1000.sourceforge.net/
+ T:    git git://git.kernel.org/pub/scm/linux/kernel/git/jkirsher/net-2.6.git
+ T:    git git://git.kernel.org/pub/scm/linux/kernel/git/jkirsher/net-next-2.6.git
  S:    Supported
  F:    Documentation/networking/e100.txt
  F:    Documentation/networking/e1000.txt
@@@ -4064,9 -4101,8 +4101,8 @@@ F:      drivers/scsi/NCR_D700.
  
  NETEFFECT IWARP RNIC DRIVER (IW_NES)
  M:    Faisal Latif <faisal.latif@intel.com>
- M:    Chien Tung <chien.tin.tung@intel.com>
  L:    linux-rdma@vger.kernel.org
- W:    http://www.neteffect.com
+ W:    http://www.intel.com/Products/Server/Adapters/Server-Cluster/Server-Cluster-overview.htm
  S:    Supported
  F:    drivers/infiniband/hw/nes/
  
@@@ -4329,6 -4365,20 +4365,20 @@@ M:    Deepak Saxena <dsaxena@plexity.net
  S:    Maintained
  F:    drivers/char/hw_random/omap-rng.c
  
+ OMAP HWMOD SUPPORT
+ M:    Benoît Cousson <b-cousson@ti.com>
+ M:    Paul Walmsley <paul@pwsan.com>
+ L:    linux-omap@vger.kernel.org
+ S:    Maintained
+ F:    arch/arm/mach-omap2/omap_hwmod.c
+ F:    arch/arm/plat-omap/include/plat/omap_hwmod.h
+ OMAP HWMOD DATA FOR OMAP4-BASED DEVICES
+ M:    Benoît Cousson <b-cousson@ti.com>
+ L:    linux-omap@vger.kernel.org
+ S:    Maintained
+ F:    arch/arm/mach-omap2/omap_hwmod_44xx_data.c
  OMAP USB SUPPORT
  M:    Felipe Balbi <balbi@ti.com>
  M:    David Brownell <dbrownell@users.sourceforge.net>
@@@ -4591,7 -4641,7 +4641,7 @@@ F:      drivers/pcmcia
  F:    include/pcmcia/
  
  PCNET32 NETWORK DRIVER
- M:    Don Fry <pcnet32@verizon.net>
+ M:    Don Fry <pcnet32@frontier.com>
  L:    netdev@vger.kernel.org
  S:    Maintained
  F:    drivers/net/pcnet32.c
@@@ -4603,6 -4653,16 +4653,16 @@@ S:    Maintaine
  F:    crypto/pcrypt.c
  F:    include/crypto/pcrypt.h
  
+ PER-CPU MEMORY ALLOCATOR
+ M:    Tejun Heo <tj@kernel.org>
+ M:    Christoph Lameter <cl@linux-foundation.org>
+ L:    linux-kernel@vger.kernel.org
+ T:    git git://git.kernel.org/pub/scm/linux/kernel/git/tj/percpu.git
+ S:    Maintained
+ F:    include/linux/percpu*.h
+ F:    mm/percpu*.c
+ F:    arch/*/include/asm/percpu.h
  PER-TASK DELAY ACCOUNTING
  M:    Balbir Singh <balbir@linux.vnet.ibm.com>
  S:    Maintained
@@@ -4613,7 -4673,7 +4673,7 @@@ PERFORMANCE EVENTS SUBSYSTE
  M:    Peter Zijlstra <a.p.zijlstra@chello.nl>
  M:    Paul Mackerras <paulus@samba.org>
  M:    Ingo Molnar <mingo@elte.hu>
- M:    Arnaldo Carvalho de Melo <acme@redhat.com>
+ M:    Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
  S:    Supported
  F:    kernel/perf_event*.c
  F:    include/linux/perf_event.h
@@@ -5038,7 -5098,7 +5098,7 @@@ L:      linux-wireless@vger.kernel.or
  W:    http://linuxwireless.org/
  T:    git git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-testing.git
  S:    Maintained
- F:    drivers/net/wireless/rtl818x/rtl8180*
+ F:    drivers/net/wireless/rtl818x/rtl8180/
  
  RTL8187 WIRELESS DRIVER
  M:    Herton Ronaldo Krzesinski <herton@mandriva.com.br>
@@@ -5048,7 -5108,17 +5108,17 @@@ L:    linux-wireless@vger.kernel.or
  W:    http://linuxwireless.org/
  T:    git git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-testing.git
  S:    Maintained
- F:    drivers/net/wireless/rtl818x/rtl8187*
+ F:    drivers/net/wireless/rtl818x/rtl8187/
+ RTL8192CE WIRELESS DRIVER
+ M:    Larry Finger <Larry.Finger@lwfinger.net>
+ M:    Chaoming Li <chaoming_li@realsil.com.cn>
+ L:    linux-wireless@vger.kernel.org
+ W:    http://linuxwireless.org/
+ T:    git git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-testing.git
+ S:    Maintained
+ F:    drivers/net/wireless/rtlwifi/
+ F:    drivers/net/wireless/rtlwifi/rtl8192ce/
  
  S3 SAVAGE FRAMEBUFFER DRIVER
  M:    Antonino Daplas <adaplas@gmail.com>
@@@ -5128,6 -5198,18 +5198,18 @@@ L:    alsa-devel@alsa-project.org (moderat
  S:    Supported
  F:    sound/soc/s3c24xx
  
+ TIMEKEEPING, NTP
+ M:    John Stultz <johnstul@us.ibm.com>
+ M:    Thomas Gleixner <tglx@linutronix.de>
+ S:    Supported
+ F:    include/linux/clocksource.h
+ F:    include/linux/time.h
+ F:    include/linux/timex.h
+ F:    include/linux/timekeeping.h
+ F:    kernel/time/clocksource.c
+ F:    kernel/time/time*.c
+ F:    kernel/time/ntp.c
  TLG2300 VIDEO4LINUX-2 DRIVER
  M:    Huang Shijie <shijie8@gmail.com>
  M:    Kang Yong <kangyong@telegent.com>
@@@ -5698,12 -5780,6 +5780,6 @@@ M:     Ion Badulescu <ionut@badula.org
  S:    Odd Fixes
  F:    drivers/net/starfire*
  
- STRADIS MPEG-2 DECODER DRIVER
- M:    Nathan Laredo <laredo@gnu.org>
- W:    http://www.stradis.com/
- S:    Maintained
- F:    drivers/media/video/stradis.c
  SUN3/3X
  M:    Sam Creasey <sammy@sammy.net>
  W:    http://sammy.net/sun3/
@@@ -5853,8 -5929,7 +5929,8 @@@ F:      drivers/net/tlan.
  TOMOYO SECURITY MODULE
  M:    Kentaro Takeda <takedakn@nttdata.co.jp>
  M:    Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
 -L:    tomoyo-users-en@lists.sourceforge.jp (subscribers-only, for developers and users in English)
 +L:    tomoyo-dev-en@lists.sourceforge.jp (subscribers-only, for developers in English)
 +L:    tomoyo-users-en@lists.sourceforge.jp (subscribers-only, for users in English)
  L:    tomoyo-dev@lists.sourceforge.jp (subscribers-only, for developers in Japanese)
  L:    tomoyo-users@lists.sourceforge.jp (subscribers-only, for users in Japanese)
  W:    http://tomoyo.sourceforge.jp/
@@@ -5934,7 -6009,6 +6010,6 @@@ F:      include/linux/tty.
  
  TULIP NETWORK DRIVERS
  M:    Grant Grundler <grundler@parisc-linux.org>
- M:    Kyle McMartin <kyle@mcmartin.ca>
  L:    netdev@vger.kernel.org
  S:    Maintained
  F:    drivers/net/tulip/
@@@ -6586,6 -6660,15 +6661,15 @@@ F:    include/linux/mfd/wm8400
  F:    include/sound/wm????.h
  F:    sound/soc/codecs/wm*
  
+ WORKQUEUE
+ M:    Tejun Heo <tj@kernel.org>
+ L:    linux-kernel@vger.kernel.org
+ T:    git git://git.kernel.org/pub/scm/linux/kernel/git/tj/wq.git
+ S:    Maintained
+ F:    include/linux/workqueue.h
+ F:    kernel/workqueue.c
+ F:    Documentation/workqueue.txt
  X.25 NETWORK LAYER
  M:    Andrew Hendry <andrew.hendry@gmail.com>
  L:    linux-x25@vger.kernel.org
diff --combined drivers/char/tpm/tpm.c
@@@ -736,7 -736,7 +736,7 @@@ int tpm_pcr_read(u32 chip_num, int pcr_
        if (chip == NULL)
                return -ENODEV;
        rc = __tpm_pcr_read(chip, pcr_idx, res_buf);
 -      module_put(chip->dev->driver->owner);
 +      tpm_chip_put(chip);
        return rc;
  }
  EXPORT_SYMBOL_GPL(tpm_pcr_read);
@@@ -775,27 -775,11 +775,27 @@@ int tpm_pcr_extend(u32 chip_num, int pc
        rc = transmit_cmd(chip, &cmd, EXTEND_PCR_RESULT_SIZE,
                          "attempting extend a PCR value");
  
 -      module_put(chip->dev->driver->owner);
 +      tpm_chip_put(chip);
        return rc;
  }
  EXPORT_SYMBOL_GPL(tpm_pcr_extend);
  
 +int tpm_send(u32 chip_num, void *cmd, size_t buflen)
 +{
 +      struct tpm_chip *chip;
 +      int rc;
 +
 +      chip = tpm_chip_find_get(chip_num);
 +      if (chip == NULL)
 +              return -ENODEV;
 +
 +      rc = transmit_cmd(chip, cmd, buflen, "attempting tpm_cmd");
 +
 +      tpm_chip_put(chip);
 +      return rc;
 +}
 +EXPORT_SYMBOL_GPL(tpm_send);
 +
  ssize_t tpm_show_pcrs(struct device *dev, struct device_attribute *attr,
                      char *buf)
  {
@@@ -1002,7 -986,7 +1002,7 @@@ int tpm_release(struct inode *inode, st
        struct tpm_chip *chip = file->private_data;
  
        del_singleshot_timer_sync(&chip->user_read_timer);
-       flush_scheduled_work();
+       flush_work_sync(&chip->work);
        file->private_data = NULL;
        atomic_set(&chip->data_pending, 0);
        kfree(chip->data_buffer);
@@@ -1054,7 -1038,7 +1054,7 @@@ ssize_t tpm_read(struct file *file, cha
        ssize_t ret_size;
  
        del_singleshot_timer_sync(&chip->user_read_timer);
-       flush_scheduled_work();
+       flush_work_sync(&chip->work);
        ret_size = atomic_read(&chip->data_pending);
        atomic_set(&chip->data_pending, 0);
        if (ret_size > 0) {     /* relay data */
diff --combined include/linux/security.h
@@@ -457,7 -457,6 +457,6 @@@ static inline void security_free_mnt_op
   *    called when the actual read/write operations are performed.
   *    @inode contains the inode structure to check.
   *    @mask contains the permission mask.
-  *    @nd contains the nameidata (may be NULL).
   *    Return 0 if permission is granted.
   * @inode_setattr:
   *    Check permission before setting file attributes.  Note that the kernel
   * @unix_stream_connect:
   *    Check permissions before establishing a Unix domain stream connection
   *    between @sock and @other.
-  *    @sock contains the socket structure.
-  *    @other contains the peer socket structure.
+  *    @sock contains the sock structure.
+  *    @other contains the peer sock structure.
+  *    @newsk contains the new sock structure.
   *    Return 0 if permission is granted.
   * @unix_may_send:
   *    Check permissions before connecting or sending datagrams from @sock to
   *    @cred points to the credentials to provide the context against which to
   *    evaluate the security data on the key.
   *    @perm describes the combination of permissions required of this key.
 - *    Return 1 if permission granted, 0 if permission denied and -ve it the
 - *    normal permissions model should be effected.
 + *    Return 0 if permission is granted, -ve error otherwise.
   * @key_getsecurity:
   *    Get a textual representation of the security context attached to a key
   *    for the purposes of honouring KEYCTL_GETSECURITY.  This function
@@@ -1567,8 -1568,7 +1567,7 @@@ struct security_operations 
        int (*inode_getsecctx)(struct inode *inode, void **ctx, u32 *ctxlen);
  
  #ifdef CONFIG_SECURITY_NETWORK
-       int (*unix_stream_connect) (struct socket *sock,
-                                   struct socket *other, struct sock *newsk);
+       int (*unix_stream_connect) (struct sock *sock, struct sock *other, struct sock *newsk);
        int (*unix_may_send) (struct socket *sock, struct socket *other);
  
        int (*socket_create) (int family, int type, int protocol, int kern);
@@@ -1712,6 -1712,7 +1711,7 @@@ 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);
+ int security_inode_exec_permission(struct inode *inode, unsigned int flags);
  int security_inode_setattr(struct dentry *dentry, struct iattr *attr);
  int security_inode_getattr(struct vfsmount *mnt, struct dentry *dentry);
  int security_inode_setxattr(struct dentry *dentry, const char *name,
@@@ -2101,6 -2102,12 +2101,12 @@@ static inline int security_inode_permis
        return 0;
  }
  
+ static inline int security_inode_exec_permission(struct inode *inode,
+                                                 unsigned int flags)
+ {
+       return 0;
+ }
  static inline int security_inode_setattr(struct dentry *dentry,
                                          struct iattr *attr)
  {
@@@ -2524,8 -2531,7 +2530,7 @@@ static inline int security_inode_getsec
  
  #ifdef CONFIG_SECURITY_NETWORK
  
- int security_unix_stream_connect(struct socket *sock, struct socket *other,
-                                struct sock *newsk);
+ int security_unix_stream_connect(struct sock *sock, struct sock *other, struct sock *newsk);
  int security_unix_may_send(struct socket *sock,  struct socket *other);
  int security_socket_create(int family, int type, int protocol, int kern);
  int security_socket_post_create(struct socket *sock, int family,
@@@ -2566,8 -2572,8 +2571,8 @@@ void security_tun_dev_post_create(struc
  int security_tun_dev_attach(struct sock *sk);
  
  #else /* CONFIG_SECURITY_NETWORK */
- static inline int security_unix_stream_connect(struct socket *sock,
-                                              struct socket *other,
+ static inline int security_unix_stream_connect(struct sock *sock,
+                                              struct sock *other,
                                               struct sock *newsk)
  {
        return 0;
diff --combined kernel/printk.c
  #include <asm/uaccess.h>
  
  /*
-  * for_each_console() allows you to iterate on each console
-  */
- #define for_each_console(con) \
-       for (con = console_drivers; con != NULL; con = con->next)
- /*
   * Architectures can override it:
   */
  void asmlinkage __attribute__((weak)) early_printk(const char *fmt, ...)
@@@ -279,12 -273,12 +273,12 @@@ int do_syslog(int type, char __user *bu
         * at open time.
         */
        if (type == SYSLOG_ACTION_OPEN || !from_file) {
 -              if (dmesg_restrict && !capable(CAP_SYS_ADMIN))
 -                      return -EPERM;
 +              if (dmesg_restrict && !capable(CAP_SYSLOG))
 +                      goto warn; /* switch to return -EPERM after 2.6.39 */
                if ((type != SYSLOG_ACTION_READ_ALL &&
                     type != SYSLOG_ACTION_SIZE_BUFFER) &&
 -                  !capable(CAP_SYS_ADMIN))
 -                      return -EPERM;
 +                  !capable(CAP_SYSLOG))
 +                      goto warn; /* switch to return -EPERM after 2.6.39 */
        }
  
        error = security_syslog(type);
        }
  out:
        return error;
 +warn:
 +      /* remove after 2.6.39 */
 +      if (capable(CAP_SYS_ADMIN))
 +              WARN_ONCE(1, "Attempt to access syslog with CAP_SYS_ADMIN "
 +                "but no CAP_SYSLOG (deprecated and denied).\n");
 +      return -EPERM;
  }
  
  SYSCALL_DEFINE3(syslog, int, type, char __user *, buf, int, len)
@@@ -1080,21 -1068,23 +1074,23 @@@ static DEFINE_PER_CPU(int, printk_pendi
  
  void printk_tick(void)
  {
-       if (__get_cpu_var(printk_pending)) {
-               __get_cpu_var(printk_pending) = 0;
+       if (__this_cpu_read(printk_pending)) {
+               __this_cpu_write(printk_pending, 0);
                wake_up_interruptible(&log_wait);
        }
  }
  
  int printk_needs_cpu(int cpu)
  {
-       return per_cpu(printk_pending, cpu);
+       if (cpu_is_offline(cpu))
+               printk_tick();
+       return __this_cpu_read(printk_pending);
  }
  
  void wake_up_klogd(void)
  {
        if (waitqueue_active(&log_wait))
-               __raw_get_cpu_var(printk_pending) = 1;
+               this_cpu_write(printk_pending, 1);
  }
  
  /**
@@@ -1363,6 -1353,7 +1359,7 @@@ void register_console(struct console *n
                spin_unlock_irqrestore(&logbuf_lock, flags);
        }
        release_console_sem();
+       console_sysfs_notify();
  
        /*
         * By unregistering the bootconsoles after we enable the real console
@@@ -1421,6 -1412,7 +1418,7 @@@ int unregister_console(struct console *
                console_drivers->flags |= CON_CONSDEV;
  
        release_console_sem();
+       console_sysfs_notify();
        return res;
  }
  EXPORT_SYMBOL(unregister_console);
@@@ -3,14 -3,12 +3,14 @@@
   *
   *  This file contains the smack hook function implementations.
   *
 - *  Author:
 + *  Authors:
   *    Casey Schaufler <casey@schaufler-ca.com>
 + *    Jarkko Sakkinen <ext-jarkko.2.sakkinen@nokia.com>
   *
   *  Copyright (C) 2007 Casey Schaufler <casey@schaufler-ca.com>
   *  Copyright (C) 2009 Hewlett-Packard Development Company, L.P.
   *                Paul Moore <paul.moore@hp.com>
 + *  Copyright (C) 2010 Nokia Corporation
   *
   *    This program is free software; you can redistribute it and/or modify
   *    it under the terms of the GNU General Public License version 2,
@@@ -37,9 -35,6 +37,9 @@@
  
  #define task_security(task)   (task_cred_xxx((task), security))
  
 +#define TRANS_TRUE    "TRUE"
 +#define TRANS_TRUE_SIZE       4
 +
  /**
   * smk_fetch - Fetch the smack label from a file.
   * @ip: a pointer to the inode
@@@ -48,7 -43,7 +48,7 @@@
   * Returns a pointer to the master list entry for the Smack label
   * or NULL if there was no label to fetch.
   */
 -static char *smk_fetch(struct inode *ip, struct dentry *dp)
 +static char *smk_fetch(const char *name, struct inode *ip, struct dentry *dp)
  {
        int rc;
        char in[SMK_LABELLEN];
@@@ -56,7 -51,7 +56,7 @@@
        if (ip->i_op->getxattr == NULL)
                return NULL;
  
 -      rc = ip->i_op->getxattr(dp, XATTR_NAME_SMACK, in, SMK_LABELLEN);
 +      rc = ip->i_op->getxattr(dp, name, in, SMK_LABELLEN);
        if (rc < 0)
                return NULL;
  
@@@ -108,8 -103,8 +108,8 @@@ static int smack_ptrace_access_check(st
        if (rc != 0)
                return rc;
  
 -      sp = current_security();
 -      tsp = task_security(ctp);
 +      sp = smk_of_current();
 +      tsp = smk_of_task(task_security(ctp));
        smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_TASK);
        smk_ad_setfield_u_tsk(&ad, ctp);
  
@@@ -143,8 -138,8 +143,8 @@@ static int smack_ptrace_traceme(struct 
        smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_TASK);
        smk_ad_setfield_u_tsk(&ad, ptp);
  
 -      sp = current_security();
 -      tsp = task_security(ptp);
 +      sp = smk_of_current();
 +      tsp = smk_of_task(task_security(ptp));
        /* we won't log here, because rc can be overriden */
        rc = smk_access(tsp, sp, MAY_READWRITE, NULL);
        if (rc != 0 && has_capability(ptp, CAP_MAC_OVERRIDE))
  static int smack_syslog(int typefrom_file)
  {
        int rc = 0;
 -      char *sp = current_security();
 +      char *sp = smk_of_current();
  
        if (capable(CAP_MAC_OVERRIDE))
                return 0;
@@@ -396,40 -391,6 +396,40 @@@ static int smack_sb_umount(struct vfsmo
  }
  
  /*
 + * BPRM hooks
 + */
 +
 +static int smack_bprm_set_creds(struct linux_binprm *bprm)
 +{
 +      struct task_smack *tsp = bprm->cred->security;
 +      struct inode_smack *isp;
 +      struct dentry *dp;
 +      int rc;
 +
 +      rc = cap_bprm_set_creds(bprm);
 +      if (rc != 0)
 +              return rc;
 +
 +      if (bprm->cred_prepared)
 +              return 0;
 +
 +      if (bprm->file == NULL || bprm->file->f_dentry == NULL)
 +              return 0;
 +
 +      dp = bprm->file->f_dentry;
 +
 +      if (dp->d_inode == NULL)
 +              return 0;
 +
 +      isp = dp->d_inode->i_security;
 +
 +      if (isp->smk_task != NULL)
 +              tsp->smk_task = isp->smk_task;
 +
 +      return 0;
 +}
 +
 +/*
   * Inode hooks
   */
  
   */
  static int smack_inode_alloc_security(struct inode *inode)
  {
 -      inode->i_security = new_inode_smack(current_security());
 +      inode->i_security = new_inode_smack(smk_of_current());
        if (inode->i_security == NULL)
                return -ENOMEM;
        return 0;
@@@ -473,8 -434,6 +473,8 @@@ static int smack_inode_init_security(st
                                     char **name, void **value, size_t *len)
  {
        char *isp = smk_of_inode(inode);
 +      char *dsp = smk_of_inode(dir);
 +      u32 may;
  
        if (name) {
                *name = kstrdup(XATTR_SMACK_SUFFIX, GFP_KERNEL);
        }
  
        if (value) {
 +              may = smk_access_entry(smk_of_current(), dsp);
 +
 +              /*
 +               * If the access rule allows transmutation and
 +               * the directory requests transmutation then
 +               * by all means transmute.
 +               */
 +              if (((may & MAY_TRANSMUTE) != 0) && smk_inode_transmutable(dir))
 +                      isp = dsp;
 +
                *value = kstrdup(isp, GFP_KERNEL);
                if (*value == NULL)
                        return -ENOMEM;
@@@ -715,8 -664,7 +715,8 @@@ static int smack_inode_setxattr(struct 
  
        if (strcmp(name, XATTR_NAME_SMACK) == 0 ||
            strcmp(name, XATTR_NAME_SMACKIPIN) == 0 ||
 -          strcmp(name, XATTR_NAME_SMACKIPOUT) == 0) {
 +          strcmp(name, XATTR_NAME_SMACKIPOUT) == 0 ||
 +          strcmp(name, XATTR_NAME_SMACKEXEC) == 0) {
                if (!capable(CAP_MAC_ADMIN))
                        rc = -EPERM;
                /*
                if (size == 0 || size >= SMK_LABELLEN ||
                    smk_import(value, size) == NULL)
                        rc = -EINVAL;
 +      } else if (strcmp(name, XATTR_NAME_SMACKTRANSMUTE) == 0) {
 +              if (!capable(CAP_MAC_ADMIN))
 +                      rc = -EPERM;
 +              if (size != TRANS_TRUE_SIZE ||
 +                  strncmp(value, TRANS_TRUE, TRANS_TRUE_SIZE) != 0)
 +                      rc = -EINVAL;
        } else
                rc = cap_inode_setxattr(dentry, name, value, size, flags);
  
  static void smack_inode_post_setxattr(struct dentry *dentry, const char *name,
                                      const void *value, size_t size, int flags)
  {
 -      struct inode_smack *isp;
        char *nsp;
 +      struct inode_smack *isp = dentry->d_inode->i_security;
  
 -      /*
 -       * Not SMACK
 -       */
 -      if (strcmp(name, XATTR_NAME_SMACK))
 -              return;
 -
 -      isp = dentry->d_inode->i_security;
 -
 -      /*
 -       * No locking is done here. This is a pointer
 -       * assignment.
 -       */
 -      nsp = smk_import(value, size);
 -      if (nsp != NULL)
 -              isp->smk_inode = nsp;
 -      else
 -              isp->smk_inode = smack_known_invalid.smk_known;
 +      if (strcmp(name, XATTR_NAME_SMACK) == 0) {
 +              nsp = smk_import(value, size);
 +              if (nsp != NULL)
 +                      isp->smk_inode = nsp;
 +              else
 +                      isp->smk_inode = smack_known_invalid.smk_known;
 +      } else if (strcmp(name, XATTR_NAME_SMACKEXEC) == 0) {
 +              nsp = smk_import(value, size);
 +              if (nsp != NULL)
 +                      isp->smk_task = nsp;
 +              else
 +                      isp->smk_task = smack_known_invalid.smk_known;
 +      } else if (strcmp(name, XATTR_NAME_SMACKTRANSMUTE) == 0)
 +              isp->smk_flags |= SMK_INODE_TRANSMUTE;
  
        return;
  }
@@@ -807,15 -752,12 +807,15 @@@ static int smack_inode_getxattr(struct 
   */
  static int smack_inode_removexattr(struct dentry *dentry, const char *name)
  {
 +      struct inode_smack *isp;
        struct smk_audit_info ad;
        int rc = 0;
  
        if (strcmp(name, XATTR_NAME_SMACK) == 0 ||
            strcmp(name, XATTR_NAME_SMACKIPIN) == 0 ||
 -          strcmp(name, XATTR_NAME_SMACKIPOUT) == 0) {
 +          strcmp(name, XATTR_NAME_SMACKIPOUT) == 0 ||
 +          strcmp(name, XATTR_NAME_SMACKEXEC) == 0 ||
 +          strcmp(name, XATTR_NAME_SMACKTRANSMUTE) == 0) {
                if (!capable(CAP_MAC_ADMIN))
                        rc = -EPERM;
        } else
        if (rc == 0)
                rc = smk_curacc(smk_of_inode(dentry->d_inode), MAY_WRITE, &ad);
  
 +      if (rc == 0) {
 +              isp = dentry->d_inode->i_security;
 +              isp->smk_task = NULL;
 +      }
 +
        return rc;
  }
  
@@@ -958,7 -895,7 +958,7 @@@ static int smack_file_permission(struc
   */
  static int smack_file_alloc_security(struct file *file)
  {
 -      file->f_security = current_security();
 +      file->f_security = smk_of_current();
        return 0;
  }
  
@@@ -1068,7 -1005,7 +1068,7 @@@ static int smack_file_fcntl(struct fil
   */
  static int smack_file_set_fowner(struct file *file)
  {
 -      file->f_security = current_security();
 +      file->f_security = smk_of_current();
        return 0;
  }
  
@@@ -1088,7 -1025,7 +1088,7 @@@ static int smack_file_send_sigiotask(st
  {
        struct file *file;
        int rc;
 -      char *tsp = tsk->cred->security;
 +      char *tsp = smk_of_task(tsk->cred->security);
        struct smk_audit_info ad;
  
        /*
@@@ -1145,9 -1082,7 +1145,9 @@@ static int smack_file_receive(struct fi
   */
  static int smack_cred_alloc_blank(struct cred *cred, gfp_t gfp)
  {
 -      cred->security = NULL;
 +      cred->security = kzalloc(sizeof(struct task_smack), gfp);
 +      if (cred->security == NULL)
 +              return -ENOMEM;
        return 0;
  }
  
   */
  static void smack_cred_free(struct cred *cred)
  {
 -      cred->security = NULL;
 +      kfree(cred->security);
  }
  
  /**
  static int smack_cred_prepare(struct cred *new, const struct cred *old,
                              gfp_t gfp)
  {
 -      new->security = old->security;
 +      struct task_smack *old_tsp = old->security;
 +      struct task_smack *new_tsp;
 +
 +      new_tsp = kzalloc(sizeof(struct task_smack), gfp);
 +      if (new_tsp == NULL)
 +              return -ENOMEM;
 +
 +      new_tsp->smk_task = old_tsp->smk_task;
 +      new_tsp->smk_forked = old_tsp->smk_task;
 +      new->security = new_tsp;
        return 0;
  }
  
   */
  static void smack_cred_transfer(struct cred *new, const struct cred *old)
  {
 -      new->security = old->security;
 +      struct task_smack *old_tsp = old->security;
 +      struct task_smack *new_tsp = new->security;
 +
 +      new_tsp->smk_task = old_tsp->smk_task;
 +      new_tsp->smk_forked = old_tsp->smk_task;
  }
  
  /**
   */
  static int smack_kernel_act_as(struct cred *new, u32 secid)
  {
 +      struct task_smack *new_tsp = new->security;
        char *smack = smack_from_secid(secid);
  
        if (smack == NULL)
                return -EINVAL;
  
 -      new->security = smack;
 +      new_tsp->smk_task = smack;
        return 0;
  }
  
@@@ -1236,10 -1157,8 +1236,10 @@@ static int smack_kernel_create_files_as
                                        struct inode *inode)
  {
        struct inode_smack *isp = inode->i_security;
 +      struct task_smack *tsp = new->security;
  
 -      new->security = isp->smk_inode;
 +      tsp->smk_forked = isp->smk_inode;
 +      tsp->smk_task = isp->smk_inode;
        return 0;
  }
  
@@@ -1256,7 -1175,7 +1256,7 @@@ static int smk_curacc_on_task(struct ta
  
        smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_TASK);
        smk_ad_setfield_u_tsk(&ad, p);
 -      return smk_curacc(task_security(p), access, &ad);
 +      return smk_curacc(smk_of_task(task_security(p)), access, &ad);
  }
  
  /**
@@@ -1302,7 -1221,7 +1302,7 @@@ static int smack_task_getsid(struct tas
   */
  static void smack_task_getsecid(struct task_struct *p, u32 *secid)
  {
 -      *secid = smack_to_secid(task_security(p));
 +      *secid = smack_to_secid(smk_of_task(task_security(p)));
  }
  
  /**
@@@ -1414,15 -1333,14 +1414,15 @@@ static int smack_task_kill(struct task_
         * can write the receiver.
         */
        if (secid == 0)
 -              return smk_curacc(task_security(p), MAY_WRITE, &ad);
 +              return smk_curacc(smk_of_task(task_security(p)), MAY_WRITE,
 +                                &ad);
        /*
         * If the secid isn't 0 we're dealing with some USB IO
         * specific behavior. This is not clean. For one thing
         * we can't take privilege into account.
         */
 -      return smk_access(smack_from_secid(secid), task_security(p),
 -                        MAY_WRITE, &ad);
 +      return smk_access(smack_from_secid(secid),
 +                        smk_of_task(task_security(p)), MAY_WRITE, &ad);
  }
  
  /**
  static int smack_task_wait(struct task_struct *p)
  {
        struct smk_audit_info ad;
 -      char *sp = current_security();
 -      char *tsp = task_security(p);
 +      char *sp = smk_of_current();
 +      char *tsp = smk_of_forked(task_security(p));
        int rc;
  
        /* we don't log here, we can be overriden */
 -      rc = smk_access(sp, tsp, MAY_WRITE, NULL);
 +      rc = smk_access(tsp, sp, MAY_WRITE, NULL);
        if (rc == 0)
                goto out_log;
  
   out_log:
        smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_TASK);
        smk_ad_setfield_u_tsk(&ad, p);
 -      smack_log(sp, tsp, MAY_WRITE, rc, &ad);
 +      smack_log(tsp, sp, MAY_WRITE, rc, &ad);
        return rc;
  }
  
  static void smack_task_to_inode(struct task_struct *p, struct inode *inode)
  {
        struct inode_smack *isp = inode->i_security;
 -      isp->smk_inode = task_security(p);
 +      isp->smk_inode = smk_of_task(task_security(p));
  }
  
  /*
   */
  static int smack_sk_alloc_security(struct sock *sk, int family, gfp_t gfp_flags)
  {
 -      char *csp = current_security();
 +      char *csp = smk_of_current();
        struct socket_smack *ssp;
  
        ssp = kzalloc(sizeof(struct socket_smack), gfp_flags);
@@@ -1749,13 -1667,10 +1749,13 @@@ static int smack_inode_setsecurity(stru
                ssp->smk_in = sp;
        else if (strcmp(name, XATTR_SMACK_IPOUT) == 0) {
                ssp->smk_out = sp;
 -              rc = smack_netlabel(sock->sk, SMACK_CIPSO_SOCKET);
 -              if (rc != 0)
 -                      printk(KERN_WARNING "Smack: \"%s\" netlbl error %d.\n",
 -                             __func__, -rc);
 +              if (sock->sk->sk_family != PF_UNIX) {
 +                      rc = smack_netlabel(sock->sk, SMACK_CIPSO_SOCKET);
 +                      if (rc != 0)
 +                              printk(KERN_WARNING
 +                                      "Smack: \"%s\" netlbl error %d.\n",
 +                                      __func__, -rc);
 +              }
        } else
                return -EOPNOTSUPP;
  
@@@ -1834,7 -1749,7 +1834,7 @@@ static int smack_flags_to_may(int flags
   */
  static int smack_msg_msg_alloc_security(struct msg_msg *msg)
  {
 -      msg->security = current_security();
 +      msg->security = smk_of_current();
        return 0;
  }
  
@@@ -1870,7 -1785,7 +1870,7 @@@ static int smack_shm_alloc_security(str
  {
        struct kern_ipc_perm *isp = &shp->shm_perm;
  
 -      isp->security = current_security();
 +      isp->security = smk_of_current();
        return 0;
  }
  
@@@ -1993,7 -1908,7 +1993,7 @@@ static int smack_sem_alloc_security(str
  {
        struct kern_ipc_perm *isp = &sma->sem_perm;
  
 -      isp->security = current_security();
 +      isp->security = smk_of_current();
        return 0;
  }
  
@@@ -2111,7 -2026,7 +2111,7 @@@ static int smack_msg_queue_alloc_securi
  {
        struct kern_ipc_perm *kisp = &msq->q_perm;
  
 -      kisp->security = current_security();
 +      kisp->security = smk_of_current();
        return 0;
  }
  
@@@ -2283,11 -2198,9 +2283,11 @@@ static void smack_d_instantiate(struct 
        struct super_block *sbp;
        struct superblock_smack *sbsp;
        struct inode_smack *isp;
 -      char *csp = current_security();
 +      char *csp = smk_of_current();
        char *fetched;
        char *final;
 +      char trattr[TRANS_TRUE_SIZE];
 +      int transflag = 0;
        struct dentry *dp;
  
        if (inode == NULL)
                break;
        case SOCKFS_MAGIC:
                /*
 -               * Casey says sockets get the smack of the task.
 +               * Socket access is controlled by the socket
 +               * structures associated with the task involved.
                 */
 -              final = csp;
 +              final = smack_known_star.smk_known;
                break;
        case PROC_SUPER_MAGIC:
                /*
                /*
                 * This isn't an understood special case.
                 * Get the value from the xattr.
 -               *
 +               */
 +
 +              /*
 +               * UNIX domain sockets use lower level socket data.
 +               */
 +              if (S_ISSOCK(inode->i_mode)) {
 +                      final = smack_known_star.smk_known;
 +                      break;
 +              }
 +              /*
                 * No xattr support means, alas, no SMACK label.
                 * Use the aforeapplied default.
                 * It would be curious if the label of the task
                 * Get the dentry for xattr.
                 */
                dp = dget(opt_dentry);
 -              fetched = smk_fetch(inode, dp);
 -              if (fetched != NULL)
 +              fetched = smk_fetch(XATTR_NAME_SMACK, inode, dp);
 +              if (fetched != NULL) {
                        final = fetched;
 +                      if (S_ISDIR(inode->i_mode)) {
 +                              trattr[0] = '\0';
 +                              inode->i_op->getxattr(dp,
 +                                      XATTR_NAME_SMACKTRANSMUTE,
 +                                      trattr, TRANS_TRUE_SIZE);
 +                              if (strncmp(trattr, TRANS_TRUE,
 +                                          TRANS_TRUE_SIZE) == 0)
 +                                      transflag = SMK_INODE_TRANSMUTE;
 +                      }
 +              }
 +              isp->smk_task = smk_fetch(XATTR_NAME_SMACKEXEC, inode, dp);
 +
                dput(dp);
                break;
        }
        else
                isp->smk_inode = final;
  
 -      isp->smk_flags |= SMK_INODE_INSTANT;
 +      isp->smk_flags |= (SMK_INODE_INSTANT | transflag);
  
  unlockandout:
        mutex_unlock(&isp->smk_lock);
@@@ -2454,7 -2345,7 +2454,7 @@@ static int smack_getprocattr(struct tas
        if (strcmp(name, "current") != 0)
                return -EINVAL;
  
 -      cp = kstrdup(task_security(p), GFP_KERNEL);
 +      cp = kstrdup(smk_of_task(task_security(p)), GFP_KERNEL);
        if (cp == NULL)
                return -ENOMEM;
  
  static int smack_setprocattr(struct task_struct *p, char *name,
                             void *value, size_t size)
  {
 +      struct task_smack *tsp;
 +      struct task_smack *oldtsp;
        struct cred *new;
        char *newsmack;
  
        if (newsmack == smack_known_web.smk_known)
                return -EPERM;
  
 +      oldtsp = p->cred->security;
        new = prepare_creds();
        if (new == NULL)
                return -ENOMEM;
 -      new->security = newsmack;
 +      tsp = kzalloc(sizeof(struct task_smack), GFP_KERNEL);
 +      if (tsp == NULL) {
 +              kfree(new);
 +              return -ENOMEM;
 +      }
 +      tsp->smk_task = newsmack;
 +      tsp->smk_forked = oldtsp->smk_forked;
 +      new->security = tsp;
        commit_creds(new);
        return size;
  }
  
  /**
   * smack_unix_stream_connect - Smack access on UDS
-  * @sock: one socket
-  * @other: the other socket
+  * @sock: one sock
+  * @other: the other sock
   * @newsk: unused
   *
   * Return 0 if a subject with the smack of sock could access
   * an object with the smack of other, otherwise an error code
   */
- static int smack_unix_stream_connect(struct socket *sock,
-                                    struct socket *other, struct sock *newsk)
+ static int smack_unix_stream_connect(struct sock *sock,
+                                    struct sock *other, struct sock *newsk)
  {
-       struct socket_smack *ssp = sock->sk->sk_security;
-       struct socket_smack *osp = other->sk->sk_security;
 -      struct inode *sp = SOCK_INODE(sock->sk_socket);
 -      struct inode *op = SOCK_INODE(other->sk_socket);
++      struct socket_smack *ssp = sock->sk_security;
++      struct socket_smack *osp = other->sk_security;
        struct smk_audit_info ad;
 +      int rc = 0;
  
        smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_NET);
-       smk_ad_setfield_u_net_sk(&ad, other->sk);
+       smk_ad_setfield_u_net_sk(&ad, other);
 -      return smk_access(smk_of_inode(sp), smk_of_inode(op),
 -                               MAY_READWRITE, &ad);
 +
 +      if (!capable(CAP_MAC_OVERRIDE))
 +              rc = smk_access(ssp->smk_out, osp->smk_in, MAY_WRITE, &ad);
 +
 +      return rc;
  }
  
  /**
   */
  static int smack_unix_may_send(struct socket *sock, struct socket *other)
  {
 -      struct inode *sp = SOCK_INODE(sock);
 -      struct inode *op = SOCK_INODE(other);
 +      struct socket_smack *ssp = sock->sk->sk_security;
 +      struct socket_smack *osp = other->sk->sk_security;
        struct smk_audit_info ad;
 +      int rc = 0;
  
        smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_NET);
        smk_ad_setfield_u_net_sk(&ad, other->sk);
 -      return smk_access(smk_of_inode(sp), smk_of_inode(op), MAY_WRITE, &ad);
 +
 +      if (!capable(CAP_MAC_OVERRIDE))
 +              rc = smk_access(ssp->smk_out, osp->smk_in, MAY_WRITE, &ad);
 +
 +      return rc;
  }
  
  /**
@@@ -2757,7 -2629,7 +2757,7 @@@ static int smack_socket_getpeersec_stre
  
  /**
   * smack_socket_getpeersec_dgram - pull in packet label
 - * @sock: the socket
 + * @sock: the peer socket
   * @skb: packet data
   * @secid: pointer to where to put the secid of the packet
   *
@@@ -2768,39 -2640,41 +2768,39 @@@ static int smack_socket_getpeersec_dgra
  
  {
        struct netlbl_lsm_secattr secattr;
 -      struct sock *sk;
 +      struct socket_smack *sp;
        char smack[SMK_LABELLEN];
 -      int family = PF_INET;
 -      u32 s;
 +      int family = PF_UNSPEC;
 +      u32 s = 0;      /* 0 is the invalid secid */
        int rc;
  
 -      /*
 -       * Only works for families with packets.
 -       */
 -      if (sock != NULL) {
 -              sk = sock->sk;
 -              if (sk->sk_family != PF_INET && sk->sk_family != PF_INET6)
 -                      return 0;
 -              family = sk->sk_family;
 +      if (skb != NULL) {
 +              if (skb->protocol == htons(ETH_P_IP))
 +                      family = PF_INET;
 +              else if (skb->protocol == htons(ETH_P_IPV6))
 +                      family = PF_INET6;
        }
 -      /*
 -       * Translate what netlabel gave us.
 -       */
 -      netlbl_secattr_init(&secattr);
 -      rc = netlbl_skbuff_getattr(skb, family, &secattr);
 -      if (rc == 0)
 -              smack_from_secattr(&secattr, smack);
 -      netlbl_secattr_destroy(&secattr);
 +      if (family == PF_UNSPEC && sock != NULL)
 +              family = sock->sk->sk_family;
  
 -      /*
 -       * Give up if we couldn't get anything
 -       */
 -      if (rc != 0)
 -              return rc;
 -
 -      s = smack_to_secid(smack);
 +      if (family == PF_UNIX) {
 +              sp = sock->sk->sk_security;
 +              s = smack_to_secid(sp->smk_out);
 +      } else if (family == PF_INET || family == PF_INET6) {
 +              /*
 +               * Translate what netlabel gave us.
 +               */
 +              netlbl_secattr_init(&secattr);
 +              rc = netlbl_skbuff_getattr(skb, family, &secattr);
 +              if (rc == 0) {
 +                      smack_from_secattr(&secattr, smack);
 +                      s = smack_to_secid(smack);
 +              }
 +              netlbl_secattr_destroy(&secattr);
 +      }
 +      *secid = s;
        if (s == 0)
                return -EINVAL;
 -
 -      *secid = s;
        return 0;
  }
  
@@@ -2821,7 -2695,7 +2821,7 @@@ static void smack_sock_graft(struct soc
                return;
  
        ssp = sk->sk_security;
 -      ssp->smk_in = ssp->smk_out = current_security();
 +      ssp->smk_in = ssp->smk_out = smk_of_current();
        /* cssp->smk_packet is already set in smack_inet_csk_clone() */
  }
  
@@@ -2942,7 -2816,7 +2942,7 @@@ static void smack_inet_csk_clone(struc
  static int smack_key_alloc(struct key *key, const struct cred *cred,
                           unsigned long flags)
  {
 -      key->security = cred->security;
 +      key->security = smk_of_task(cred->security);
        return 0;
  }
  
@@@ -2971,7 -2845,6 +2971,7 @@@ static int smack_key_permission(key_ref
  {
        struct key *keyp;
        struct smk_audit_info ad;
 +      char *tsp = smk_of_task(cred->security);
  
        keyp = key_ref_to_ptr(key_ref);
        if (keyp == NULL)
        /*
         * This should not occur
         */
 -      if (cred->security == NULL)
 +      if (tsp == NULL)
                return -EACCES;
  #ifdef CONFIG_AUDIT
        smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_KEY);
        ad.a.u.key_struct.key = keyp->serial;
        ad.a.u.key_struct.key_desc = keyp->description;
  #endif
 -      return smk_access(cred->security, keyp->security,
 +      return smk_access(tsp, keyp->security,
                                 MAY_READWRITE, &ad);
  }
  #endif /* CONFIG_KEYS */
@@@ -3194,8 -3067,6 +3194,8 @@@ struct security_operations smack_ops = 
        .sb_mount =                     smack_sb_mount,
        .sb_umount =                    smack_sb_umount,
  
 +      .bprm_set_creds =               smack_bprm_set_creds,
 +
        .inode_alloc_security =         smack_inode_alloc_security,
        .inode_free_security =          smack_inode_free_security,
        .inode_init_security =          smack_inode_init_security,
@@@ -3332,16 -3203,9 +3332,16 @@@ static __init void init_smack_know_list
  static __init int smack_init(void)
  {
        struct cred *cred;
 +      struct task_smack *tsp;
  
 -      if (!security_module_enable(&smack_ops))
 +      tsp = kzalloc(sizeof(struct task_smack), GFP_KERNEL);
 +      if (tsp == NULL)
 +              return -ENOMEM;
 +
 +      if (!security_module_enable(&smack_ops)) {
 +              kfree(tsp);
                return 0;
 +      }
  
        printk(KERN_INFO "Smack:  Initializing.\n");
  
         * Set the security state for the initial task.
         */
        cred = (struct cred *) current->cred;
 -      cred->security = &smack_known_floor.smk_known;
 +      tsp->smk_forked = smack_known_floor.smk_known;
 +      tsp->smk_task = smack_known_floor.smk_known;
 +      cred->security = tsp;
  
        /* initialize the smack_know_list */
        init_smack_know_list();