From: Greg Kroah-Hartman Date: Mon, 30 Oct 2017 08:27:09 +0000 (+0100) Subject: Merge 4.9.59 into android-4.9 X-Git-Tag: android-x86-7.1-r1~6^2~101 X-Git-Url: http://git.osdn.net/view?a=commitdiff_plain;h=16cc920a0fd2c4e304816f96d216d46effb61594;p=android-x86%2Fkernel.git Merge 4.9.59 into android-4.9 Changes in 4.9.59 USB: devio: Revert "USB: devio: Don't corrupt user memory" USB: core: fix out-of-bounds access bug in usb_get_bos_descriptor() USB: serial: metro-usb: add MS7820 device id usb: cdc_acm: Add quirk for Elatec TWN3 usb: quirks: add quirk for WORLDE MINI MIDI keyboard usb: hub: Allow reset retry for USB2 devices on connect bounce ALSA: usb-audio: Add native DSD support for Pro-Ject Pre Box S2 Digital can: gs_usb: fix busy loop if no more TX context is available parisc: Fix double-word compare and exchange in LWS code on 32-bit kernels iio: dummy: events: Add missing break usb: musb: sunxi: Explicitly release USB PHY on exit usb: musb: Check for host-mode using is_host_active() on reset interrupt xhci: Identify USB 3.1 capable hosts by their port protocol capability can: esd_usb2: Fix can_dlc value for received RTR, frames drm/nouveau/bsp/g92: disable by default drm/nouveau/mmu: flush tlbs before deleting page tables ALSA: seq: Enable 'use' locking in all configurations ALSA: hda: Remove superfluous '-' added by printk conversion ALSA: hda: Abort capability probe at invalid register read i2c: ismt: Separate I2C block read from SMBus block read i2c: piix4: Fix SMBus port selection for AMD Family 17h chips brcmfmac: Add check for short event packets brcmsmac: make some local variables 'static const' to reduce stack size bus: mbus: fix window size calculation for 4GB windows clockevents/drivers/cs5535: Improve resilience to spurious interrupts rtlwifi: rtl8821ae: Fix connection lost problem x86/microcode/intel: Disable late loading on model 79 KEYS: encrypted: fix dereference of NULL user_key_payload lib/digsig: fix dereference of NULL user_key_payload KEYS: don't let add_key() update an uninstantiated key pkcs7: Prevent NULL pointer dereference, since sinfo is not always set. vmbus: fix missing signaling in hv_signal_on_read() xfs: don't unconditionally clear the reflink flag on zero-block files xfs: evict CoW fork extents when performing finsert/fcollapse fs/xfs: Use %pS printk format for direct addresses xfs: report zeroed or not correctly in xfs_zero_range() xfs: update i_size after unwritten conversion in dio completion xfs: perag initialization should only touch m_ag_max_usable for AG 0 xfs: Capture state of the right inode in xfs_iflush_done xfs: always swap the cow forks when swapping extents xfs: handle racy AIO in xfs_reflink_end_cow xfs: Don't log uninitialised fields in inode structures xfs: move more RT specific code under CONFIG_XFS_RT xfs: don't change inode mode if ACL update fails xfs: reinit btree pointer on attr tree inactivation walk xfs: handle error if xfs_btree_get_bufs fails xfs: cancel dirty pages on invalidation xfs: trim writepage mapping to within eof fscrypt: fix dereference of NULL user_key_payload KEYS: Fix race between updating and finding a negative key FS-Cache: fix dereference of NULL user_key_payload Linux 4.9.59 Signed-off-by: Greg Kroah-Hartman --- 16cc920a0fd2c4e304816f96d216d46effb61594 diff --cc fs/crypto/keyinfo.c index 018c588c7ac3,a755fa1a0017..8e704d12a1cf --- a/fs/crypto/keyinfo.c +++ b/fs/crypto/keyinfo.c @@@ -108,7 -107,12 +108,12 @@@ static int validate_user_key(struct fsc res = -ENOKEY; goto out; } - ukp = user_key_payload(keyring_key); + ukp = user_key_payload_locked(keyring_key); + if (!ukp) { + /* key was revoked before we acquired its semaphore */ + res = -EKEYREVOKED; + goto out; + } if (ukp->datalen != sizeof(struct fscrypt_key)) { res = -EINVAL; goto out; diff --cc fs/fscache/object-list.c index 67f940892ef8,37e0c31d284f..5eb2e24ce790 --- a/fs/fscache/object-list.c +++ b/fs/fscache/object-list.c @@@ -329,7 -329,14 +329,14 @@@ static void fscache_objlist_config(stru config = 0; rcu_read_lock(); - confkey = user_key_payload(key); + confkey = user_key_payload_rcu(key); + if (!confkey) { + /* key was revoked */ + rcu_read_unlock(); + key_put(key); + goto no_config; + } + buf = confkey->data; for (len = confkey->datalen - 1; len >= 0; len--) { diff --cc include/linux/key.h index 2de88a3ebee0,ed9b44fd9580..7e2d14379f49 --- a/include/linux/key.h +++ b/include/linux/key.h @@@ -350,16 -359,17 +359,20 @@@ static inline short key_read_state(cons * Return true if the specified key has been positively instantiated, false * otherwise. */ - static inline bool key_is_instantiated(const struct key *key) + static inline bool key_is_positive(const struct key *key) + { + return key_read_state(key) == KEY_IS_POSITIVE; + } + + static inline bool key_is_negative(const struct key *key) { - return test_bit(KEY_FLAG_INSTANTIATED, &key->flags) && - !test_bit(KEY_FLAG_NEGATIVE, &key->flags); + return key_read_state(key) < 0; } -#define rcu_dereference_key(KEY) \ +#define dereference_key_rcu(KEY) \ + (rcu_dereference((KEY)->payload.rcu_data0)) + +#define dereference_key_locked(KEY) \ (rcu_dereference_protected((KEY)->payload.rcu_data0, \ rwsem_is_locked(&((struct key *)(KEY))->sem))) diff --cc lib/digsig.c index 03d7c63837ae,a876156503f0..6ba6fcd92dd1 --- a/lib/digsig.c +++ b/lib/digsig.c @@@ -85,8 -85,14 +85,14 @@@ static int digsig_verify_rsa(struct ke struct pubkey_hdr *pkh; down_read(&key->sem); - ukp = user_key_payload(key); + ukp = user_key_payload_locked(key); + if (!ukp) { + /* key was revoked before we acquired its semaphore */ + err = -EKEYREVOKED; + goto err1; + } + if (ukp->datalen < sizeof(*pkh)) goto err1; diff --cc security/keys/encrypted-keys/encrypted.c index a62eba231899,a871159bf03c..ae70e828da2e --- a/security/keys/encrypted-keys/encrypted.c +++ b/security/keys/encrypted-keys/encrypted.c @@@ -314,7 -314,14 +314,14 @@@ static struct key *request_user_key(con goto error; down_read(&ukey->sem); - upayload = user_key_payload(ukey); + upayload = user_key_payload_locked(ukey); + if (!upayload) { + /* key was revoked before we acquired its semaphore */ + up_read(&ukey->sem); + key_put(ukey); + ukey = ERR_PTR(-EKEYREVOKED); + goto error; + } *master_key = upayload->data; *master_keylen = upayload->datalen; error: diff --cc security/keys/user_defined.c index fa880f6a1924,3dc2607211cc..b4c170af7532 --- a/security/keys/user_defined.c +++ b/security/keys/user_defined.c @@@ -106,8 -106,8 +106,8 @@@ int user_update(struct key *key, struc /* attach the new data, displacing the old */ key->expiry = prep->expiry; - if (!test_bit(KEY_FLAG_NEGATIVE, &key->flags)) + if (key_is_positive(key)) - zap = rcu_dereference_key(key); + zap = dereference_key_locked(key); rcu_assign_keypointer(key, prep->payload.data[0]); prep->payload.data[0] = NULL;