Merge branch 'stable-4.11' of git://git.infradead.org/users/pcmoore/audit
authorLinus Torvalds <torvalds@linux-foundation.org>
Tue, 21 Feb 2017 21:25:50 +0000 (13:25 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Tue, 21 Feb 2017 21:25:50 +0000 (13:25 -0800)
Pull audit updates from Paul Moore:
 "The audit changes for v4.11 are relatively small compared to what we
  did for v4.10, both in terms of size and impact.

   - two patches from Steve tweak the formatting for some of the audit
     records to make them more consistent with other audit records.

   - three patches from Richard record the name of a module on module
     load, fix the logging of sockaddr information when using
     socketcall() on 32-bit systems, and add the ability to reset
     audit's lost record counter.

   - my lone patch just fixes an annoying style nit that I was reminded
     about by one of Richard's patches.

  All these patches pass our test suite"

* 'stable-4.11' of git://git.infradead.org/users/pcmoore/audit:
  audit: remove unnecessary curly braces from switch/case statements
  audit: log module name on init_module
  audit: log 32-bit socketcalls
  audit: add feature audit_lost reset
  audit: Make AUDIT_ANOM_ABEND event normalized
  audit: Make AUDIT_KERNEL event conform to the specification

1  2 
include/linux/audit.h
include/uapi/linux/audit.h
kernel/audit.c
kernel/audit.h
kernel/auditsc.c
kernel/module.c
net/compat.c

diff --combined include/linux/audit.h
index f51fca8d0b6f86f4229a3ff487c39c18ad1a92c4,aba3a2684300d77bf9fbb70ad56461dfbc1e189e..504e784b7ffa6da23212a0a0d110efe91774eb27
@@@ -147,7 -147,7 +147,7 @@@ extern void                    audit_log_d_path(struc
  extern void               audit_log_key(struct audit_buffer *ab,
                                          char *key);
  extern void               audit_log_link_denied(const char *operation,
 -                                                struct path *link);
 +                                                const struct path *link);
  extern void               audit_log_lost(const char *message);
  #ifdef CONFIG_SECURITY
  extern void               audit_log_secctx(struct audit_buffer *ab, u32 secid);
@@@ -360,6 -360,7 +360,7 @@@ extern int __audit_log_bprm_fcaps(struc
                                  const struct cred *old);
  extern void __audit_log_capset(const struct cred *new, const struct cred *old);
  extern void __audit_mmap_fd(int fd, int flags);
+ extern void __audit_log_kern_module(char *name);
  
  static inline void audit_ipc_obj(struct kern_ipc_perm *ipcp)
  {
@@@ -387,6 -388,20 +388,20 @@@ static inline int audit_socketcall(int 
                return __audit_socketcall(nargs, args);
        return 0;
  }
+ static inline int audit_socketcall_compat(int nargs, u32 *args)
+ {
+       unsigned long a[AUDITSC_ARGS];
+       int i;
+       if (audit_dummy_context())
+               return 0;
+       for (i = 0; i < nargs; i++)
+               a[i] = (unsigned long)args[i];
+       return __audit_socketcall(nargs, a);
+ }
  static inline int audit_sockaddr(int len, void *addr)
  {
        if (unlikely(!audit_dummy_context()))
@@@ -436,6 -451,12 +451,12 @@@ static inline void audit_mmap_fd(int fd
                __audit_mmap_fd(fd, flags);
  }
  
+ static inline void audit_log_kern_module(char *name)
+ {
+       if (!audit_dummy_context())
+               __audit_log_kern_module(name);
+ }
  extern int audit_n_rules;
  extern int audit_signals;
  #else /* CONFIG_AUDITSYSCALL */
@@@ -513,6 -534,12 +534,12 @@@ static inline int audit_socketcall(int 
  {
        return 0;
  }
+ static inline int audit_socketcall_compat(int nargs, u32 *args)
+ {
+       return 0;
+ }
  static inline void audit_fd_pair(int fd1, int fd2)
  { }
  static inline int audit_sockaddr(int len, void *addr)
@@@ -541,6 -568,11 +568,11 @@@ static inline void audit_log_capset(con
  { }
  static inline void audit_mmap_fd(int fd, int flags)
  { }
+ static inline void audit_log_kern_module(char *name)
+ {
+ }
  static inline void audit_ptrace(struct task_struct *t)
  { }
  #define audit_n_rules 0
index 1c107cb1c83f80236cac0234a456d665bb9b7a15,3c02bb2ff779d2e3a313bb5eadf3a43e029aa814..0714a66f0e0cd6018758d991163b1de1f6326dd2
  #define AUDIT_PROCTITLE               1327    /* Proctitle emit event */
  #define AUDIT_FEATURE_CHANGE  1328    /* audit log listing feature changes */
  #define AUDIT_REPLACE         1329    /* Replace auditd if this packet unanswerd */
+ #define AUDIT_KERN_MODULE     1330    /* Kernel Module events */
  
  #define AUDIT_AVC             1400    /* SE Linux avc denial or grant */
  #define AUDIT_SELINUX_ERR     1401    /* Internal SE Linux Errors */
@@@ -326,17 -327,19 +327,21 @@@ enum 
  #define AUDIT_STATUS_RATE_LIMIT               0x0008
  #define AUDIT_STATUS_BACKLOG_LIMIT    0x0010
  #define AUDIT_STATUS_BACKLOG_WAIT_TIME        0x0020
+ #define AUDIT_STATUS_LOST             0x0040
  
  #define AUDIT_FEATURE_BITMAP_BACKLOG_LIMIT    0x00000001
  #define AUDIT_FEATURE_BITMAP_BACKLOG_WAIT_TIME        0x00000002
  #define AUDIT_FEATURE_BITMAP_EXECUTABLE_PATH  0x00000004
 +#define AUDIT_FEATURE_BITMAP_EXCLUDE_EXTEND   0x00000008
  #define AUDIT_FEATURE_BITMAP_SESSIONID_FILTER 0x00000010
+ #define AUDIT_FEATURE_BITMAP_LOST_RESET               0x00000020
  #define AUDIT_FEATURE_BITMAP_ALL (AUDIT_FEATURE_BITMAP_BACKLOG_LIMIT | \
                                  AUDIT_FEATURE_BITMAP_BACKLOG_WAIT_TIME | \
                                  AUDIT_FEATURE_BITMAP_EXECUTABLE_PATH | \
-                                 AUDIT_FEATURE_BITMAP_SESSIONID_FILTER)
 +                                AUDIT_FEATURE_BITMAP_EXCLUDE_EXTEND | \
+                                 AUDIT_FEATURE_BITMAP_SESSIONID_FILTER | \
+                                 AUDIT_FEATURE_BITMAP_LOST_RESET)
  
  /* deprecated: AUDIT_VERSION_* */
  #define AUDIT_VERSION_LATEST          AUDIT_FEATURE_BITMAP_ALL
diff --combined kernel/audit.c
index 6e399bb69d7c6ab54ddf22d2d908c630c0d17fc0,25dd70a588b27b6ede925fce4244f4bc173012e6..e794544f5e63334afccadf6cc70f5fb2541e1e2e
@@@ -121,11 -121,11 +121,11 @@@ u32             audit_sig_sid = 0
     3) suppressed due to audit_rate_limit
     4) suppressed due to audit_backlog_limit
  */
- static atomic_t    audit_lost = ATOMIC_INIT(0);
+ static atomic_t       audit_lost = ATOMIC_INIT(0);
  
  /* The netlink socket. */
  static struct sock *audit_sock;
 -static int audit_net_id;
 +static unsigned int audit_net_id;
  
  /* Hash for inode-based rules */
  struct list_head audit_inode_hash[AUDIT_INODE_BUCKETS];
@@@ -1007,12 -1007,6 +1007,12 @@@ static int audit_receive_msg(struct sk_
                                return err;
                }
                if (s.mask & AUDIT_STATUS_PID) {
 +                      /* NOTE: we are using task_tgid_vnr() below because
 +                       *       the s.pid value is relative to the namespace
 +                       *       of the caller; at present this doesn't matter
 +                       *       much since you can really only run auditd
 +                       *       from the initial pid namespace, but something
 +                       *       to keep in mind if this changes */
                        int new_pid = s.pid;
                        pid_t requesting_pid = task_tgid_vnr(current);
  
                        if (err < 0)
                                return err;
                }
+               if (s.mask == AUDIT_STATUS_LOST) {
+                       u32 lost = atomic_xchg(&audit_lost, 0);
+                       audit_log_config_change("lost", 0, lost, 1);
+                       return lost;
+               }
                break;
        }
        case AUDIT_GET_FEATURE:
@@@ -1310,8 -1310,9 +1316,8 @@@ static void __net_exit audit_net_exit(s
                auditd_reset();
        mutex_unlock(&audit_cmd_mutex);
  
 -      RCU_INIT_POINTER(aunet->nlsk, NULL);
 -      synchronize_net();
        netlink_kernel_release(sock);
 +      aunet->nlsk = NULL;
  }
  
  static struct pernet_operations audit_net_ops __net_initdata = {
@@@ -1349,7 -1350,9 +1355,9 @@@ static int __init audit_init(void
                panic("audit: failed to start the kauditd thread (%d)\n", err);
        }
  
-       audit_log(NULL, GFP_KERNEL, AUDIT_KERNEL, "initialized");
+       audit_log(NULL, GFP_KERNEL, AUDIT_KERNEL,
+               "state=initialized audit_enabled=%u res=1",
+                audit_enabled);
  
        return 0;
  }
@@@ -1893,7 -1896,7 +1901,7 @@@ void audit_copy_inode(struct audit_name
   * @call_panic: optional pointer to int that will be updated if secid fails
   */
  void audit_log_name(struct audit_context *context, struct audit_names *n,
 -                  struct path *path, int record_num, int *call_panic)
 +                  const struct path *path, int record_num, int *call_panic)
  {
        struct audit_buffer *ab;
        ab = audit_log_start(context, GFP_KERNEL, AUDIT_PATH);
@@@ -2056,7 -2059,7 +2064,7 @@@ void audit_log_task_info(struct audit_b
                         " euid=%u suid=%u fsuid=%u"
                         " egid=%u sgid=%u fsgid=%u tty=%s ses=%u",
                         task_ppid_nr(tsk),
 -                       task_pid_nr(tsk),
 +                       task_tgid_nr(tsk),
                         from_kuid(&init_user_ns, audit_get_loginuid(tsk)),
                         from_kuid(&init_user_ns, cred->uid),
                         from_kgid(&init_user_ns, cred->gid),
@@@ -2081,7 -2084,7 +2089,7 @@@ EXPORT_SYMBOL(audit_log_task_info)
   * @operation: specific link operation
   * @link: the path that triggered the restriction
   */
 -void audit_log_link_denied(const char *operation, struct path *link)
 +void audit_log_link_denied(const char *operation, const struct path *link)
  {
        struct audit_buffer *ab;
        struct audit_names *name;
diff --combined kernel/audit.h
index 960d49c9db5e3c79b70171c6c9ca1f4d8acf58f2,144b7ebd2debc090a01a91e371253cfc13f86d71..ca579880303ab475b2c81839a4948bdb128e92f8
@@@ -199,6 -199,9 +199,9 @@@ struct audit_context 
                struct {
                        int                     argc;
                } execve;
+               struct {
+                       char                    *name;
+               } module;
        };
        int fds[2];
        struct audit_proctitle proctitle;
@@@ -212,7 -215,7 +215,7 @@@ extern void audit_copy_inode(struct aud
  extern void audit_log_cap(struct audit_buffer *ab, char *prefix,
                          kernel_cap_t *cap);
  extern void audit_log_name(struct audit_context *context,
 -                         struct audit_names *n, struct path *path,
 +                         struct audit_names *n, const struct path *path,
                           int record_num, int *call_panic);
  
  extern int audit_pid;
diff --combined kernel/auditsc.c
index cf1fa43512c111b6fff0a81403acb62f9a4620a4,4db32e8669f877105578d30d9e297ff93bf7e79b..d6a8de5f8fa3d0ba33c14b20e6341e32d62dab2a
@@@ -458,7 -458,7 +458,7 @@@ static int audit_filter_rules(struct ta
  
                switch (f->type) {
                case AUDIT_PID:
 -                      pid = task_pid_nr(tsk);
 +                      pid = task_tgid_nr(tsk);
                        result = audit_comparator(pid, f->op, f->val);
                        break;
                case AUDIT_PPID:
@@@ -1221,7 -1221,7 +1221,7 @@@ static void show_special(struct audit_c
                                context->ipc.perm_mode);
                }
                break; }
-       case AUDIT_MQ_OPEN: {
+       case AUDIT_MQ_OPEN:
                audit_log_format(ab,
                        "oflag=0x%x mode=%#ho mq_flags=0x%lx mq_maxmsg=%ld "
                        "mq_msgsize=%ld mq_curmsgs=%ld",
                        context->mq_open.attr.mq_maxmsg,
                        context->mq_open.attr.mq_msgsize,
                        context->mq_open.attr.mq_curmsgs);
-               break; }
-       case AUDIT_MQ_SENDRECV: {
+               break;
+       case AUDIT_MQ_SENDRECV:
                audit_log_format(ab,
                        "mqdes=%d msg_len=%zd msg_prio=%u "
                        "abs_timeout_sec=%ld abs_timeout_nsec=%ld",
                        context->mq_sendrecv.msg_prio,
                        context->mq_sendrecv.abs_timeout.tv_sec,
                        context->mq_sendrecv.abs_timeout.tv_nsec);
-               break; }
-       case AUDIT_MQ_NOTIFY: {
+               break;
+       case AUDIT_MQ_NOTIFY:
                audit_log_format(ab, "mqdes=%d sigev_signo=%d",
                                context->mq_notify.mqdes,
                                context->mq_notify.sigev_signo);
-               break; }
+               break;
        case AUDIT_MQ_GETSETATTR: {
                struct mq_attr *attr = &context->mq_getsetattr.mqstat;
                audit_log_format(ab,
                        attr->mq_flags, attr->mq_maxmsg,
                        attr->mq_msgsize, attr->mq_curmsgs);
                break; }
-       case AUDIT_CAPSET: {
+       case AUDIT_CAPSET:
                audit_log_format(ab, "pid=%d", context->capset.pid);
                audit_log_cap(ab, "cap_pi", &context->capset.cap.inheritable);
                audit_log_cap(ab, "cap_pp", &context->capset.cap.permitted);
                audit_log_cap(ab, "cap_pe", &context->capset.cap.effective);
-               break; }
-       case AUDIT_MMAP: {
+               break;
+       case AUDIT_MMAP:
                audit_log_format(ab, "fd=%d flags=0x%x", context->mmap.fd,
                                 context->mmap.flags);
-               break; }
-       case AUDIT_EXECVE: {
+               break;
+       case AUDIT_EXECVE:
                audit_log_execve_info(context, &ab);
-               break; }
+               break;
+       case AUDIT_KERN_MODULE:
+               audit_log_format(ab, "name=");
+               audit_log_untrustedstring(ab, context->module.name);
+               kfree(context->module.name);
+               break;
        }
        audit_log_end(ab);
  }
@@@ -1998,7 -2003,7 +2003,7 @@@ static void audit_log_set_loginuid(kuid
        loginuid = from_kuid(&init_user_ns, kloginuid),
        tty = audit_get_tty(current);
  
 -      audit_log_format(ab, "pid=%d uid=%u", task_pid_nr(current), uid);
 +      audit_log_format(ab, "pid=%d uid=%u", task_tgid_nr(current), uid);
        audit_log_task_context(ab);
        audit_log_format(ab, " old-auid=%u auid=%u tty=%s old-ses=%u ses=%u res=%d",
                         oldloginuid, loginuid, tty ? tty_name(tty) : "(none)",
@@@ -2228,7 -2233,7 +2233,7 @@@ void __audit_ptrace(struct task_struct 
  {
        struct audit_context *context = current->audit_context;
  
 -      context->target_pid = task_pid_nr(t);
 +      context->target_pid = task_tgid_nr(t);
        context->target_auid = audit_get_loginuid(t);
        context->target_uid = task_uid(t);
        context->target_sessionid = audit_get_sessionid(t);
@@@ -2253,7 -2258,7 +2258,7 @@@ int __audit_signal_info(int sig, struc
  
        if (audit_pid && t->tgid == audit_pid) {
                if (sig == SIGTERM || sig == SIGHUP || sig == SIGUSR1 || sig == SIGUSR2) {
 -                      audit_sig_pid = task_pid_nr(tsk);
 +                      audit_sig_pid = task_tgid_nr(tsk);
                        if (uid_valid(tsk->loginuid))
                                audit_sig_uid = tsk->loginuid;
                        else
@@@ -2353,7 -2358,7 +2358,7 @@@ int __audit_log_bprm_fcaps(struct linux
  void __audit_log_capset(const struct cred *new, const struct cred *old)
  {
        struct audit_context *context = current->audit_context;
 -      context->capset.pid = task_pid_nr(current);
 +      context->capset.pid = task_tgid_nr(current);
        context->capset.cap.effective   = new->cap_effective;
        context->capset.cap.inheritable = new->cap_effective;
        context->capset.cap.permitted   = new->cap_permitted;
@@@ -2368,6 -2373,15 +2373,15 @@@ void __audit_mmap_fd(int fd, int flags
        context->type = AUDIT_MMAP;
  }
  
+ void __audit_log_kern_module(char *name)
+ {
+       struct audit_context *context = current->audit_context;
+       context->module.name = kmalloc(strlen(name) + 1, GFP_KERNEL);
+       strcpy(context->module.name, name);
+       context->type = AUDIT_KERN_MODULE;
+ }
  static void audit_log_task(struct audit_buffer *ab)
  {
        kuid_t auid, uid;
                         from_kgid(&init_user_ns, gid),
                         sessionid);
        audit_log_task_context(ab);
 -      audit_log_format(ab, " pid=%d comm=", task_pid_nr(current));
 +      audit_log_format(ab, " pid=%d comm=", task_tgid_nr(current));
        audit_log_untrustedstring(ab, get_task_comm(comm, current));
        audit_log_d_path_exe(ab, current->mm);
  }
@@@ -2411,7 -2425,7 +2425,7 @@@ void audit_core_dumps(long signr
        if (unlikely(!ab))
                return;
        audit_log_task(ab);
-       audit_log_format(ab, " sig=%ld", signr);
+       audit_log_format(ab, " sig=%ld res=1", signr);
        audit_log_end(ab);
  }
  
diff --combined kernel/module.c
index 3d8f126208e3ae04eeff3fd1b1e00044c0e3d0d2,5432dbedf8cf87bb85a53ba4276951914d9e6f2a..e2eec4b47143d1f2930258b7ccc028efa7e71d4c
@@@ -46,7 -46,7 +46,7 @@@
  #include <linux/string.h>
  #include <linux/mutex.h>
  #include <linux/rculist.h>
 -#include <asm/uaccess.h>
 +#include <linux/uaccess.h>
  #include <asm/cacheflush.h>
  #include <asm/mmu_context.h>
  #include <linux/license.h>
@@@ -61,6 -61,7 +61,7 @@@
  #include <linux/pfn.h>
  #include <linux/bsearch.h>
  #include <linux/dynamic_debug.h>
+ #include <linux/audit.h>
  #include <uapi/linux/module.h>
  #include "module-internal.h"
  
@@@ -313,11 -314,8 +314,11 @@@ struct load_info 
        } index;
  };
  
 -/* We require a truly strong try_module_get(): 0 means failure due to
 -   ongoing or failed initialization etc. */
 +/*
 + * We require a truly strong try_module_get(): 0 means success.
 + * Otherwise an error is returned due to ongoing or failed
 + * initialization etc.
 + */
  static inline int strong_try_module_get(struct module *mod)
  {
        BUG_ON(mod && mod->state == MODULE_STATE_UNFORMED);
@@@ -333,7 -331,7 +334,7 @@@ static inline void add_taint_module(str
                                    enum lockdep_ok lockdep_ok)
  {
        add_taint(flag, lockdep_ok);
 -      mod->taints |= (1U << flag);
 +      set_bit(flag, &mod->taints);
  }
  
  /*
@@@ -389,16 -387,16 +390,16 @@@ extern const struct kernel_symbol __sta
  extern const struct kernel_symbol __stop___ksymtab_gpl[];
  extern const struct kernel_symbol __start___ksymtab_gpl_future[];
  extern const struct kernel_symbol __stop___ksymtab_gpl_future[];
 -extern const unsigned long __start___kcrctab[];
 -extern const unsigned long __start___kcrctab_gpl[];
 -extern const unsigned long __start___kcrctab_gpl_future[];
 +extern const s32 __start___kcrctab[];
 +extern const s32 __start___kcrctab_gpl[];
 +extern const s32 __start___kcrctab_gpl_future[];
  #ifdef CONFIG_UNUSED_SYMBOLS
  extern const struct kernel_symbol __start___ksymtab_unused[];
  extern const struct kernel_symbol __stop___ksymtab_unused[];
  extern const struct kernel_symbol __start___ksymtab_unused_gpl[];
  extern const struct kernel_symbol __stop___ksymtab_unused_gpl[];
 -extern const unsigned long __start___kcrctab_unused[];
 -extern const unsigned long __start___kcrctab_unused_gpl[];
 +extern const s32 __start___kcrctab_unused[];
 +extern const s32 __start___kcrctab_unused_gpl[];
  #endif
  
  #ifndef CONFIG_MODVERSIONS
@@@ -497,7 -495,7 +498,7 @@@ struct find_symbol_arg 
  
        /* Output */
        struct module *owner;
 -      const unsigned long *crc;
 +      const s32 *crc;
        const struct kernel_symbol *sym;
  };
  
@@@ -563,7 -561,7 +564,7 @@@ static bool find_symbol_in_section(cons
   * (optional) module which owns it.  Needs preempt disabled or module_mutex. */
  const struct kernel_symbol *find_symbol(const char *name,
                                        struct module **owner,
 -                                      const unsigned long **crc,
 +                                      const s32 **crc,
                                        bool gplok,
                                        bool warn)
  {
@@@ -1141,13 -1139,22 +1142,13 @@@ static inline int module_unload_init(st
  static size_t module_flags_taint(struct module *mod, char *buf)
  {
        size_t l = 0;
 +      int i;
 +
 +      for (i = 0; i < TAINT_FLAGS_COUNT; i++) {
 +              if (taint_flags[i].module && test_bit(i, &mod->taints))
 +                      buf[l++] = taint_flags[i].c_true;
 +      }
  
 -      if (mod->taints & (1 << TAINT_PROPRIETARY_MODULE))
 -              buf[l++] = 'P';
 -      if (mod->taints & (1 << TAINT_OOT_MODULE))
 -              buf[l++] = 'O';
 -      if (mod->taints & (1 << TAINT_FORCED_MODULE))
 -              buf[l++] = 'F';
 -      if (mod->taints & (1 << TAINT_CRAP))
 -              buf[l++] = 'C';
 -      if (mod->taints & (1 << TAINT_UNSIGNED_MODULE))
 -              buf[l++] = 'E';
 -      /*
 -       * TAINT_FORCED_RMMOD: could be added.
 -       * TAINT_CPU_OUT_OF_SPEC, TAINT_MACHINE_CHECK, TAINT_BAD_PAGE don't
 -       * apply to modules.
 -       */
        return l;
  }
  
@@@ -1249,17 -1256,23 +1250,17 @@@ static int try_to_force_load(struct mod
  }
  
  #ifdef CONFIG_MODVERSIONS
 -/* If the arch applies (non-zero) relocations to kernel kcrctab, unapply it. */
 -static unsigned long maybe_relocated(unsigned long crc,
 -                                   const struct module *crc_owner)
 +
 +static u32 resolve_rel_crc(const s32 *crc)
  {
 -#ifdef ARCH_RELOCATES_KCRCTAB
 -      if (crc_owner == NULL)
 -              return crc - (unsigned long)reloc_start;
 -#endif
 -      return crc;
 +      return *(u32 *)((void *)crc + *crc);
  }
  
  static int check_version(Elf_Shdr *sechdrs,
                         unsigned int versindex,
                         const char *symname,
                         struct module *mod,
 -                       const unsigned long *crc,
 -                       const struct module *crc_owner)
 +                       const s32 *crc)
  {
        unsigned int i, num_versions;
        struct modversion_info *versions;
                / sizeof(struct modversion_info);
  
        for (i = 0; i < num_versions; i++) {
 +              u32 crcval;
 +
                if (strcmp(versions[i].name, symname) != 0)
                        continue;
  
 -              if (versions[i].crc == maybe_relocated(*crc, crc_owner))
 +              if (IS_ENABLED(CONFIG_MODULE_REL_CRCS))
 +                      crcval = resolve_rel_crc(crc);
 +              else
 +                      crcval = *crc;
 +              if (versions[i].crc == crcval)
                        return 1;
 -              pr_debug("Found checksum %lX vs module %lX\n",
 -                     maybe_relocated(*crc, crc_owner), versions[i].crc);
 +              pr_debug("Found checksum %X vs module %lX\n",
 +                       crcval, versions[i].crc);
                goto bad_version;
        }
  
 -      pr_warn("%s: no symbol version for %s\n", mod->name, symname);
 -      return 0;
 +      /* Broken toolchain. Warn once, then let it go.. */
 +      pr_warn_once("%s: no symbol version for %s\n", mod->name, symname);
 +      return 1;
  
  bad_version:
        pr_warn("%s: disagrees about version of symbol %s\n",
@@@ -1307,7 -1313,7 +1308,7 @@@ static inline int check_modstruct_versi
                                          unsigned int versindex,
                                          struct module *mod)
  {
 -      const unsigned long *crc;
 +      const s32 *crc;
  
        /*
         * Since this should be found in kernel (which can't be removed), no
        }
        preempt_enable();
        return check_version(sechdrs, versindex,
 -                           VMLINUX_SYMBOL_STR(module_layout), mod, crc,
 -                           NULL);
 +                           VMLINUX_SYMBOL_STR(module_layout), mod, crc);
  }
  
  /* First part is kernel version, which we ignore if module has crcs. */
@@@ -1339,7 -1346,8 +1340,7 @@@ static inline int check_version(Elf_Shd
                                unsigned int versindex,
                                const char *symname,
                                struct module *mod,
 -                              const unsigned long *crc,
 -                              const struct module *crc_owner)
 +                              const s32 *crc)
  {
        return 1;
  }
@@@ -1366,7 -1374,7 +1367,7 @@@ static const struct kernel_symbol *reso
  {
        struct module *owner;
        const struct kernel_symbol *sym;
 -      const unsigned long *crc;
 +      const s32 *crc;
        int err;
  
        /*
        if (!sym)
                goto unlock;
  
 -      if (!check_version(info->sechdrs, info->index.vers, name, mod, crc,
 -                         owner)) {
 +      if (!check_version(info->sechdrs, info->index.vers, name, mod, crc)) {
                sym = ERR_PTR(-EINVAL);
                goto getname;
        }
@@@ -1900,9 -1909,6 +1901,9 @@@ static void frob_writable_data(const st
  /* livepatching wants to disable read-only so it can frob module. */
  void module_disable_ro(const struct module *mod)
  {
 +      if (!rodata_enabled)
 +              return;
 +
        frob_text(&mod->core_layout, set_memory_rw);
        frob_rodata(&mod->core_layout, set_memory_rw);
        frob_ro_after_init(&mod->core_layout, set_memory_rw);
  
  void module_enable_ro(const struct module *mod, bool after_init)
  {
 +      if (!rodata_enabled)
 +              return;
 +
        frob_text(&mod->core_layout, set_memory_ro);
        frob_rodata(&mod->core_layout, set_memory_ro);
        frob_text(&mod->init_layout, set_memory_ro);
@@@ -1947,9 -1950,6 +1948,9 @@@ void set_all_modules_text_rw(void
  {
        struct module *mod;
  
 +      if (!rodata_enabled)
 +              return;
 +
        mutex_lock(&module_mutex);
        list_for_each_entry_rcu(mod, &modules, list) {
                if (mod->state == MODULE_STATE_UNFORMED)
@@@ -1966,18 -1966,9 +1967,18 @@@ void set_all_modules_text_ro(void
  {
        struct module *mod;
  
 +      if (!rodata_enabled)
 +              return;
 +
        mutex_lock(&module_mutex);
        list_for_each_entry_rcu(mod, &modules, list) {
 -              if (mod->state == MODULE_STATE_UNFORMED)
 +              /*
 +               * Ignore going modules since it's possible that ro
 +               * protection has already been disabled, otherwise we'll
 +               * run into protection faults at module deallocation.
 +               */
 +              if (mod->state == MODULE_STATE_UNFORMED ||
 +                      mod->state == MODULE_STATE_GOING)
                        continue;
  
                frob_text(&mod->core_layout, set_memory_ro);
  
  static void disable_ro_nx(const struct module_layout *layout)
  {
 -      frob_text(layout, set_memory_rw);
 -      frob_rodata(layout, set_memory_rw);
 +      if (rodata_enabled) {
 +              frob_text(layout, set_memory_rw);
 +              frob_rodata(layout, set_memory_rw);
 +              frob_ro_after_init(layout, set_memory_rw);
 +      }
        frob_rodata(layout, set_memory_x);
 -      frob_ro_after_init(layout, set_memory_rw);
        frob_ro_after_init(layout, set_memory_x);
        frob_writable_data(layout, set_memory_x);
  }
@@@ -2804,17 -2793,14 +2805,17 @@@ static int copy_chunked_from_user(void 
  }
  
  #ifdef CONFIG_LIVEPATCH
 -static int find_livepatch_modinfo(struct module *mod, struct load_info *info)
 +static int check_modinfo_livepatch(struct module *mod, struct load_info *info)
  {
 -      mod->klp = get_modinfo(info, "livepatch") ? true : false;
 +      if (get_modinfo(info, "livepatch")) {
 +              mod->klp = true;
 +              add_taint_module(mod, TAINT_LIVEPATCH, LOCKDEP_STILL_OK);
 +      }
  
        return 0;
  }
  #else /* !CONFIG_LIVEPATCH */
 -static int find_livepatch_modinfo(struct module *mod, struct load_info *info)
 +static int check_modinfo_livepatch(struct module *mod, struct load_info *info)
  {
        if (get_modinfo(info, "livepatch")) {
                pr_err("%s: module is marked as livepatch module, but livepatch support is disabled",
@@@ -2984,7 -2970,7 +2985,7 @@@ static int check_modinfo(struct module 
                        "is unknown, you have been warned.\n", mod->name);
        }
  
 -      err = find_livepatch_modinfo(mod, info);
 +      err = check_modinfo_livepatch(mod, info);
        if (err)
                return err;
  
@@@ -3608,6 -3594,8 +3609,8 @@@ static int load_module(struct load_inf
                goto free_copy;
        }
  
+       audit_log_kern_module(mod->name);
        /* Reserve our place in the list. */
        err = add_unformed_module(mod);
        if (err)
                       mod->name, after_dashes);
        }
  
-       /* Link in to syfs. */
+       /* Link in to sysfs. */
        err = mod_sysfs_setup(mod, info, mod->kp, mod->num_kp);
        if (err < 0)
                goto coming_cleanup;
   sysfs_cleanup:
        mod_sysfs_teardown(mod);
   coming_cleanup:
 +      mod->state = MODULE_STATE_GOING;
        blocking_notifier_call_chain(&module_notify_list,
                                     MODULE_STATE_GOING, mod);
        klp_module_going(mod);
@@@ -4052,10 -4039,6 +4055,10 @@@ int module_kallsyms_on_each_symbol(int 
  }
  #endif /* CONFIG_KALLSYMS */
  
 +/* Maximum number of characters written by module_flags() */
 +#define MODULE_FLAGS_BUF_SIZE (TAINT_FLAGS_COUNT + 4)
 +
 +/* Keep in sync with MODULE_FLAGS_BUF_SIZE !!! */
  static char *module_flags(struct module *mod, char *buf)
  {
        int bx = 0;
@@@ -4100,7 -4083,7 +4103,7 @@@ static void m_stop(struct seq_file *m, 
  static int m_show(struct seq_file *m, void *p)
  {
        struct module *mod = list_entry(p, struct module, list);
 -      char buf[8];
 +      char buf[MODULE_FLAGS_BUF_SIZE];
  
        /* We always ignore unformed modules. */
        if (mod->state == MODULE_STATE_UNFORMED)
@@@ -4271,7 -4254,7 +4274,7 @@@ EXPORT_SYMBOL_GPL(__module_text_address
  void print_modules(void)
  {
        struct module *mod;
 -      char buf[8];
 +      char buf[MODULE_FLAGS_BUF_SIZE];
  
        printk(KERN_DEFAULT "Modules linked in:");
        /* Most callers should already have preempt disabled, but make sure */
diff --combined net/compat.c
index 96c544b05b15e3287cff8905b4b6007af69322af,a96fd2f3507b45bd083614fb4c65ea61b5e7dbe5..d69f539ca0bc5021fd8b20f6ee6297ccd07cad28
  #include <linux/filter.h>
  #include <linux/compat.h>
  #include <linux/security.h>
+ #include <linux/audit.h>
  #include <linux/export.h>
  
  #include <net/scm.h>
  #include <net/sock.h>
  #include <net/ip.h>
  #include <net/ipv6.h>
 -#include <asm/uaccess.h>
 +#include <linux/uaccess.h>
  #include <net/compat.h>
  
  int get_compat_msghdr(struct msghdr *kmsg,
@@@ -781,14 -782,24 +782,24 @@@ COMPAT_SYSCALL_DEFINE5(recvmmsg, int, f
  
  COMPAT_SYSCALL_DEFINE2(socketcall, int, call, u32 __user *, args)
  {
-       int ret;
-       u32 a[6];
+       u32 a[AUDITSC_ARGS];
+       unsigned int len;
        u32 a0, a1;
+       int ret;
  
        if (call < SYS_SOCKET || call > SYS_SENDMMSG)
                return -EINVAL;
-       if (copy_from_user(a, args, nas[call]))
+       len = nas[call];
+       if (len > sizeof(a))
+               return -EINVAL;
+       if (copy_from_user(a, args, len))
                return -EFAULT;
+       ret = audit_socketcall_compat(len / sizeof(a[0]), a);
+       if (ret)
+               return ret;
        a0 = a[0];
        a1 = a[1];