1. 21 11月, 2017 8 次提交
    • J
      apparmor: fix locking when creating a new complain profile. · 5d7c44ef
      John Johansen 提交于
      Break the per cpu buffer atomic section when creating a new null
      complain profile. In learning mode this won't matter and we can
      safely re-aquire the buffer.
      
      This fixes the following lockdep BUG trace
         nov. 14 14:09:09 cyclope audit[7152]: AVC apparmor="ALLOWED" operation="exec" profile="/usr/sbin/sssd" name="/usr/sbin/adcli" pid=7152 comm="sssd_be" requested_mask="x" denied_mask="x" fsuid=0 ouid=0 target="/usr/sbin/sssd//null-/usr/sbin/adcli"
          nov. 14 14:09:09 cyclope kernel: BUG: sleeping function called from invalid context at kernel/locking/mutex.c:747
          nov. 14 14:09:09 cyclope kernel: in_atomic(): 1, irqs_disabled(): 0, pid: 7152, name: sssd_be
          nov. 14 14:09:09 cyclope kernel: 1 lock held by sssd_be/7152:
          nov. 14 14:09:09 cyclope kernel:  #0:  (&sig->cred_guard_mutex){....}, at: [<ffffffff8182d53e>] prepare_bprm_creds+0x4e/0x100
          nov. 14 14:09:09 cyclope kernel: CPU: 3 PID: 7152 Comm: sssd_be Not tainted 4.14.0prahal+intel #150
          nov. 14 14:09:09 cyclope kernel: Hardware name: LENOVO 20CDCTO1WW/20CDCTO1WW, BIOS GQET53WW (1.33 ) 09/15/2017
          nov. 14 14:09:09 cyclope kernel: Call Trace:
          nov. 14 14:09:09 cyclope kernel:  dump_stack+0xb0/0x135
          nov. 14 14:09:09 cyclope kernel:  ? _atomic_dec_and_lock+0x15b/0x15b
          nov. 14 14:09:09 cyclope kernel:  ? lockdep_print_held_locks+0xc4/0x130
          nov. 14 14:09:09 cyclope kernel:  ___might_sleep+0x29c/0x320
          nov. 14 14:09:09 cyclope kernel:  ? rq_clock+0xf0/0xf0
          nov. 14 14:09:09 cyclope kernel:  ? __kernel_text_address+0xd/0x40
          nov. 14 14:09:09 cyclope kernel:  __might_sleep+0x95/0x190
          nov. 14 14:09:09 cyclope kernel:  ? aa_new_null_profile+0x50a/0x960
          nov. 14 14:09:09 cyclope kernel:  __mutex_lock+0x13e/0x1a20
          nov. 14 14:09:09 cyclope kernel:  ? aa_new_null_profile+0x50a/0x960
          nov. 14 14:09:09 cyclope kernel:  ? save_stack+0x43/0xd0
          nov. 14 14:09:09 cyclope kernel:  ? kmem_cache_alloc_trace+0x13f/0x290
          nov. 14 14:09:09 cyclope kernel:  ? mutex_lock_io_nested+0x1880/0x1880
          nov. 14 14:09:09 cyclope kernel:  ? profile_transition+0x932/0x2d40
          nov. 14 14:09:09 cyclope kernel:  ? apparmor_bprm_set_creds+0x1479/0x1f70
          nov. 14 14:09:09 cyclope kernel:  ? security_bprm_set_creds+0x5a/0x80
          nov. 14 14:09:09 cyclope kernel:  ? prepare_binprm+0x366/0x980
          nov. 14 14:09:09 cyclope kernel:  ? do_execveat_common.isra.30+0x12a9/0x2350
          nov. 14 14:09:09 cyclope kernel:  ? SyS_execve+0x2c/0x40
          nov. 14 14:09:09 cyclope kernel:  ? do_syscall_64+0x228/0x650
          nov. 14 14:09:09 cyclope kernel:  ? entry_SYSCALL64_slow_path+0x25/0x25
          nov. 14 14:09:09 cyclope kernel:  ? deactivate_slab.isra.62+0x49d/0x5e0
          nov. 14 14:09:09 cyclope kernel:  ? save_stack_trace+0x16/0x20
          nov. 14 14:09:09 cyclope kernel:  ? init_object+0x88/0x90
          nov. 14 14:09:09 cyclope kernel:  ? ___slab_alloc+0x520/0x590
          nov. 14 14:09:09 cyclope kernel:  ? ___slab_alloc+0x520/0x590
          nov. 14 14:09:09 cyclope kernel:  ? aa_alloc_proxy+0xab/0x200
          nov. 14 14:09:09 cyclope kernel:  ? lock_downgrade+0x7e0/0x7e0
          nov. 14 14:09:09 cyclope kernel:  ? memcg_kmem_get_cache+0x970/0x970
          nov. 14 14:09:09 cyclope kernel:  ? kasan_unpoison_shadow+0x35/0x50
          nov. 14 14:09:09 cyclope kernel:  ? kasan_unpoison_shadow+0x35/0x50
          nov. 14 14:09:09 cyclope kernel:  ? kasan_kmalloc+0xad/0xe0
          nov. 14 14:09:09 cyclope kernel:  ? aa_alloc_proxy+0xab/0x200
          nov. 14 14:09:09 cyclope kernel:  ? kmem_cache_alloc_trace+0x13f/0x290
          nov. 14 14:09:09 cyclope kernel:  ? aa_alloc_proxy+0xab/0x200
          nov. 14 14:09:09 cyclope kernel:  ? aa_alloc_proxy+0xab/0x200
          nov. 14 14:09:09 cyclope kernel:  ? _raw_spin_unlock+0x22/0x30
          nov. 14 14:09:09 cyclope kernel:  ? vec_find+0xa0/0xa0
          nov. 14 14:09:09 cyclope kernel:  ? aa_label_init+0x6f/0x230
          nov. 14 14:09:09 cyclope kernel:  ? __label_insert+0x3e0/0x3e0
          nov. 14 14:09:09 cyclope kernel:  ? kmem_cache_alloc_trace+0x13f/0x290
          nov. 14 14:09:09 cyclope kernel:  ? aa_alloc_profile+0x58/0x200
          nov. 14 14:09:09 cyclope kernel:  mutex_lock_nested+0x16/0x20
          nov. 14 14:09:09 cyclope kernel:  ? mutex_lock_nested+0x16/0x20
          nov. 14 14:09:09 cyclope kernel:  aa_new_null_profile+0x50a/0x960
          nov. 14 14:09:09 cyclope kernel:  ? aa_fqlookupn_profile+0xdc0/0xdc0
          nov. 14 14:09:09 cyclope kernel:  ? aa_compute_fperms+0x4b5/0x640
          nov. 14 14:09:09 cyclope kernel:  ? disconnect.isra.2+0x1b0/0x1b0
          nov. 14 14:09:09 cyclope kernel:  ? aa_str_perms+0x8d/0xe0
          nov. 14 14:09:09 cyclope kernel:  profile_transition+0x932/0x2d40
          nov. 14 14:09:09 cyclope kernel:  ? up_read+0x1a/0x40
          nov. 14 14:09:09 cyclope kernel:  ? ext4_xattr_get+0x15c/0xaf0 [ext4]
          nov. 14 14:09:09 cyclope kernel:  ? x_table_lookup+0x190/0x190
          nov. 14 14:09:09 cyclope kernel:  ? ext4_xattr_ibody_get+0x590/0x590 [ext4]
          nov. 14 14:09:09 cyclope kernel:  ? sched_clock+0x9/0x10
          nov. 14 14:09:09 cyclope kernel:  ? sched_clock+0x9/0x10
          nov. 14 14:09:09 cyclope kernel:  ? ext4_xattr_security_get+0x1a/0x20 [ext4]
          nov. 14 14:09:09 cyclope kernel:  ? __vfs_getxattr+0x6d/0xa0
          nov. 14 14:09:09 cyclope kernel:  ? get_vfs_caps_from_disk+0x114/0x720
          nov. 14 14:09:09 cyclope kernel:  ? sched_clock+0x9/0x10
          nov. 14 14:09:09 cyclope kernel:  ? sched_clock+0x9/0x10
          nov. 14 14:09:09 cyclope kernel:  ? tsc_resume+0x10/0x10
          nov. 14 14:09:09 cyclope kernel:  ? get_vfs_caps_from_disk+0x720/0x720
          nov. 14 14:09:09 cyclope kernel:  ? native_sched_clock_from_tsc+0x201/0x2b0
          nov. 14 14:09:09 cyclope kernel:  ? sched_clock+0x9/0x10
          nov. 14 14:09:09 cyclope kernel:  ? sched_clock_cpu+0x1b/0x170
          nov. 14 14:09:09 cyclope kernel:  ? find_held_lock+0x3c/0x1e0
          nov. 14 14:09:09 cyclope kernel:  ? rb_insert_color_cached+0x1660/0x1660
          nov. 14 14:09:09 cyclope kernel:  apparmor_bprm_set_creds+0x1479/0x1f70
          nov. 14 14:09:09 cyclope kernel:  ? sched_clock+0x9/0x10
          nov. 14 14:09:09 cyclope kernel:  ? handle_onexec+0x31d0/0x31d0
          nov. 14 14:09:09 cyclope kernel:  ? tsc_resume+0x10/0x10
          nov. 14 14:09:09 cyclope kernel:  ? graph_lock+0xd0/0xd0
          nov. 14 14:09:09 cyclope kernel:  ? tsc_resume+0x10/0x10
          nov. 14 14:09:09 cyclope kernel:  ? sched_clock_cpu+0x1b/0x170
          nov. 14 14:09:09 cyclope kernel:  ? sched_clock+0x9/0x10
          nov. 14 14:09:09 cyclope kernel:  ? sched_clock+0x9/0x10
          nov. 14 14:09:09 cyclope kernel:  ? sched_clock_cpu+0x1b/0x170
          nov. 14 14:09:09 cyclope kernel:  ? find_held_lock+0x3c/0x1e0
          nov. 14 14:09:09 cyclope kernel:  security_bprm_set_creds+0x5a/0x80
          nov. 14 14:09:09 cyclope kernel:  prepare_binprm+0x366/0x980
          nov. 14 14:09:09 cyclope kernel:  ? install_exec_creds+0x150/0x150
          nov. 14 14:09:09 cyclope kernel:  ? __might_fault+0x89/0xb0
          nov. 14 14:09:09 cyclope kernel:  ? up_read+0x40/0x40
          nov. 14 14:09:09 cyclope kernel:  ? get_user_arg_ptr.isra.18+0x2c/0x70
          nov. 14 14:09:09 cyclope kernel:  ? count.isra.20.constprop.32+0x7c/0xf0
          nov. 14 14:09:09 cyclope kernel:  do_execveat_common.isra.30+0x12a9/0x2350
          nov. 14 14:09:09 cyclope kernel:  ? prepare_bprm_creds+0x100/0x100
          nov. 14 14:09:09 cyclope kernel:  ? _raw_spin_unlock+0x22/0x30
          nov. 14 14:09:09 cyclope kernel:  ? deactivate_slab.isra.62+0x49d/0x5e0
          nov. 14 14:09:09 cyclope kernel:  ? save_stack_trace+0x16/0x20
          nov. 14 14:09:09 cyclope kernel:  ? init_object+0x88/0x90
          nov. 14 14:09:09 cyclope kernel:  ? ___slab_alloc+0x520/0x590
          nov. 14 14:09:09 cyclope kernel:  ? ___slab_alloc+0x520/0x590
          nov. 14 14:09:09 cyclope kernel:  ? kasan_check_write+0x14/0x20
          nov. 14 14:09:09 cyclope kernel:  ? memcg_kmem_get_cache+0x970/0x970
          nov. 14 14:09:09 cyclope kernel:  ? kasan_unpoison_shadow+0x35/0x50
          nov. 14 14:09:09 cyclope kernel:  ? glob_match+0x730/0x730
          nov. 14 14:09:09 cyclope kernel:  ? kmem_cache_alloc+0x225/0x280
          nov. 14 14:09:09 cyclope kernel:  ? getname_flags+0xb8/0x510
          nov. 14 14:09:09 cyclope kernel:  ? mm_fault_error+0x2e0/0x2e0
          nov. 14 14:09:09 cyclope kernel:  ? getname_flags+0xf6/0x510
          nov. 14 14:09:09 cyclope kernel:  ? ptregs_sys_vfork+0x10/0x10
          nov. 14 14:09:09 cyclope kernel:  SyS_execve+0x2c/0x40
          nov. 14 14:09:09 cyclope kernel:  do_syscall_64+0x228/0x650
          nov. 14 14:09:09 cyclope kernel:  ? syscall_return_slowpath+0x2f0/0x2f0
          nov. 14 14:09:09 cyclope kernel:  ? syscall_return_slowpath+0x167/0x2f0
          nov. 14 14:09:09 cyclope kernel:  ? prepare_exit_to_usermode+0x220/0x220
          nov. 14 14:09:09 cyclope kernel:  ? prepare_exit_to_usermode+0xda/0x220
          nov. 14 14:09:09 cyclope kernel:  ? perf_trace_sys_enter+0x1060/0x1060
          nov. 14 14:09:09 cyclope kernel:  ? __put_user_4+0x1c/0x30
          nov. 14 14:09:09 cyclope kernel:  entry_SYSCALL64_slow_path+0x25/0x25
          nov. 14 14:09:09 cyclope kernel: RIP: 0033:0x7f9320f23637
          nov. 14 14:09:09 cyclope kernel: RSP: 002b:00007fff783be338 EFLAGS: 00000202 ORIG_RAX: 000000000000003b
          nov. 14 14:09:09 cyclope kernel: RAX: ffffffffffffffda RBX: 0000000000000000 RCX: 00007f9320f23637
          nov. 14 14:09:09 cyclope kernel: RDX: 0000558c35002a70 RSI: 0000558c3505bd10 RDI: 0000558c35018b90
          nov. 14 14:09:09 cyclope kernel: RBP: 0000558c34b63ae8 R08: 0000558c3505bd10 R09: 0000000000000080
          nov. 14 14:09:09 cyclope kernel: R10: 0000000000000095 R11: 0000000000000202 R12: 0000000000000001
          nov. 14 14:09:09 cyclope kernel: R13: 0000558c35018b90 R14: 0000558c3505bd18 R15: 0000558c3505bd10
      
      Fixes: 4227c333 ("apparmor: Move path lookup to using preallocated buffers")
      BugLink: http://bugs.launchpad.net/bugs/173228Reported-by: NAlban Browaeys <prahal@yahoo.com>
      Signed-off-by: NJohn Johansen <john.johansen@canonical.com>
      5d7c44ef
    • J
      apparmor: fix profile attachment for special unconfined profiles · 06d426d1
      John Johansen 提交于
      It used to be that unconfined would never attach. However that is not
      the case anymore as some special profiles can be marked as unconfined,
      that are not the namespaces unconfined profile, and may have an
      attachment.
      
      Fixes: f1bd9041 ("apparmor: add the base fns() for domain labels")
      Signed-off-by: NJohn Johansen <john.johansen@canonical.com>
      06d426d1
    • J
      apparmor: ensure that undecidable profile attachments fail · 844b8292
      John Johansen 提交于
      Profiles that have an undecidable overlap in their attachments are
      being incorrectly handled. Instead of failing to attach the first one
      encountered is being used.
      
      eg.
        profile A /** { .. }
        profile B /*foo { .. }
      
      have an unresolvable longest left attachment, they both have an exact
      match on / and then have an overlapping expression that has no clear
      winner.
      
      Currently the winner will be the profile that is loaded first which
      can result in non-deterministic behavior. Instead in this situation
      the exec should fail.
      
      Fixes: 898127c3 ("AppArmor: functions for domain transitions")
      Signed-off-by: NJohn Johansen <john.johansen@canonical.com>
      844b8292
    • J
      apparmor: fix leak of null profile name if profile allocation fails · 4633307e
      John Johansen 提交于
      Fixes: d07881d2 ("apparmor: move new_null_profile to after profile lookup fns()")
      Reported-by: NSeth Arnold <seth.arnold@canonical.com>
      Signed-off-by: NJohn Johansen <john.johansen@canonical.com>
      4633307e
    • C
      apparmor: remove unused redundant variable stop · e3bcfc14
      Colin Ian King 提交于
      The boolean variable 'stop' is being set but never read. This
      is a redundant variable and can be removed.
      
      Cleans up clang warning: Value stored to 'stop' is never read
      Signed-off-by: NColin Ian King <colin.king@canonical.com>
      Signed-off-by: NJohn Johansen <john.johansen@canonical.com>
      e3bcfc14
    • T
      apparmor: Fix bool initialization/comparison · 954317fe
      Thomas Meyer 提交于
      Bool initializations should use true and false. Bool tests don't need
      comparisons.
      Signed-off-by: NThomas Meyer <thomas@m3y3r.de>
      Signed-off-by: NJohn Johansen <john.johansen@canonical.com>
      954317fe
    • A
      apparmor: initialized returned struct aa_perms · 7bba39ae
      Arnd Bergmann 提交于
      gcc-4.4 points out suspicious code in compute_mnt_perms, where
      the aa_perms structure is only partially initialized before getting
      returned:
      
      security/apparmor/mount.c: In function 'compute_mnt_perms':
      security/apparmor/mount.c:227: error: 'perms.prompt' is used uninitialized in this function
      security/apparmor/mount.c:227: error: 'perms.hide' is used uninitialized in this function
      security/apparmor/mount.c:227: error: 'perms.cond' is used uninitialized in this function
      security/apparmor/mount.c:227: error: 'perms.complain' is used uninitialized in this function
      security/apparmor/mount.c:227: error: 'perms.stop' is used uninitialized in this function
      security/apparmor/mount.c:227: error: 'perms.deny' is used uninitialized in this function
      
      Returning or assigning partially initialized structures is a bit tricky,
      in particular it is explicitly allowed in c99 to assign a partially
      initialized structure to another, as long as only members are read that
      have been initialized earlier. Looking at what various compilers do here,
      the version that produced the warning copied uninitialized stack data,
      while newer versions (and also clang) either set the other members to
      zero or don't update the parts of the return buffer that are not modified
      in the temporary structure, but they never warn about this.
      
      In case of apparmor, it seems better to be a little safer and always
      initialize the aa_perms structure. Most users already do that, this
      changes the remaining ones, including the one instance that I got the
      warning for.
      
      Fixes: fa488437d0f9 ("apparmor: add mount mediation")
      Signed-off-by: NArnd Bergmann <arnd@arndb.de>
      Reviewed-by: NSeth Arnold <seth.arnold@canonical.com>
      Acked-by: NGeert Uytterhoeven <geert@linux-m68k.org>
      Signed-off-by: NJohn Johansen <john.johansen@canonical.com>
      7bba39ae
    • C
      apparmor: fix spelling mistake: "resoure" -> "resource" · 5933a627
      Colin Ian King 提交于
      Trivial fix to spelling mistake in comment and also with text in
      audit_resource call.
      Signed-off-by: NColin Ian King <colin.king@canonical.com>
      Signed-off-by: NJohn Johansen <john.johansen@canonical.com>
      5933a627
  2. 27 10月, 2017 1 次提交
  3. 19 10月, 2017 1 次提交
  4. 18 10月, 2017 6 次提交
    • E
      KEYS: load key flags and expiry time atomically in proc_keys_show() · ab5c69f0
      Eric Biggers 提交于
      In proc_keys_show(), the key semaphore is not held, so the key ->flags
      and ->expiry can be changed concurrently.  We therefore should read them
      atomically just once.
      Signed-off-by: NEric Biggers <ebiggers@google.com>
      Signed-off-by: NDavid Howells <dhowells@redhat.com>
      ab5c69f0
    • E
      KEYS: Load key expiry time atomically in keyring_search_iterator() · 9d6c8711
      Eric Biggers 提交于
      Similar to the case for key_validate(), we should load the key ->expiry
      once atomically in keyring_search_iterator(), since it can be changed
      concurrently with the flags whenever the key semaphore isn't held.
      Signed-off-by: NEric Biggers <ebiggers@google.com>
      Signed-off-by: NDavid Howells <dhowells@redhat.com>
      9d6c8711
    • E
      KEYS: load key flags and expiry time atomically in key_validate() · 1823d475
      Eric Biggers 提交于
      In key_validate(), load the flags and expiry time once atomically, since
      these can change concurrently if key_validate() is called without the
      key semaphore held.  And we don't want to get inconsistent results if a
      variable is referenced multiple times.  For example, key->expiry was
      referenced in both 'if (key->expiry)' and in 'if (now.tv_sec >=
      key->expiry)', making it theoretically possible to see a spurious
      EKEYEXPIRED while the expiration time was being removed, i.e. set to 0.
      Signed-off-by: NEric Biggers <ebiggers@google.com>
      Signed-off-by: NDavid Howells <dhowells@redhat.com>
      1823d475
    • D
      KEYS: don't let add_key() update an uninstantiated key · 60ff5b2f
      David Howells 提交于
      Currently, when passed a key that already exists, add_key() will call the
      key's ->update() method if such exists.  But this is heavily broken in the
      case where the key is uninstantiated because it doesn't call
      __key_instantiate_and_link().  Consequently, it doesn't do most of the
      things that are supposed to happen when the key is instantiated, such as
      setting the instantiation state, clearing KEY_FLAG_USER_CONSTRUCT and
      awakening tasks waiting on it, and incrementing key->user->nikeys.
      
      It also never takes key_construction_mutex, which means that
      ->instantiate() can run concurrently with ->update() on the same key.  In
      the case of the "user" and "logon" key types this causes a memory leak, at
      best.  Maybe even worse, the ->update() methods of the "encrypted" and
      "trusted" key types actually just dereference a NULL pointer when passed an
      uninstantiated key.
      
      Change key_create_or_update() to wait interruptibly for the key to finish
      construction before continuing.
      
      This patch only affects *uninstantiated* keys.  For now we still allow a
      negatively instantiated key to be updated (thereby positively
      instantiating it), although that's broken too (the next patch fixes it)
      and I'm not sure that anyone actually uses that functionality either.
      
      Here is a simple reproducer for the bug using the "encrypted" key type
      (requires CONFIG_ENCRYPTED_KEYS=y), though as noted above the bug
      pertained to more than just the "encrypted" key type:
      
          #include <stdlib.h>
          #include <unistd.h>
          #include <keyutils.h>
      
          int main(void)
          {
              int ringid = keyctl_join_session_keyring(NULL);
      
              if (fork()) {
                  for (;;) {
                      const char payload[] = "update user:foo 32";
      
                      usleep(rand() % 10000);
                      add_key("encrypted", "desc", payload, sizeof(payload), ringid);
                      keyctl_clear(ringid);
                  }
              } else {
                  for (;;)
                      request_key("encrypted", "desc", "callout_info", ringid);
              }
          }
      
      It causes:
      
          BUG: unable to handle kernel NULL pointer dereference at 0000000000000018
          IP: encrypted_update+0xb0/0x170
          PGD 7a178067 P4D 7a178067 PUD 77269067 PMD 0
          PREEMPT SMP
          CPU: 0 PID: 340 Comm: reproduce Tainted: G      D         4.14.0-rc1-00025-g428490e3 #796
          Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Bochs 01/01/2011
          task: ffff8a467a39a340 task.stack: ffffb15c40770000
          RIP: 0010:encrypted_update+0xb0/0x170
          RSP: 0018:ffffb15c40773de8 EFLAGS: 00010246
          RAX: 0000000000000000 RBX: ffff8a467a275b00 RCX: 0000000000000000
          RDX: 0000000000000005 RSI: ffff8a467a275b14 RDI: ffffffffb742f303
          RBP: ffffb15c40773e20 R08: 0000000000000000 R09: ffff8a467a275b17
          R10: 0000000000000020 R11: 0000000000000000 R12: 0000000000000000
          R13: 0000000000000000 R14: ffff8a4677057180 R15: ffff8a467a275b0f
          FS:  00007f5d7fb08700(0000) GS:ffff8a467f200000(0000) knlGS:0000000000000000
          CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
          CR2: 0000000000000018 CR3: 0000000077262005 CR4: 00000000001606f0
          Call Trace:
           key_create_or_update+0x2bc/0x460
           SyS_add_key+0x10c/0x1d0
           entry_SYSCALL_64_fastpath+0x1f/0xbe
          RIP: 0033:0x7f5d7f211259
          RSP: 002b:00007ffed03904c8 EFLAGS: 00000246 ORIG_RAX: 00000000000000f8
          RAX: ffffffffffffffda RBX: 000000003b2a7955 RCX: 00007f5d7f211259
          RDX: 00000000004009e4 RSI: 00000000004009ff RDI: 0000000000400a04
          RBP: 0000000068db8bad R08: 000000003b2a7955 R09: 0000000000000004
          R10: 000000000000001a R11: 0000000000000246 R12: 0000000000400868
          R13: 00007ffed03905d0 R14: 0000000000000000 R15: 0000000000000000
          Code: 77 28 e8 64 34 1f 00 45 31 c0 31 c9 48 8d 55 c8 48 89 df 48 8d 75 d0 e8 ff f9 ff ff 85 c0 41 89 c4 0f 88 84 00 00 00 4c 8b 7d c8 <49> 8b 75 18 4c 89 ff e8 24 f8 ff ff 85 c0 41 89 c4 78 6d 49 8b
          RIP: encrypted_update+0xb0/0x170 RSP: ffffb15c40773de8
          CR2: 0000000000000018
      
      Cc: <stable@vger.kernel.org> # v2.6.12+
      Reported-by: NEric Biggers <ebiggers@google.com>
      Signed-off-by: NDavid Howells <dhowells@redhat.com>
      cc: Eric Biggers <ebiggers@google.com>
      60ff5b2f
    • D
      KEYS: Fix race between updating and finding a negative key · 363b02da
      David Howells 提交于
      Consolidate KEY_FLAG_INSTANTIATED, KEY_FLAG_NEGATIVE and the rejection
      error into one field such that:
      
       (1) The instantiation state can be modified/read atomically.
      
       (2) The error can be accessed atomically with the state.
      
       (3) The error isn't stored unioned with the payload pointers.
      
      This deals with the problem that the state is spread over three different
      objects (two bits and a separate variable) and reading or updating them
      atomically isn't practical, given that not only can uninstantiated keys
      change into instantiated or rejected keys, but rejected keys can also turn
      into instantiated keys - and someone accessing the key might not be using
      any locking.
      
      The main side effect of this problem is that what was held in the payload
      may change, depending on the state.  For instance, you might observe the
      key to be in the rejected state.  You then read the cached error, but if
      the key semaphore wasn't locked, the key might've become instantiated
      between the two reads - and you might now have something in hand that isn't
      actually an error code.
      
      The state is now KEY_IS_UNINSTANTIATED, KEY_IS_POSITIVE or a negative error
      code if the key is negatively instantiated.  The key_is_instantiated()
      function is replaced with key_is_positive() to avoid confusion as negative
      keys are also 'instantiated'.
      
      Additionally, barriering is included:
      
       (1) Order payload-set before state-set during instantiation.
      
       (2) Order state-read before payload-read when using the key.
      
      Further separate barriering is necessary if RCU is being used to access the
      payload content after reading the payload pointers.
      
      Fixes: 146aa8b1 ("KEYS: Merge the type-specific data with the payload data")
      Cc: stable@vger.kernel.org # v4.4+
      Reported-by: NEric Biggers <ebiggers@google.com>
      Signed-off-by: NDavid Howells <dhowells@redhat.com>
      Reviewed-by: NEric Biggers <ebiggers@google.com>
      363b02da
    • A
      security/keys: BIG_KEY requires CONFIG_CRYPTO · 3cd18d19
      Arnd Bergmann 提交于
      The recent rework introduced a possible randconfig build failure
      when CONFIG_CRYPTO configured to only allow modules:
      
      security/keys/big_key.o: In function `big_key_crypt':
      big_key.c:(.text+0x29f): undefined reference to `crypto_aead_setkey'
      security/keys/big_key.o: In function `big_key_init':
      big_key.c:(.init.text+0x1a): undefined reference to `crypto_alloc_aead'
      big_key.c:(.init.text+0x45): undefined reference to `crypto_aead_setauthsize'
      big_key.c:(.init.text+0x77): undefined reference to `crypto_destroy_tfm'
      crypto/gcm.o: In function `gcm_hash_crypt_remain_continue':
      gcm.c:(.text+0x167): undefined reference to `crypto_ahash_finup'
      crypto/gcm.o: In function `crypto_gcm_exit_tfm':
      gcm.c:(.text+0x847): undefined reference to `crypto_destroy_tfm'
      
      When we 'select CRYPTO' like the other users, we always get a
      configuration that builds.
      
      Fixes: 428490e3 ("security/keys: rewrite all of big_key crypto")
      Signed-off-by: NArnd Bergmann <arnd@arndb.de>
      Signed-off-by: NDavid Howells <dhowells@redhat.com>
      3cd18d19
  5. 12 10月, 2017 1 次提交
    • E
      KEYS: encrypted: fix dereference of NULL user_key_payload · 13923d08
      Eric Biggers 提交于
      A key of type "encrypted" references a "master key" which is used to
      encrypt and decrypt the encrypted key's payload.  However, when we
      accessed the master key's payload, we failed to handle the case where
      the master key has been revoked, which sets the payload pointer to NULL.
      Note that request_key() *does* skip revoked keys, but there is still a
      window where the key can be revoked before we acquire its semaphore.
      
      Fix it by checking for a NULL payload, treating it like a key which was
      already revoked at the time it was requested.
      
      This was an issue for master keys of type "user" only.  Master keys can
      also be of type "trusted", but those cannot be revoked.
      
      Fixes: 7e70cb49 ("keys: add new key-type encrypted")
      Reviewed-by: NJames Morris <james.l.morris@oracle.com>
      Cc: <stable@vger.kernel.org>    [v2.6.38+]
      Cc: Mimi Zohar <zohar@linux.vnet.ibm.com>
      Cc: David Safford <safford@us.ibm.com>
      Signed-off-by: NEric Biggers <ebiggers@google.com>
      Signed-off-by: NDavid Howells <dhowells@redhat.com>
      13923d08
  6. 04 10月, 2017 1 次提交
    • C
      lsm: fix smack_inode_removexattr and xattr_getsecurity memleak · 57e7ba04
      Casey Schaufler 提交于
      security_inode_getsecurity() provides the text string value
      of a security attribute. It does not provide a "secctx".
      The code in xattr_getsecurity() that calls security_inode_getsecurity()
      and then calls security_release_secctx() happened to work because
      SElinux and Smack treat the attribute and the secctx the same way.
      It fails for cap_inode_getsecurity(), because that module has no
      secctx that ever needs releasing. It turns out that Smack is the
      one that's doing things wrong by not allocating memory when instructed
      to do so by the "alloc" parameter.
      
      The fix is simple enough. Change the security_release_secctx() to
      kfree() because it isn't a secctx being returned by
      security_inode_getsecurity(). Change Smack to allocate the string when
      told to do so.
      
      Note: this also fixes memory leaks for LSMs which implement
      inode_getsecurity but not release_secctx, such as capabilities.
      Signed-off-by: NCasey Schaufler <casey@schaufler-ca.com>
      Reported-by: NKonstantin Khlebnikov <khlebnikov@yandex-team.ru>
      Cc: stable@vger.kernel.org
      Signed-off-by: NJames Morris <james.l.morris@oracle.com>
      57e7ba04
  7. 26 9月, 2017 2 次提交
    • J
      security/keys: rewrite all of big_key crypto · 428490e3
      Jason A. Donenfeld 提交于
      This started out as just replacing the use of crypto/rng with
      get_random_bytes_wait, so that we wouldn't use bad randomness at boot
      time. But, upon looking further, it appears that there were even deeper
      underlying cryptographic problems, and that this seems to have been
      committed with very little crypto review. So, I rewrote the whole thing,
      trying to keep to the conventions introduced by the previous author, to
      fix these cryptographic flaws.
      
      It makes no sense to seed crypto/rng at boot time and then keep
      using it like this, when in fact there's already get_random_bytes_wait,
      which can ensure there's enough entropy and be a much more standard way
      of generating keys. Since this sensitive material is being stored
      untrusted, using ECB and no authentication is simply not okay at all. I
      find it surprising and a bit horrifying that this code even made it past
      basic crypto review, which perhaps points to some larger issues. This
      patch moves from using AES-ECB to using AES-GCM. Since keys are uniquely
      generated each time, we can set the nonce to zero. There was also a race
      condition in which the same key would be reused at the same time in
      different threads. A mutex fixes this issue now.
      
      So, to summarize, this commit fixes the following vulnerabilities:
      
        * Low entropy key generation, allowing an attacker to potentially
          guess or predict keys.
        * Unauthenticated encryption, allowing an attacker to modify the
          cipher text in particular ways in order to manipulate the plaintext,
          which is is even more frightening considering the next point.
        * Use of ECB mode, allowing an attacker to trivially swap blocks or
          compare identical plaintext blocks.
        * Key re-use.
        * Faulty memory zeroing.
      Signed-off-by: NJason A. Donenfeld <Jason@zx2c4.com>
      Reviewed-by: NEric Biggers <ebiggers3@gmail.com>
      Signed-off-by: NDavid Howells <dhowells@redhat.com>
      Cc: Herbert Xu <herbert@gondor.apana.org.au>
      Cc: Kirill Marinushkin <k.marinushkin@gmail.com>
      Cc: security@kernel.org
      Cc: stable@vger.kernel.org
      428490e3
    • J
      security/keys: properly zero out sensitive key material in big_key · 91080180
      Jason A. Donenfeld 提交于
      Error paths forgot to zero out sensitive material, so this patch changes
      some kfrees into a kzfrees.
      Signed-off-by: NJason A. Donenfeld <Jason@zx2c4.com>
      Signed-off-by: NDavid Howells <dhowells@redhat.com>
      Reviewed-by: NEric Biggers <ebiggers3@gmail.com>
      Cc: Herbert Xu <herbert@gondor.apana.org.au>
      Cc: Kirill Marinushkin <k.marinushkin@gmail.com>
      Cc: security@kernel.org
      Cc: stable@vger.kernel.org
      91080180
  8. 25 9月, 2017 10 次提交
    • E
      KEYS: use kmemdup() in request_key_auth_new() · e007ce9c
      Eric Biggers 提交于
      kmemdup() is preferred to kmalloc() followed by memcpy().
      Signed-off-by: NEric Biggers <ebiggers@google.com>
      Signed-off-by: NDavid Howells <dhowells@redhat.com>
      e007ce9c
    • E
      KEYS: restrict /proc/keys by credentials at open time · 4aa68e07
      Eric Biggers 提交于
      When checking for permission to view keys whilst reading from
      /proc/keys, we should use the credentials with which the /proc/keys file
      was opened.  This is because, in a classic type of exploit, it can be
      possible to bypass checks for the *current* credentials by passing the
      file descriptor to a suid program.
      
      Following commit 34dbbcdb ("Make file credentials available to the
      seqfile interfaces") we can finally fix it.  So let's do it.
      Signed-off-by: NEric Biggers <ebiggers@google.com>
      Signed-off-by: NDavid Howells <dhowells@redhat.com>
      4aa68e07
    • E
      KEYS: reset parent each time before searching key_user_tree · 8f674565
      Eric Biggers 提交于
      In key_user_lookup(), if there is no key_user for the given uid, we drop
      key_user_lock, allocate a new key_user, and search the tree again.  But
      we failed to set 'parent' to NULL at the beginning of the second search.
      If the tree were to be empty for the second search, the insertion would
      be done with an invalid 'parent', scribbling over freed memory.
      
      Fortunately this can't actually happen currently because the tree always
      contains at least the root_key_user.  But it still should be fixed to
      make the code more robust.
      Signed-off-by: NEric Biggers <ebiggers@google.com>
      Signed-off-by: NDavid Howells <dhowells@redhat.com>
      8f674565
    • E
      KEYS: prevent KEYCTL_READ on negative key · 37863c43
      Eric Biggers 提交于
      Because keyctl_read_key() looks up the key with no permissions
      requested, it may find a negatively instantiated key.  If the key is
      also possessed, we went ahead and called ->read() on the key.  But the
      key payload will actually contain the ->reject_error rather than the
      normal payload.  Thus, the kernel oopses trying to read the
      user_key_payload from memory address (int)-ENOKEY = 0x00000000ffffff82.
      
      Fortunately the payload data is stored inline, so it shouldn't be
      possible to abuse this as an arbitrary memory read primitive...
      
      Reproducer:
          keyctl new_session
          keyctl request2 user desc '' @s
          keyctl read $(keyctl show | awk '/user: desc/ {print $1}')
      
      It causes a crash like the following:
           BUG: unable to handle kernel paging request at 00000000ffffff92
           IP: user_read+0x33/0xa0
           PGD 36a54067 P4D 36a54067 PUD 0
           Oops: 0000 [#1] SMP
           CPU: 0 PID: 211 Comm: keyctl Not tainted 4.14.0-rc1 #337
           Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.10.2-20170228_101828-anatol 04/01/2014
           task: ffff90aa3b74c3c0 task.stack: ffff9878c0478000
           RIP: 0010:user_read+0x33/0xa0
           RSP: 0018:ffff9878c047bee8 EFLAGS: 00010246
           RAX: 0000000000000001 RBX: ffff90aa3d7da340 RCX: 0000000000000017
           RDX: 0000000000000000 RSI: 00000000ffffff82 RDI: ffff90aa3d7da340
           RBP: ffff9878c047bf00 R08: 00000024f95da94f R09: 0000000000000000
           R10: 0000000000000001 R11: 0000000000000000 R12: 0000000000000000
           R13: 0000000000000000 R14: 0000000000000000 R15: 0000000000000000
           FS:  00007f58ece69740(0000) GS:ffff90aa3e200000(0000) knlGS:0000000000000000
           CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
           CR2: 00000000ffffff92 CR3: 0000000036adc001 CR4: 00000000003606f0
           Call Trace:
            keyctl_read_key+0xac/0xe0
            SyS_keyctl+0x99/0x120
            entry_SYSCALL_64_fastpath+0x1f/0xbe
           RIP: 0033:0x7f58ec787bb9
           RSP: 002b:00007ffc8d401678 EFLAGS: 00000206 ORIG_RAX: 00000000000000fa
           RAX: ffffffffffffffda RBX: 00007ffc8d402800 RCX: 00007f58ec787bb9
           RDX: 0000000000000000 RSI: 00000000174a63ac RDI: 000000000000000b
           RBP: 0000000000000004 R08: 00007ffc8d402809 R09: 0000000000000020
           R10: 0000000000000000 R11: 0000000000000206 R12: 00007ffc8d402800
           R13: 00007ffc8d4016e0 R14: 0000000000000000 R15: 0000000000000000
           Code: e5 41 55 49 89 f5 41 54 49 89 d4 53 48 89 fb e8 a4 b4 ad ff 85 c0 74 09 80 3d b9 4c 96 00 00 74 43 48 8b b3 20 01 00 00 4d 85 ed <0f> b7 5e 10 74 29 4d 85 e4 74 24 4c 39 e3 4c 89 e2 4c 89 ef 48
           RIP: user_read+0x33/0xa0 RSP: ffff9878c047bee8
           CR2: 00000000ffffff92
      
      Fixes: 61ea0c0b ("KEYS: Skip key state checks when checking for possession")
      Cc: <stable@vger.kernel.org>	[v3.13+]
      Signed-off-by: NEric Biggers <ebiggers@google.com>
      Signed-off-by: NDavid Howells <dhowells@redhat.com>
      37863c43
    • E
      KEYS: prevent creating a different user's keyrings · 237bbd29
      Eric Biggers 提交于
      It was possible for an unprivileged user to create the user and user
      session keyrings for another user.  For example:
      
          sudo -u '#3000' sh -c 'keyctl add keyring _uid.4000 "" @u
                                 keyctl add keyring _uid_ses.4000 "" @u
                                 sleep 15' &
          sleep 1
          sudo -u '#4000' keyctl describe @u
          sudo -u '#4000' keyctl describe @us
      
      This is problematic because these "fake" keyrings won't have the right
      permissions.  In particular, the user who created them first will own
      them and will have full access to them via the possessor permissions,
      which can be used to compromise the security of a user's keys:
      
          -4: alswrv-----v------------  3000     0 keyring: _uid.4000
          -5: alswrv-----v------------  3000     0 keyring: _uid_ses.4000
      
      Fix it by marking user and user session keyrings with a flag
      KEY_FLAG_UID_KEYRING.  Then, when searching for a user or user session
      keyring by name, skip all keyrings that don't have the flag set.
      
      Fixes: 69664cf1 ("keys: don't generate user and user session keyrings unless they're accessed")
      Cc: <stable@vger.kernel.org>	[v2.6.26+]
      Signed-off-by: NEric Biggers <ebiggers@google.com>
      Signed-off-by: NDavid Howells <dhowells@redhat.com>
      237bbd29
    • E
      KEYS: fix writing past end of user-supplied buffer in keyring_read() · e645016a
      Eric Biggers 提交于
      Userspace can call keyctl_read() on a keyring to get the list of IDs of
      keys in the keyring.  But if the user-supplied buffer is too small, the
      kernel would write the full list anyway --- which will corrupt whatever
      userspace memory happened to be past the end of the buffer.  Fix it by
      only filling the space that is available.
      
      Fixes: b2a4df20 ("KEYS: Expand the capacity of a keyring")
      Cc: <stable@vger.kernel.org>	[v3.13+]
      Signed-off-by: NEric Biggers <ebiggers@google.com>
      Signed-off-by: NDavid Howells <dhowells@redhat.com>
      e645016a
    • E
      KEYS: fix key refcount leak in keyctl_read_key() · 7fc0786d
      Eric Biggers 提交于
      In keyctl_read_key(), if key_permission() were to return an error code
      other than EACCES, we would leak a the reference to the key.  This can't
      actually happen currently because key_permission() can only return an
      error code other than EACCES if security_key_permission() does, only
      SELinux and Smack implement that hook, and neither can return an error
      code other than EACCES.  But it should still be fixed, as it is a bug
      waiting to happen.
      
      Fixes: 29db9190 ("[PATCH] Keys: Add LSM hooks for key management [try #3]")
      Signed-off-by: NEric Biggers <ebiggers@google.com>
      Signed-off-by: NDavid Howells <dhowells@redhat.com>
      7fc0786d
    • E
      KEYS: fix key refcount leak in keyctl_assume_authority() · 884bee02
      Eric Biggers 提交于
      In keyctl_assume_authority(), if keyctl_change_reqkey_auth() were to
      fail, we would leak the reference to the 'authkey'.  Currently this can
      only happen if prepare_creds() fails to allocate memory.  But it still
      should be fixed, as it is a more severe bug waiting to happen.
      
      This patch also moves the read of 'authkey->serial' to before the
      reference to the authkey is dropped.  Doing the read after dropping the
      reference is very fragile because it assumes we still hold another
      reference to the key.  (Which we do, in current->cred->request_key_auth,
      but there's no reason not to write it in the "obviously correct" way.)
      
      Fixes: d84f4f99 ("CRED: Inaugurate COW credentials")
      Signed-off-by: NEric Biggers <ebiggers@google.com>
      Signed-off-by: NDavid Howells <dhowells@redhat.com>
      884bee02
    • E
      KEYS: don't revoke uninstantiated key in request_key_auth_new() · f7b48cf0
      Eric Biggers 提交于
      If key_instantiate_and_link() were to fail (which fortunately isn't
      possible currently), the call to key_revoke(authkey) would crash with a
      NULL pointer dereference in request_key_auth_revoke() because the key
      has not yet been instantiated.
      
      Fix this by removing the call to key_revoke().  key_put() is sufficient,
      as it's not possible for an uninstantiated authkey to have been used for
      anything yet.
      
      Fixes: b5f545c8 ("[PATCH] keys: Permit running process to instantiate keys")
      Signed-off-by: NEric Biggers <ebiggers@google.com>
      Signed-off-by: NDavid Howells <dhowells@redhat.com>
      f7b48cf0
    • E
      KEYS: fix cred refcount leak in request_key_auth_new() · 44d81433
      Eric Biggers 提交于
      In request_key_auth_new(), if key_alloc() or key_instantiate_and_link()
      were to fail, we would leak a reference to the 'struct cred'.  Currently
      this can only happen if key_alloc() fails to allocate memory.  But it
      still should be fixed, as it is a more severe bug waiting to happen.
      
      Fix it by cleaning things up to use a helper function which frees a
      'struct request_key_auth' correctly.
      
      Fixes: d84f4f99 ("CRED: Inaugurate COW credentials")
      Signed-off-by: NEric Biggers <ebiggers@google.com>
      Signed-off-by: NDavid Howells <dhowells@redhat.com>
      44d81433
  9. 24 9月, 2017 1 次提交
  10. 23 9月, 2017 9 次提交