1. 15 Feb, 2019 1 commit
    • David Howells's avatar
      keys: Fix dependency loop between construction record and auth key · 822ad64d
      David Howells authored
      In the request_key() upcall mechanism there's a dependency loop by which if
      a key type driver overrides the ->request_key hook and the userspace side
      manages to lose the authorisation key, the auth key and the internal
      construction record (struct key_construction) can keep each other pinned.
      
      Fix this by the following changes:
      
       (1) Killing off the construction record and using the auth key instead.
      
       (2) Including the operation name in the auth key payload and making the
           payload available outside of security/keys/.
      
       (3) The ->request_key hook is given the authkey instead of the cons
           record and operation name.
      
      Changes (2) and (3) allow the auth key to naturally be cleaned up if the
      keyring it is in is destroyed or cleared or the auth key is unlinked.
      
      Fixes: 7ee02a316600 ("keys: Fix dependency loop between construction record and auth key")
      Signed-off-by: 's avatarDavid Howells <dhowells@redhat.com>
      Signed-off-by: 's avatarJames Morris <james.morris@microsoft.com>
      822ad64d
  2. 08 Aug, 2018 1 commit
  3. 30 Jul, 2018 1 commit
  4. 31 May, 2018 1 commit
    • Dave Wysochanski's avatar
      NFSv4: Fix possible 1-byte stack overflow in nfs_idmap_read_and_verify_message · d6889480
      Dave Wysochanski authored
      In nfs_idmap_read_and_verify_message there is an incorrect sprintf '%d'
      that converts the __u32 'im_id' from struct idmap_msg to 'id_str', which
      is a stack char array variable of length NFS_UINT_MAXLEN == 11.
      If a uid or gid value is > 2147483647 = 0x7fffffff, the conversion
      overflows into a negative value, for example:
      crash> p (unsigned) (0x80000000)
      $1 = 2147483648
      crash> p (signed) (0x80000000)
      $2 = -2147483648
      The '-' sign is written to the buffer and this causes a 1 byte overflow
      when the NULL byte is written, which corrupts kernel stack memory.  If
      CONFIG_CC_STACKPROTECTOR_STRONG is set we see a stack-protector panic:
      
      [11558053.616565] Kernel panic - not syncing: stack-protector: Kernel stack is corrupted in: ffffffffa05b8a8c
      [11558053.639063] CPU: 6 PID: 9423 Comm: rpc.idmapd Tainted: G        W      ------------ T 3.10.0-514.el7.x86_64 #1
      [11558053.641990] Hardware name: Red Hat OpenStack Compute, BIOS 1.10.2-3.el7_4.1 04/01/2014
      [11558053.644462]  ffffffff818c7bc0 00000000b1f3aec1 ffff880de0f9bd48 ffffffff81685eac
      [11558053.646430]  ffff880de0f9bdc8 ffffffff8167f2b3 ffffffff00000010 ffff880de0f9bdd8
      [11558053.648313]  ffff880de0f9bd78 00000000b1f3aec1 ffffffff811dcb03 ffffffffa05b8a8c
      [11558053.650107] Call Trace:
      [11558053.651347]  [<ffffffff81685eac>] dump_stack+0x19/0x1b
      [11558053.653013]  [<ffffffff8167f2b3>] panic+0xe3/0x1f2
      [11558053.666240]  [<ffffffff811dcb03>] ? kfree+0x103/0x140
      [11558053.682589]  [<ffffffffa05b8a8c>] ? idmap_pipe_downcall+0x1cc/0x1e0 [nfsv4]
      [11558053.689710]  [<ffffffff810855db>] __stack_chk_fail+0x1b/0x30
      [11558053.691619]  [<ffffffffa05b8a8c>] idmap_pipe_downcall+0x1cc/0x1e0 [nfsv4]
      [11558053.693867]  [<ffffffffa00209d6>] rpc_pipe_write+0x56/0x70 [sunrpc]
      [11558053.695763]  [<ffffffff811fe12d>] vfs_write+0xbd/0x1e0
      [11558053.702236]  [<ffffffff810acccc>] ? task_work_run+0xac/0xe0
      [11558053.704215]  [<ffffffff811fec4f>] SyS_write+0x7f/0xe0
      [11558053.709674]  [<ffffffff816964c9>] system_call_fastpath+0x16/0x1b
      
      Fix this by calling the internally defined nfs_map_numeric_to_string()
      function which properly uses '%u' to convert this __u32.  For consistency,
      also replace the one other place where snprintf is called.
      Signed-off-by: 's avatarDave Wysochanski <dwysocha@redhat.com>
      Reported-by: 's avatarStephen Johnston <sjohnsto@redhat.com>
      Fixes: cf4ab538 ("NFSv4: Fix the string length returned by the idmapper")
      Cc: stable@vger.kernel.org # v3.4+
      Signed-off-by: 's avatarTrond Myklebust <trond.myklebust@hammerspace.com>
      d6889480
  5. 22 Jan, 2018 1 commit
    • Eric Biggers's avatar
      NFS: reject request for id_legacy key without auxdata · 49686cbb
      Eric Biggers authored
      nfs_idmap_legacy_upcall() is supposed to be called with 'aux' pointing
      to a 'struct idmap', via the call to request_key_with_auxdata() in
      nfs_idmap_request_key().
      
      However it can also be reached via the request_key() system call in
      which case 'aux' will be NULL, causing a NULL pointer dereference in
      nfs_idmap_prepare_pipe_upcall(), assuming that the key description is
      valid enough to get that far.
      
      Fix this by making nfs_idmap_legacy_upcall() negate the key if no
      auxdata is provided.
      
      As usual, this bug was found by syzkaller.  A simple reproducer using
      the command-line keyctl program is:
      
          keyctl request2 id_legacy uid:0 '' @s
      
      Fixes: 57e62324 ("NFS: Store the legacy idmapper result in the keyring")
      Reported-by: syzbot+5dfdbcf7b3eb5912abbb@syzkaller.appspotmail.com
      Cc: <stable@vger.kernel.org> # v3.4+
      Signed-off-by: 's avatarEric Biggers <ebiggers@google.com>
      Signed-off-by: 's avatarTrond Myklebust <trondmy@gmail.com>
      49686cbb
  6. 01 Oct, 2017 1 commit
  7. 13 Jul, 2017 1 commit
  8. 01 Mar, 2017 1 commit
    • David Howells's avatar
      KEYS: Differentiate uses of rcu_dereference_key() and user_key_payload() · 0837e49a
      David Howells authored
      rcu_dereference_key() and user_key_payload() are currently being used in
      two different, incompatible ways:
      
       (1) As a wrapper to rcu_dereference() - when only the RCU read lock used
           to protect the key.
      
       (2) As a wrapper to rcu_dereference_protected() - when the key semaphor is
           used to protect the key and the may be being modified.
      
      Fix this by splitting both of the key wrappers to produce:
      
       (1) RCU accessors for keys when caller has the key semaphore locked:
      
      	dereference_key_locked()
      	user_key_payload_locked()
      
       (2) RCU accessors for keys when caller holds the RCU read lock:
      
      	dereference_key_rcu()
      	user_key_payload_rcu()
      
      This should fix following warning in the NFS idmapper
      
        ===============================
        [ INFO: suspicious RCU usage. ]
        4.10.0 #1 Tainted: G        W
        -------------------------------
        ./include/keys/user-type.h:53 suspicious rcu_dereference_protected() usage!
        other info that might help us debug this:
        rcu_scheduler_active = 2, debug_locks = 0
        1 lock held by mount.nfs/5987:
          #0:  (rcu_read_lock){......}, at: [<d000000002527abc>] nfs_idmap_get_key+0x15c/0x420 [nfsv4]
        stack backtrace:
        CPU: 1 PID: 5987 Comm: mount.nfs Tainted: G        W       4.10.0 #1
        Call Trace:
          dump_stack+0xe8/0x154 (unreliable)
          lockdep_rcu_suspicious+0x140/0x190
          nfs_idmap_get_key+0x380/0x420 [nfsv4]
          nfs_map_name_to_uid+0x2a0/0x3b0 [nfsv4]
          decode_getfattr_attrs+0xfac/0x16b0 [nfsv4]
          decode_getfattr_generic.constprop.106+0xbc/0x150 [nfsv4]
          nfs4_xdr_dec_lookup_root+0xac/0xb0 [nfsv4]
          rpcauth_unwrap_resp+0xe8/0x140 [sunrpc]
          call_decode+0x29c/0x910 [sunrpc]
          __rpc_execute+0x140/0x8f0 [sunrpc]
          rpc_run_task+0x170/0x200 [sunrpc]
          nfs4_call_sync_sequence+0x68/0xa0 [nfsv4]
          _nfs4_lookup_root.isra.44+0xd0/0xf0 [nfsv4]
          nfs4_lookup_root+0xe0/0x350 [nfsv4]
          nfs4_lookup_root_sec+0x70/0xa0 [nfsv4]
          nfs4_find_root_sec+0xc4/0x100 [nfsv4]
          nfs4_proc_get_rootfh+0x5c/0xf0 [nfsv4]
          nfs4_get_rootfh+0x6c/0x190 [nfsv4]
          nfs4_server_common_setup+0xc4/0x260 [nfsv4]
          nfs4_create_server+0x278/0x3c0 [nfsv4]
          nfs4_remote_mount+0x50/0xb0 [nfsv4]
          mount_fs+0x74/0x210
          vfs_kern_mount+0x78/0x220
          nfs_do_root_mount+0xb0/0x140 [nfsv4]
          nfs4_try_mount+0x60/0x100 [nfsv4]
          nfs_fs_mount+0x5ec/0xda0 [nfs]
          mount_fs+0x74/0x210
          vfs_kern_mount+0x78/0x220
          do_mount+0x254/0xf70
          SyS_mount+0x94/0x100
          system_call+0x38/0xe0
      Reported-by: 's avatarJan Stancek <jstancek@redhat.com>
      Signed-off-by: 's avatarDavid Howells <dhowells@redhat.com>
      Tested-by: 's avatarJan Stancek <jstancek@redhat.com>
      Signed-off-by: 's avatarJames Morris <james.l.morris@oracle.com>
      0837e49a
  9. 11 Apr, 2016 1 commit
    • David Howells's avatar
      KEYS: Add a facility to restrict new links into a keyring · 5ac7eace
      David Howells authored
      Add a facility whereby proposed new links to be added to a keyring can be
      vetted, permitting them to be rejected if necessary.  This can be used to
      block public keys from which the signature cannot be verified or for which
      the signature verification fails.  It could also be used to provide
      blacklisting.
      
      This affects operations like add_key(), KEYCTL_LINK and KEYCTL_INSTANTIATE.
      
      To this end:
      
       (1) A function pointer is added to the key struct that, if set, points to
           the vetting function.  This is called as:
      
      	int (*restrict_link)(struct key *keyring,
      			     const struct key_type *key_type,
      			     unsigned long key_flags,
      			     const union key_payload *key_payload),
      
           where 'keyring' will be the keyring being added to, key_type and
           key_payload will describe the key being added and key_flags[*] can be
           AND'ed with KEY_FLAG_TRUSTED.
      
           [*] This parameter will be removed in a later patch when
           	 KEY_FLAG_TRUSTED is removed.
      
           The function should return 0 to allow the link to take place or an
           error (typically -ENOKEY, -ENOPKG or -EKEYREJECTED) to reject the
           link.
      
           The pointer should not be set directly, but rather should be set
           through keyring_alloc().
      
           Note that if called during add_key(), preparse is called before this
           method, but a key isn't actually allocated until after this function
           is called.
      
       (2) KEY_ALLOC_BYPASS_RESTRICTION is added.  This can be passed to
           key_create_or_update() or key_instantiate_and_link() to bypass the
           restriction check.
      
       (3) KEY_FLAG_TRUSTED_ONLY is removed.  The entire contents of a keyring
           with this restriction emplaced can be considered 'trustworthy' by
           virtue of being in the keyring when that keyring is consulted.
      
       (4) key_alloc() and keyring_alloc() take an extra argument that will be
           used to set restrict_link in the new key.  This ensures that the
           pointer is set before the key is published, thus preventing a window
           of unrestrictedness.  Normally this argument will be NULL.
      
       (5) As a temporary affair, keyring_restrict_trusted_only() is added.  It
           should be passed to keyring_alloc() as the extra argument instead of
           setting KEY_FLAG_TRUSTED_ONLY on a keyring.  This will be replaced in
           a later patch with functions that look in the appropriate places for
           authoritative keys.
      Signed-off-by: 's avatarDavid Howells <dhowells@redhat.com>
      Reviewed-by: 's avatarMimi Zohar <zohar@linux.vnet.ibm.com>
      5ac7eace
  10. 21 Oct, 2015 1 commit
    • David Howells's avatar
      KEYS: Merge the type-specific data with the payload data · 146aa8b1
      David Howells authored
      Merge the type-specific data with the payload data into one four-word chunk
      as it seems pointless to keep them separate.
      
      Use user_key_payload() for accessing the payloads of overloaded
      user-defined keys.
      Signed-off-by: 's avatarDavid Howells <dhowells@redhat.com>
      cc: linux-cifs@vger.kernel.org
      cc: ecryptfs@vger.kernel.org
      cc: linux-ext4@vger.kernel.org
      cc: linux-f2fs-devel@lists.sourceforge.net
      cc: linux-nfs@vger.kernel.org
      cc: ceph-devel@vger.kernel.org
      cc: linux-ima-devel@lists.sourceforge.net
      146aa8b1
  11. 17 Aug, 2015 1 commit
  12. 02 Jun, 2015 1 commit
  13. 23 Apr, 2015 2 commits
  14. 03 Feb, 2015 1 commit
  15. 16 Sep, 2014 1 commit
  16. 22 Jul, 2014 1 commit
  17. 17 Jul, 2014 1 commit
    • David Howells's avatar
      KEYS: Allow special keys (eg. DNS results) to be invalidated by CAP_SYS_ADMIN · 0c7774ab
      David Howells authored
      Special kernel keys, such as those used to hold DNS results for AFS, CIFS and
      NFS and those used to hold idmapper results for NFS, used to be
      'invalidateable' with key_revoke().  However, since the default permissions for
      keys were reduced:
      
      	Commit: 96b5c8fe
      	KEYS: Reduce initial permissions on keys
      
      it has become impossible to do this.
      
      Add a key flag (KEY_FLAG_ROOT_CAN_INVAL) that will permit a key to be
      invalidated by root.  This should not be used for system keyrings as the
      garbage collector will try and remove any invalidate key.  For system keyrings,
      KEY_FLAG_ROOT_CAN_CLEAR can be used instead.
      
      After this, from userspace, keyctl_invalidate() and "keyctl invalidate" can be
      used by any possessor of CAP_SYS_ADMIN (typically root) to invalidate DNS and
      idmapper keys.  Invalidated keys are immediately garbage collected and will be
      immediately rerequested if needed again.
      Signed-off-by: 's avatarDavid Howells <dhowells@redhat.com>
      Tested-by: 's avatarSteve Dickson <steved@redhat.com>
      0c7774ab
  18. 01 Sep, 2013 1 commit
  19. 30 Aug, 2013 1 commit
  20. 22 Aug, 2013 2 commits
  21. 28 Jun, 2013 1 commit
  22. 20 Mar, 2013 1 commit
  23. 23 Feb, 2013 1 commit
  24. 13 Feb, 2013 2 commits
  25. 02 Oct, 2012 2 commits
  26. 01 Oct, 2012 2 commits
  27. 28 Sep, 2012 3 commits
  28. 16 Aug, 2012 2 commits
  29. 30 Jul, 2012 2 commits
    • Bryan Schumaker's avatar
      NFS: Keep module parameters in the generic NFS client · fac1e8e4
      Bryan Schumaker authored
      Otherwise we break backwards compatibility when v4 becomes a modules.
      Signed-off-by: 's avatarTrond Myklebust <Trond.Myklebust@netapp.com>
      fac1e8e4
    • David Howells's avatar
      NFS: Fix a number of bugs in the idmapper · a427b9ec
      David Howells authored
      Fix a number of bugs in the NFS idmapper code:
      
       (1) Only registered key types can be passed to the core keys code, so
           register the legacy idmapper key type.
      
           This is a requirement because the unregister function cleans up keys
           belonging to that key type so that there aren't dangling pointers to the
           module left behind - including the key->type pointer.
      
       (2) Rename the legacy key type.  You can't have two key types with the same
           name, and (1) would otherwise require that.
      
       (3) complete_request_key() must be called in the error path of
           nfs_idmap_legacy_upcall().
      
       (4) There is one idmap struct for each nfs_client struct.  This means that
           idmap->idmap_key_cons is shared without the use of a lock.  This is a
           problem because key_instantiate_and_link() - as called indirectly by
           idmap_pipe_downcall() - releases anyone waiting for the key to be
           instantiated.
      
           What happens is that idmap_pipe_downcall() running in the rpc.idmapd
           thread, releases the NFS filesystem in whatever thread that is running in
           to continue.  This may then make another idmapper call, overwriting
           idmap_key_cons before idmap_pipe_downcall() gets the chance to call
           complete_request_key().
      
           I *think* that reading idmap_key_cons only once, before
           key_instantiate_and_link() is called, and then caching the result in a
           variable is sufficient.
      
      Bug (4) is the cause of:
      
      BUG: unable to handle kernel NULL pointer dereference at           (null)
      IP: [<          (null)>]           (null)
      PGD 0
      Oops: 0010 [#1] SMP
      CPU 1
      Modules linked in: ppdev parport_pc lp parport ip6table_filter ip6_tables ebtable_nat ebtables ipt_MASQUERADE iptable_nat nf_nat nf_conntrack_ipv4 nf_defrag_ipv4 xt_state nf_conntrack nfs fscache xt_CHECKSUM auth_rpcgss iptable_mangle nfs_acl bridge stp llc lockd be2iscsi iscsi_boot_sysfs bnx2i cnic uio cxgb4i cxgb4 cxgb3i libcxgbi cxgb3 mdio ib_iser rdma_cm ib_cm iw_cm ib_sa ib_mad ib_core ib_addr iscsi_tcp libiscsi_tcp libiscsi scsi_transport_iscsi snd_hda_codec_realtek snd_usb_audio snd_hda_intel snd_hda_codec snd_seq snd_pcm snd_hwdep snd_usbmidi_lib snd_rawmidi snd_timer uvcvideo videobuf2_core videodev media videobuf2_vmalloc snd_seq_device videobuf2_memops e1000e vhost_net iTCO_wdt joydev coretemp snd soundcore macvtap macvlan i2c_i801 snd_page_alloc tun iTCO_vendor_support microcode kvm_intel kvm sunrpc hid_logitech_dj usb_storage i915 drm_kms_helper drm i2c_algo_bit i2c_core video [last unloaded: scsi_wait_scan]
      Pid: 1229, comm: rpc.idmapd Not tainted 3.4.2-1.fc16.x86_64 #1 Gateway DX4710-UB801A/G33M05G1
      RIP: 0010:[<0000000000000000>]  [<          (null)>]           (null)
      RSP: 0018:ffff8801a3645d40  EFLAGS: 00010246
      RAX: ffff880077707e30 RBX: ffff880077707f50 RCX: ffff8801a18ccd80
      RDX: 0000000000000006 RSI: ffff8801a3645e75 RDI: ffff880077707f50
      RBP: ffff8801a3645d88 R08: ffff8801a430f9c0 R09: ffff8801a3645db0
      R10: 000000000000000a R11: 0000000000000246 R12: ffff8801a18ccd80
      R13: ffff8801a3645e75 R14: ffff8801a430f9c0 R15: 0000000000000006
      FS:  00007fb6fb51a700(0000) GS:ffff8801afc80000(0000) knlGS:0000000000000000
      CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
      CR2: 0000000000000000 CR3: 00000001a49b0000 CR4: 00000000000027e0
      DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
      DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400
      Process rpc.idmapd (pid: 1229, threadinfo ffff8801a3644000, task ffff8801a3bf9710)
      Stack:
       ffffffff81260878 ffff8801a3645db0 ffff8801a3645db0 ffff880077707a90
       ffff880077707f50 ffff8801a18ccd80 0000000000000006 ffff8801a3645e75
       ffff8801a430f9c0 ffff8801a3645dd8 ffffffff81260983 ffff8801a3645de8
      Call Trace:
       [<ffffffff81260878>] ? __key_instantiate_and_link+0x58/0x100
       [<ffffffff81260983>] key_instantiate_and_link+0x63/0xa0
       [<ffffffffa057062b>] idmap_pipe_downcall+0x1cb/0x1e0 [nfs]
       [<ffffffffa0107f57>] rpc_pipe_write+0x67/0x90 [sunrpc]
       [<ffffffff8117f833>] vfs_write+0xb3/0x180
       [<ffffffff8117fb5a>] sys_write+0x4a/0x90
       [<ffffffff81600329>] system_call_fastpath+0x16/0x1b
      Code:  Bad RIP value.
      RIP  [<          (null)>]           (null)
       RSP <ffff8801a3645d40>
      CR2: 0000000000000000
      Signed-off-by: 's avatarDavid Howells <dhowells@redhat.com>
      Reviewed-by: 's avatarSteve Dickson <steved@redhat.com>
      Signed-off-by: 's avatarTrond Myklebust <Trond.Myklebust@netapp.com>
      Cc: stable@vger.kernel.org [>= 3.4]
      a427b9ec
  30. 20 Jun, 2012 1 commit
  31. 23 May, 2012 1 commit