Skip to contentSkip to conversation

Linux 4.4.95

DISCUSSION Greg KH 1 participant 2 messages Oct 27, 2017 Stable branch

lore
Share & tools
lore

Greg KH

author maintainer
#0 lore raw

I'm announcing the release of the 4.4.95 kernel.

All users of the 4.4 kernel series must upgrade.

The updated 4.4.y git tree can be found at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable.git linux-4.4.y
and can be browsed at the normal kernel.org git web browser:
http://git.kernel.org/?p=linux/kernel/git/stable/linux-stable.git;a=summary

thanks,

greg k-h

------------

 Makefile                                            |    2 
 arch/parisc/kernel/syscall.S                        |   55 ++---
 crypto/asymmetric_keys/pkcs7_parser.c               |    3 
 drivers/bus/mvebu-mbus.c                            |    2 
 drivers/clocksource/cs5535-clockevt.c               |    3 
 drivers/gpu/drm/nouveau/nvkm/engine/bsp/g84.c       |    2 
 drivers/gpu/drm/nouveau/nvkm/subdev/mmu/base.c      |    2 
 drivers/i2c/busses/i2c-ismt.c                       |    5 
 drivers/net/can/usb/esd_usb2.c                      |    2 
 drivers/net/can/usb/gs_usb.c                        |   10 -
 drivers/net/wireless/brcm80211/brcmsmac/phy/phy_n.c |  197 +++++++++-----------
 drivers/net/wireless/realtek/rtlwifi/rtl8821ae/hw.c |    2 
 drivers/usb/class/cdc-acm.c                         |    3 
 drivers/usb/core/config.c                           |    6 
 drivers/usb/core/devio.c                            |    6 
 drivers/usb/core/hub.c                              |   11 -
 drivers/usb/core/quirks.c                           |    4 
 drivers/usb/musb/musb_core.c                        |    6 
 drivers/usb/musb/sunxi.c                            |    2 
 drivers/usb/serial/metro-usb.c                      |    1 
 fs/ext4/crypto_key.c                                |    6 
 fs/f2fs/crypto.c                                    |    1 
 fs/f2fs/crypto_fname.c                              |    2 
 fs/f2fs/crypto_key.c                                |   25 ++
 fs/f2fs/file.c                                      |    6 
 fs/fscache/object-list.c                            |    7 
 include/linux/key.h                                 |   49 +++-
 include/linux/mbus.h                                |    4 
 kernel/sched/auto_group.c                           |   23 +-
 lib/digsig.c                                        |    6 
 net/dns_resolver/dns_key.c                          |    2 
 security/keys/big_key.c                             |    4 
 security/keys/encrypted-keys/encrypted.c            |    9 
 security/keys/gc.c                                  |    8 
 security/keys/key.c                                 |   41 +++-
 security/keys/keyctl.c                              |    9 
 security/keys/keyring.c                             |   10 -
 security/keys/proc.c                                |    7 
 security/keys/process_keys.c                        |    2 
 security/keys/request_key.c                         |    7 
 security/keys/request_key_auth.c                    |    2 
 security/keys/trusted.c                             |    2 
 security/keys/user_defined.c                        |    4 
 sound/core/seq/seq_lock.c                           |    4 
 sound/core/seq/seq_lock.h                           |   12 -
 sound/pci/hda/hda_codec.c                           |    2 
 sound/usb/quirks.c                                  |    1 
 47 files changed, 325 insertions(+), 254 deletions(-)

Alan Stern (1):
USB: core: fix out-of-bounds access bug in usb_get_bos_descriptor()

Arnd Bergmann (1):
brcmsmac: make some local variables 'static const' to reduce stack size

Ben Hutchings (1):
ALSA: seq: Enable 'use' locking in all configurations

Ben Skeggs (1):
drm/nouveau/mmu: flush tlbs before deleting page tables

David Howells (2):
KEYS: don't let add_key() update an uninstantiated key
KEYS: Fix race between updating and finding a negative key

David Kozub (1):
clockevents/drivers/cs5535: Improve resilience to spurious interrupts

Eric Biggers (5):
KEYS: encrypted: fix dereference of NULL user_key_payload lib/digsig: fix dereference of NULL user_key_payload
fscrypt: fix dereference of NULL user_key_payload
fscrypto: require write access to mount to set encryption policy
FS-Cache: fix dereference of NULL user_key_payload

Eric Sesterhenn (1):
pkcs7: Prevent NULL pointer dereference, since sinfo is not always set.

Felipe Balbi (1):
usb: quirks: add quirk for WORLDE MINI MIDI keyboard

Greg Kroah-Hartman (1):

      Linux 4.4.95

Hans de Goede (1):
USB: devio: Revert "USB: devio: Don't corrupt user memory"

Ilia Mirkin (1):
drm/nouveau/bsp/g92: disable by default

Jaegeuk Kim (2):
f2fs crypto: replace some BUG_ON()'s with error checks f2fs crypto: add missing locking for keyring_key access

Jan Luebbe (1):
bus: mbus: fix window size calculation for 4GB windows

Johan Hovold (1):
USB: serial: metro-usb: add MS7820 device id

John David Anglin (2):
parisc: Avoid trashing sr2 and sr3 in LWS code
parisc: Fix double-word compare and exchange in LWS code on 32-bit kernels

Jonathan Liu (2):
usb: musb: sunxi: Explicitly release USB PHY on exit
usb: musb: Check for host-mode using is_host_active() on reset interrupt

Jussi Laako (1):
ALSA: usb-audio: Add native DSD support for Pro-Ject Pre Box S2 Digital

Larry Finger (1):
rtlwifi: rtl8821ae: Fix connection lost problem

Maksim Salau (1):
usb: cdc_acm: Add quirk for Elatec TWN3

Mathias Nyman (1):
usb: hub: Allow reset retry for USB2 devices on connect bounce

Oleg Nesterov (1):
sched/autogroup: Fix autogroup_move_group() to never skip sched_move_task()

Pontus Andersson (1):
i2c: ismt: Separate I2C block read from SMBus block read

Stefan Mätje (1):
can: esd_usb2: Fix can_dlc value for received RTR, frames

Takashi Iwai (1):
ALSA: hda: Remove superfluous '-' added by printk conversion

Wolfgang Grandegger (1):
can: gs_usb: fix busy loop if no more TX context is available

author maintainer
#1 lore raw
Makefile +1 -1
index ff9d6bbf2210..57e1ea2a189a 100644
@@ -1,6 +1,6 @@
 VERSION = 4
 PATCHLEVEL = 4
-SUBLEVEL = 94
+SUBLEVEL = 95
 EXTRAVERSION =
 NAME = Blurry Fish Butt
 
arch/parisc/kernel/syscall.S +25 -30

138 lines not on this page · raw message

crypto/asymmetric_keys/pkcs7_parser.c +3 -0
index 8f3056cd0399..2516e97c58f1 100644
@@ -90,6 +90,9 @@ static int pkcs7_check_authattrs(struct pkcs7_message *msg)
 	bool want;
 
 	sinfo = msg->signed_infos;
+	if (!sinfo)
+		goto inconsistent;
+
 	if (sinfo->authattrs) {
 		want = true;
 		msg->have_authattrs = true;
drivers/bus/mvebu-mbus.c +1 -1
index c43c3d2baf73..0d628becf37f 100644
@@ -720,7 +720,7 @@ mvebu_mbus_default_setup_cpu_target(struct mvebu_mbus_state *mbus)
 			if (mbus->hw_io_coherency)
 				w->mbus_attr |= ATTR_HW_COHERENCY;
 			w->base = base & DDR_BASE_CS_LOW_MASK;
-			w->size = (size | ~DDR_SIZE_MASK) + 1;
+			w->size = (u64)(size | ~DDR_SIZE_MASK) + 1;
 		}
 	}
 	mvebu_mbus_dram_info.num_cs = cs;
drivers/clocksource/cs5535-clockevt.c +2 -1
index 9a7e37cf56b0..e1d7373e63e0 100644
@@ -117,7 +117,8 @@ static irqreturn_t mfgpt_tick(int irq, void *dev_id)
 	/* Turn off the clock (and clear the event) */
 	disable_timer(cs5535_event_clock);
 
-	if (clockevent_state_shutdown(&cs5535_clockevent))
+	if (clockevent_state_detached(&cs5535_clockevent) ||
+	    clockevent_state_shutdown(&cs5535_clockevent))
 		return IRQ_HANDLED;
 
 	/* Clear the counter */
drivers/gpu/drm/nouveau/nvkm/engine/bsp/g84.c +1 -1
index 3ef01071f073..103471ff4dc4 100644
@@ -40,5 +40,5 @@ int
 g84_bsp_new(struct nvkm_device *device, int index, struct nvkm_engine **pengine)
 {
 	return nvkm_xtensa_new_(&g84_bsp, device, index,
-				true, 0x103000, pengine);
+				device->chipset != 0x92, 0x103000, pengine);
 }
drivers/gpu/drm/nouveau/nvkm/subdev/mmu/base.c +2 -0
index e04a2296ecd0..5bb7f7e0f11f 100644
@@ -240,6 +240,8 @@ nvkm_vm_unmap_pgt(struct nvkm_vm *vm, int big, u32 fpde, u32 lpde)
 			mmu->func->map_pgt(vpgd->obj, pde, vpgt->mem);
 		}
 
+		mmu->func->flush(vm);
+
 		nvkm_memory_del(&pgt);
 	}
 }
drivers/i2c/busses/i2c-ismt.c +4 -1
index 639d1a9c8793..1111cb966a44 100644
@@ -338,12 +338,15 @@ static int ismt_process_desc(const struct ismt_desc *desc,
 			data->word = dma_buffer[0] | (dma_buffer[1] << 8);
 			break;
 		case I2C_SMBUS_BLOCK_DATA:
-		case I2C_SMBUS_I2C_BLOCK_DATA:
 			if (desc->rxbytes != dma_buffer[0] + 1)
 				return -EMSGSIZE;
 
 			memcpy(data->block, dma_buffer, desc->rxbytes);
 			break;
+		case I2C_SMBUS_I2C_BLOCK_DATA:
+			memcpy(&data->block[1], dma_buffer, desc->rxbytes);
+			data->block[0] = desc->rxbytes;
+			break;
 		}
 		return 0;
 	}
drivers/net/can/usb/esd_usb2.c +1 -1
index 113e64fcd73b..4c6707ecc619 100644
@@ -333,7 +333,7 @@ static void esd_usb2_rx_can_msg(struct esd_usb2_net_priv *priv,
 		}
 
 		cf->can_id = id & ESD_IDMASK;
-		cf->can_dlc = get_can_dlc(msg->msg.rx.dlc);
+		cf->can_dlc = get_can_dlc(msg->msg.rx.dlc & ~ESD_RTR);
 
 		if (id & ESD_EXTID)
 			cf->can_id |= CAN_EFF_FLAG;
drivers/net/can/usb/gs_usb.c +2 -8
index ae5709354546..27e2352fcc42 100644
@@ -356,6 +356,8 @@ static void gs_usb_receive_bulk_callback(struct urb *urb)
 
 		gs_free_tx_context(txc);
 
+		atomic_dec(&dev->active_tx_urbs);
+
 		netif_wake_queue(netdev);
 	}
 
@@ -444,14 +446,6 @@ static void gs_usb_xmit_callback(struct urb *urb)
 			  urb->transfer_buffer_length,
 			  urb->transfer_buffer,
 			  urb->transfer_dma);
-
-	atomic_dec(&dev->active_tx_urbs);
-
-	if (!netif_device_present(netdev))
-		return;
-
-	if (netif_queue_stopped(netdev))
-		netif_wake_queue(netdev);
 }
 
 static netdev_tx_t gs_can_start_xmit(struct sk_buff *skb, struct net_device *netdev)
drivers/net/wireless/brcm80211/brcmsmac/phy/phy_n.c +97 -100

374 lines not on this page · raw message

drivers/net/wireless/realtek/rtlwifi/rtl8821ae/hw.c +1 -1
index c2103e7a8132..bbb789f8990b 100644
@@ -1127,7 +1127,7 @@ static u8 _rtl8821ae_dbi_read(struct rtl_priv *rtlpriv, u16 addr)
 	}
 	if (0 == tmp) {
 		read_addr = REG_DBI_RDATA + addr % 4;
-		ret = rtl_read_byte(rtlpriv, read_addr);
+		ret = rtl_read_word(rtlpriv, read_addr);
 	}
 	return ret;
 }
drivers/usb/class/cdc-acm.c +3 -0
index df96f5f88c15..3f6bb3fff890 100644
@@ -1762,6 +1762,9 @@ static const struct usb_device_id acm_ids[] = {
 	{ USB_DEVICE(0xfff0, 0x0100), /* DATECS FP-2000 */
 	.driver_info = NO_UNION_NORMAL, /* reports zero length descriptor */
 	},
+	{ USB_DEVICE(0x09d8, 0x0320), /* Elatec GmbH TWN3 */
+	.driver_info = NO_UNION_NORMAL, /* has misplaced union descriptor */
+	},
 
 	{ USB_DEVICE(0x2912, 0x0001), /* ATOL FPrint */
 	.driver_info = CLEAR_HALT_CONDITIONS,
drivers/usb/core/config.c +4 -2
index d9d048fc9082..5172bec612eb 100644
@@ -926,10 +926,12 @@ int usb_get_bos_descriptor(struct usb_device *dev)
 	for (i = 0; i < num; i++) {
 		buffer += length;
 		cap = (struct usb_dev_cap_header *)buffer;
-		length = cap->bLength;
 
-		if (total_len < length)
+		if (total_len < sizeof(*cap) || total_len < cap->bLength) {
+			dev->bos->desc->bNumDeviceCaps = i;
 			break;
+		}
+		length = cap->bLength;
 		total_len -= length;
 
 		if (cap->bDescriptorType != USB_DT_DEVICE_CAPABILITY) {
drivers/usb/core/devio.c +1 -5
index bd9419213d06..873ba02d59e6 100644
@@ -1417,11 +1417,7 @@ static int proc_do_submiturb(struct usb_dev_state *ps, struct usbdevfs_urb *uurb
 			totlen += isopkt[u].length;
 		}
 		u *= sizeof(struct usb_iso_packet_descriptor);
-		if (totlen <= uurb->buffer_length)
-			uurb->buffer_length = totlen;
-		else
-			WARN_ONCE(1, "uurb->buffer_length is too short %d vs %d",
-				  totlen, uurb->buffer_length);
+		uurb->buffer_length = totlen;
 		break;
 
 	default:
drivers/usb/core/hub.c +7 -4
index 51bba58c0c3b..22e61786354a 100644
@@ -2656,13 +2656,16 @@ static int hub_port_wait_reset(struct usb_hub *hub, int port1,
 	if (!(portstatus & USB_PORT_STAT_CONNECTION))
 		return -ENOTCONN;
 
-	/* bomb out completely if the connection bounced.  A USB 3.0
-	 * connection may bounce if multiple warm resets were issued,
+	/* Retry if connect change is set but status is still connected.
+	 * A USB 3.0 connection may bounce if multiple warm resets were issued,
 	 * but the device may have successfully re-connected. Ignore it.
 	 */
 	if (!hub_is_superspeed(hub->hdev) &&
-			(portchange & USB_PORT_STAT_C_CONNECTION))
-		return -ENOTCONN;
+	    (portchange & USB_PORT_STAT_C_CONNECTION)) {
+		usb_clear_port_feature(hub->hdev, port1,
+				       USB_PORT_FEAT_C_CONNECTION);
+		return -EAGAIN;
+	}
 
 	if (!(portstatus & USB_PORT_STAT_ENABLE))
 		return -EBUSY;
drivers/usb/core/quirks.c +4 -0
index 82806e311202..a6aaf2f193a4 100644
@@ -221,6 +221,10 @@ static const struct usb_device_id usb_quirk_list[] = {
 	/* Corsair Strafe RGB */
 	{ USB_DEVICE(0x1b1c, 0x1b20), .driver_info = USB_QUIRK_DELAY_INIT },
 
+	/* MIDI keyboard WORLDE MINI */
+	{ USB_DEVICE(0x1c75, 0x0204), .driver_info =
+			USB_QUIRK_CONFIG_INTF_STRINGS },
+
 	/* Acer C120 LED Projector */
 	{ USB_DEVICE(0x1de1, 0xc102), .driver_info = USB_QUIRK_NO_LPM },
 
drivers/usb/musb/musb_core.c +2 -4
index 00eed5d66fda..06d83825923a 100644
@@ -877,7 +877,7 @@ b_host:
 	 */
 	if (int_usb & MUSB_INTR_RESET) {
 		handled = IRQ_HANDLED;
-		if (devctl & MUSB_DEVCTL_HM) {
+		if (is_host_active(musb)) {
 			/*
 			 * When BABBLE happens what we can depends on which
 			 * platform MUSB is running, because some platforms
@@ -887,9 +887,7 @@ b_host:
 			 * drop the session.
 			 */
 			dev_err(musb->controller, "Babble\n");
-
-			if (is_host_active(musb))
-				musb_recover_from_babble(musb);
+			musb_recover_from_babble(musb);
 		} else {
 			dev_dbg(musb->controller, "BUS RESET as %s\n",
 				usb_otg_state_string(musb->xceiv->otg->state));
drivers/usb/musb/sunxi.c +2 -0
index d9b0dc461439..2d3be66fb563 100644
@@ -320,6 +320,8 @@ static int sunxi_musb_exit(struct musb *musb)
 	if (test_bit(SUNXI_MUSB_FL_HAS_SRAM, &glue->flags))
 		sunxi_sram_release(musb->controller->parent);
 
+	devm_usb_put_phy(glue->dev, glue->xceiv);
+
 	return 0;
 }
 
drivers/usb/serial/metro-usb.c +1 -0
index 39e683096e94..45182c65fa1f 100644
@@ -45,6 +45,7 @@ struct metrousb_private {
 static const struct usb_device_id id_table[] = {
 	{ USB_DEVICE(FOCUS_VENDOR_ID, FOCUS_PRODUCT_ID_BI) },
 	{ USB_DEVICE(FOCUS_VENDOR_ID, FOCUS_PRODUCT_ID_UNI) },
+	{ USB_DEVICE_INTERFACE_CLASS(0x0c2e, 0x0730, 0xff) },	/* MS7820 */
 	{ }, /* Terminating entry. */
 };
 MODULE_DEVICE_TABLE(usb, id_table);
fs/ext4/crypto_key.c +6 -0
index 505f8afde57c..9a1bc638abce 100644
@@ -204,6 +204,12 @@ int ext4_get_encryption_info(struct inode *inode)
 	}
 	down_read(&keyring_key->sem);
 	ukp = user_key_payload(keyring_key);
+	if (!ukp) {
+		/* key was revoked before we acquired its semaphore */
+		res = -EKEYREVOKED;
+		up_read(&keyring_key->sem);
+		goto out;
+	}
 	if (ukp->datalen != sizeof(struct ext4_encryption_key)) {
 		res = -EINVAL;
 		up_read(&keyring_key->sem);
fs/f2fs/crypto.c +0 -1
index 4a62ef14e932..d879c6c846b7 100644
@@ -362,7 +362,6 @@ static int f2fs_page_crypto(struct f2fs_crypto_ctx *ctx,
 	else
 		res = crypto_ablkcipher_encrypt(req);
 	if (res == -EINPROGRESS || res == -EBUSY) {
-		BUG_ON(req->base.data != &ecr);
 		wait_for_completion(&ecr.completion);
 		res = ecr.res;
 	}
fs/f2fs/crypto_fname.c +0 -2
index 38349ed5ea51..0fce444dd5ae 100644
@@ -124,7 +124,6 @@ static int f2fs_fname_encrypt(struct inode *inode,
 	ablkcipher_request_set_crypt(req, &src_sg, &dst_sg, ciphertext_len, iv);
 	res = crypto_ablkcipher_encrypt(req);
 	if (res == -EINPROGRESS || res == -EBUSY) {
-		BUG_ON(req->base.data != &ecr);
 		wait_for_completion(&ecr.completion);
 		res = ecr.res;
 	}
@@ -180,7 +179,6 @@ static int f2fs_fname_decrypt(struct inode *inode,
 	ablkcipher_request_set_crypt(req, &src_sg, &dst_sg, iname->len, iv);
 	res = crypto_ablkcipher_decrypt(req);
 	if (res == -EINPROGRESS || res == -EBUSY) {
-		BUG_ON(req->base.data != &ecr);
 		wait_for_completion(&ecr.completion);
 		res = ecr.res;
 	}
fs/f2fs/crypto_key.c +22 -3
index 18595d7a0efc..7e62889a1d3d 100644
@@ -75,7 +75,6 @@ static int f2fs_derive_key_aes(char deriving_key[F2FS_AES_128_ECB_KEY_SIZE],
 					F2FS_AES_256_XTS_KEY_SIZE, NULL);
 	res = crypto_ablkcipher_encrypt(req);
 	if (res == -EINPROGRESS || res == -EBUSY) {
-		BUG_ON(req->base.data != &ecr);
 		wait_for_completion(&ecr.completion);
 		res = ecr.res;
 	}
@@ -189,18 +188,38 @@ int f2fs_get_encryption_info(struct inode *inode)
 		keyring_key = NULL;
 		goto out;
 	}
-	BUG_ON(keyring_key->type != &key_type_logon);
+	if (keyring_key->type != &key_type_logon) {
+		printk_once(KERN_WARNING "f2fs: key type must be logon\n");
+		res = -ENOKEY;
+		goto out;
+	}
+	down_read(&keyring_key->sem);
 	ukp = user_key_payload(keyring_key);
+	if (!ukp) {
+		/* key was revoked before we acquired its semaphore */
+		res = -EKEYREVOKED;
+		up_read(&keyring_key->sem);
+		goto out;
+	}
 	if (ukp->datalen != sizeof(struct f2fs_encryption_key)) {
 		res = -EINVAL;
+		up_read(&keyring_key->sem);
 		goto out;
 	}
 	master_key = (struct f2fs_encryption_key *)ukp->data;
 	BUILD_BUG_ON(F2FS_AES_128_ECB_KEY_SIZE !=
 				F2FS_KEY_DERIVATION_NONCE_SIZE);
-	BUG_ON(master_key->size != F2FS_AES_256_XTS_KEY_SIZE);
+	if (master_key->size != F2FS_AES_256_XTS_KEY_SIZE) {
+		printk_once(KERN_WARNING
+				"f2fs: key size incorrect: %d\n",
+				master_key->size);
+		res = -ENOKEY;
+		up_read(&keyring_key->sem);
+		goto out;
+	}
 	res = f2fs_derive_key_aes(ctx.nonce, master_key->raw,
 				  raw_key);
+	up_read(&keyring_key->sem);
 	if (res)
 		goto out;
 
fs/f2fs/file.c +6 -0
index 4b449d263333..01eed94b01ea 100644
@@ -1541,12 +1541,18 @@ static int f2fs_ioc_set_encryption_policy(struct file *filp, unsigned long arg)
 				sizeof(policy)))
 		return -EFAULT;
 
+	err = mnt_want_write_file(filp);
+	if (err)
+		return err;
+
 	mutex_lock(&inode->i_mutex);
 
 	err = f2fs_process_policy(&policy, inode);
 
 	mutex_unlock(&inode->i_mutex);
 
+	mnt_drop_write_file(filp);
+
 	return err;
 #else
 	return -EOPNOTSUPP;
fs/fscache/object-list.c +7 -0
index 6b028b7c4250..926580a85153 100644
@@ -330,6 +330,13 @@ static void fscache_objlist_config(struct fscache_objlist_data *data)
 	rcu_read_lock();
 
 	confkey = user_key_payload(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--) {
include/linux/key.h +31 -18

86 lines not on this page · raw message

include/linux/mbus.h +2 -2
index 1f7bc630d225..71a5a56b0bba 100644
@@ -29,8 +29,8 @@ struct mbus_dram_target_info
 	struct mbus_dram_window {
 		u8	cs_index;
 		u8	mbus_attr;
-		u32	base;
-		u32	size;
+		u64	base;
+		u64	size;
 	} cs[4];
 };
 
kernel/sched/auto_group.c +12 -11
index 750ed601ddf7..8620fd01b3d0 100644
@@ -111,14 +111,11 @@ bool task_wants_autogroup(struct task_struct *p, struct task_group *tg)
 {
 	if (tg != &root_task_group)
 		return false;
-
 	/*
-	 * We can only assume the task group can't go away on us if
-	 * autogroup_move_group() can see us on ->thread_group list.
+	 * If we race with autogroup_move_group() the caller can use the old
+	 * value of signal->autogroup but in this case sched_move_task() will
+	 * be called again before autogroup_kref_put().
 	 */
-	if (p->flags & PF_EXITING)
-		return false;
-
 	return true;
 }
 
@@ -138,13 +135,17 @@ autogroup_move_group(struct task_struct *p, struct autogroup *ag)
 	}
 
 	p->signal->autogroup = autogroup_kref_get(ag);
-
-	if (!READ_ONCE(sysctl_sched_autogroup_enabled))
-		goto out;
-
+	/*
+	 * We can't avoid sched_move_task() after we changed signal->autogroup,
+	 * this process can already run with task_group() == prev->tg or we can
+	 * race with cgroup code which can read autogroup = prev under rq->lock.
+	 * In the latter case for_each_thread() can not miss a migrating thread,
+	 * cpu_cgroup_attach() must not be possible after cgroup_exit() and it
+	 * can't be removed from thread list, we hold ->siglock.
+	 */
 	for_each_thread(p, t)
 		sched_move_task(t);
-out:
+
 	unlock_task_sighand(p, &flags);
 	autogroup_kref_put(prev);
 }
lib/digsig.c +6 -0
index 07be6c1ef4e2..00c5c8179393 100644
@@ -87,6 +87,12 @@ static int digsig_verify_rsa(struct key *key,
 	down_read(&key->sem);
 	ukp = user_key_payload(key);
 
+	if (!ukp) {
+		/* key was revoked before we acquired its semaphore */
+		err = -EKEYREVOKED;
+		goto err1;
+	}
+
 	if (ukp->datalen < sizeof(*pkh))
 		goto err1;
 
net/dns_resolver/dns_key.c +1 -1
index c79b85eb4d4c..6abc5012200b 100644
@@ -224,7 +224,7 @@ static int dns_resolver_match_preparse(struct key_match_data *match_data)
 static void dns_resolver_describe(const struct key *key, struct seq_file *m)
 {
 	seq_puts(m, key->description);
-	if (key_is_instantiated(key)) {
+	if (key_is_positive(key)) {
 		int err = PTR_ERR(key->payload.data[dns_key_error]);
 
 		if (err)
security/keys/big_key.c +2 -2
index 907c1522ee46..08c4cc5c2973 100644
@@ -138,7 +138,7 @@ void big_key_revoke(struct key *key)
 
 	/* clear the quota */
 	key_payload_reserve(key, 0);
-	if (key_is_instantiated(key) &&
+	if (key_is_positive(key) &&
 	    (size_t)key->payload.data[big_key_len] > BIG_KEY_FILE_THRESHOLD)
 		vfs_truncate(path, 0);
 }
@@ -170,7 +170,7 @@ void big_key_describe(const struct key *key, struct seq_file *m)
 
 	seq_puts(m, key->description);
 
-	if (key_is_instantiated(key))
+	if (key_is_positive(key))
 		seq_printf(m, ": %zu [%s]",
 			   datalen,
 			   datalen > BIG_KEY_FILE_THRESHOLD ? "file" : "buff");
security/keys/encrypted-keys/encrypted.c +8 -1
index 31898856682e..ce295c0c1da0 100644
@@ -315,6 +315,13 @@ static struct key *request_user_key(const char *master_desc, const u8 **master_k
 
 	down_read(&ukey->sem);
 	upayload = user_key_payload(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:
@@ -845,7 +852,7 @@ static int encrypted_update(struct key *key, struct key_preparsed_payload *prep)
 	size_t datalen = prep->datalen;
 	int ret = 0;
 
-	if (test_bit(KEY_FLAG_NEGATIVE, &key->flags))
+	if (key_is_negative(key))
 		return -ENOKEY;
 	if (datalen <= 0 || datalen > 32767 || !prep->data)
 		return -EINVAL;
security/keys/gc.c +4 -4
index 9cb4fe4478a1..1659094d684d 100644
@@ -129,15 +129,15 @@ static noinline void key_gc_unused_keys(struct list_head *keys)
 	while (!list_empty(keys)) {
 		struct key *key =
 			list_entry(keys->next, struct key, graveyard_link);
+		short state = key->state;
+
 		list_del(&key->graveyard_link);
 
 		kdebug("- %u", key->serial);
 		key_check(key);
 
 		/* Throw away the key data if the key is instantiated */
-		if (test_bit(KEY_FLAG_INSTANTIATED, &key->flags) &&
-		    !test_bit(KEY_FLAG_NEGATIVE, &key->flags) &&
-		    key->type->destroy)
+		if (state == KEY_IS_POSITIVE && key->type->destroy)
 			key->type->destroy(key);
 
 		security_key_free(key);
@@ -151,7 +151,7 @@ static noinline void key_gc_unused_keys(struct list_head *keys)
 		}
 
 		atomic_dec(&key->user->nkeys);
-		if (test_bit(KEY_FLAG_INSTANTIATED, &key->flags))
+		if (state != KEY_IS_UNINSTANTIATED)
 			atomic_dec(&key->user->nikeys);
 
 		key_user_put(key->user);
security/keys/key.c +30 -11

85 lines not on this page · raw message

security/keys/keyctl.c +4 -5
index a009dc66eb8f..2e741e1a8712 100644
@@ -738,10 +738,9 @@ long keyctl_read_key(key_serial_t keyid, char __user *buffer, size_t buflen)
 
 	key = key_ref_to_ptr(key_ref);
 
-	if (test_bit(KEY_FLAG_NEGATIVE, &key->flags)) {
-		ret = -ENOKEY;
-		goto error2;
-	}
+	ret = key_read_state(key);
+	if (ret < 0)
+		goto error2; /* Negatively instantiated */
 
 	/* see if we can read it directly */
 	ret = key_permission(key_ref, KEY_NEED_READ);
@@ -873,7 +872,7 @@ long keyctl_chown_key(key_serial_t id, uid_t user, gid_t group)
 		atomic_dec(&key->user->nkeys);
 		atomic_inc(&newowner->nkeys);
 
-		if (test_bit(KEY_FLAG_INSTANTIATED, &key->flags)) {
+		if (key->state != KEY_IS_UNINSTANTIATED) {
 			atomic_dec(&key->user->nikeys);
 			atomic_inc(&newowner->nikeys);
 		}
security/keys/keyring.c +5 -5
index 0c8dd4fbe130..ef828238cdc0 100644
@@ -407,7 +407,7 @@ static void keyring_describe(const struct key *keyring, struct seq_file *m)
 	else
 		seq_puts(m, "[anon]");
 
-	if (key_is_instantiated(keyring)) {
+	if (key_is_positive(keyring)) {
 		if (keyring->keys.nr_leaves_on_tree != 0)
 			seq_printf(m, ": %lu", keyring->keys.nr_leaves_on_tree);
 		else
@@ -522,7 +522,8 @@ static int keyring_search_iterator(const void *object, void *iterator_data)
 {
 	struct keyring_search_context *ctx = iterator_data;
 	const struct key *key = keyring_ptr_to_key(object);
-	unsigned long kflags = key->flags;
+	unsigned long kflags = READ_ONCE(key->flags);
+	short state = READ_ONCE(key->state);
 
 	kenter("{%d}", key->serial);
 
@@ -566,9 +567,8 @@ static int keyring_search_iterator(const void *object, void *iterator_data)
 
 	if (ctx->flags & KEYRING_SEARCH_DO_STATE_CHECK) {
 		/* we set a different error code if we pass a negative key */
-		if (kflags & (1 << KEY_FLAG_NEGATIVE)) {
-			smp_rmb();
-			ctx->result = ERR_PTR(key->reject_error);
+		if (state < 0) {
+			ctx->result = ERR_PTR(state);
 			kleave(" = %d [neg]", ctx->skipped_ret);
 			goto skipped;
 		}
security/keys/proc.c +5 -2
index b9f531c9e4fa..036128682463 100644
@@ -182,6 +182,7 @@ static int proc_keys_show(struct seq_file *m, void *v)
 	unsigned long timo;
 	key_ref_t key_ref, skey_ref;
 	char xbuf[16];
+	short state;
 	int rc;
 
 	struct keyring_search_context ctx = {
@@ -240,17 +241,19 @@ static int proc_keys_show(struct seq_file *m, void *v)
 			sprintf(xbuf, "%luw", timo / (60*60*24*7));
 	}
 
+	state = key_read_state(key);
+
 #define showflag(KEY, LETTER, FLAG) \
 	(test_bit(FLAG,	&(KEY)->flags) ? LETTER : '-')
 
 	seq_printf(m, "%08x %c%c%c%c%c%c%c %5d %4s %08x %5d %5d %-9.9s ",
 		   key->serial,
-		   showflag(key, 'I', KEY_FLAG_INSTANTIATED),
+		   state != KEY_IS_UNINSTANTIATED ? 'I' : '-',
 		   showflag(key, 'R', KEY_FLAG_REVOKED),
 		   showflag(key, 'D', KEY_FLAG_DEAD),
 		   showflag(key, 'Q', KEY_FLAG_IN_QUOTA),
 		   showflag(key, 'U', KEY_FLAG_USER_CONSTRUCT),
-		   showflag(key, 'N', KEY_FLAG_NEGATIVE),
+		   state < 0 ? 'N' : '-',
 		   showflag(key, 'i', KEY_FLAG_INVALIDATED),
 		   atomic_read(&key->usage),
 		   xbuf,
security/keys/process_keys.c +1 -1
index 7dd050f24261..ac1d5b2b1626 100644
@@ -727,7 +727,7 @@ try_again:
 
 	ret = -EIO;
 	if (!(lflags & KEY_LOOKUP_PARTIAL) &&
-	    !test_bit(KEY_FLAG_INSTANTIATED, &key->flags))
+	    key_read_state(key) == KEY_IS_UNINSTANTIATED)
 		goto invalid_key;
 
 	/* check the permissions */
security/keys/request_key.c +3 -4
index c7a117c9a8f3..2ce733342b5a 100644
@@ -594,10 +594,9 @@ int wait_for_key_construction(struct key *key, bool intr)
 			  intr ? TASK_INTERRUPTIBLE : TASK_UNINTERRUPTIBLE);
 	if (ret)
 		return -ERESTARTSYS;
-	if (test_bit(KEY_FLAG_NEGATIVE, &key->flags)) {
-		smp_rmb();
-		return key->reject_error;
-	}
+	ret = key_read_state(key);
+	if (ret < 0)
+		return ret;
 	return key_validate(key);
 }
 EXPORT_SYMBOL(wait_for_key_construction);
security/keys/request_key_auth.c +1 -1
index 4f0f112fe276..217775fcd0f3 100644
@@ -73,7 +73,7 @@ static void request_key_auth_describe(const struct key *key,
 
 	seq_puts(m, "key:");
 	seq_puts(m, key->description);
-	if (key_is_instantiated(key))
+	if (key_is_positive(key))
 		seq_printf(m, " pid:%d ci:%zu", rka->pid, rka->callout_len);
 }
 
security/keys/trusted.c +1 -1
index 16dec53184b6..509aedcf8310 100644
@@ -1014,7 +1014,7 @@ static int trusted_update(struct key *key, struct key_preparsed_payload *prep)
 	char *datablob;
 	int ret = 0;
 
-	if (test_bit(KEY_FLAG_NEGATIVE, &key->flags))
+	if (key_is_negative(key))
 		return -ENOKEY;
 	p = key->payload.data[0];
 	if (!p->migratable)
security/keys/user_defined.c +2 -2
index 8705d79b2c6f..eba8a516ee9e 100644
@@ -120,7 +120,7 @@ int user_update(struct key *key, struct key_preparsed_payload *prep)
 
 	if (ret == 0) {
 		/* attach the new data, displacing the old */
-		if (!test_bit(KEY_FLAG_NEGATIVE, &key->flags))
+		if (key_is_positive(key))
 			zap = key->payload.data[0];
 		else
 			zap = NULL;
@@ -174,7 +174,7 @@ EXPORT_SYMBOL_GPL(user_destroy);
 void user_describe(const struct key *key, struct seq_file *m)
 {
 	seq_puts(m, key->description);
-	if (key_is_instantiated(key))
+	if (key_is_positive(key))
 		seq_printf(m, ": %u", key->datalen);
 }
 
sound/core/seq/seq_lock.c +0 -4
index 12ba83367b1b..ba5752ee9af3 100644
@@ -23,8 +23,6 @@
 #include <sound/core.h>
 #include "seq_lock.h"
 
-#if defined(CONFIG_SMP) || defined(CONFIG_SND_DEBUG)
-
 /* wait until all locks are released */
 void snd_use_lock_sync_helper(snd_use_lock_t *lockp, const char *file, int line)
 {
@@ -42,5 +40,3 @@ void snd_use_lock_sync_helper(snd_use_lock_t *lockp, const char *file, int line)
 }
 
 EXPORT_SYMBOL(snd_use_lock_sync_helper);
-
-#endif
sound/core/seq/seq_lock.h +0 -12
index 54044bc2c9ef..ac38031c370e 100644
@@ -3,8 +3,6 @@
 
 #include <linux/sched.h>
 
-#if defined(CONFIG_SMP) || defined(CONFIG_SND_DEBUG)
-
 typedef atomic_t snd_use_lock_t;
 
 /* initialize lock */
@@ -20,14 +18,4 @@ typedef atomic_t snd_use_lock_t;
 void snd_use_lock_sync_helper(snd_use_lock_t *lock, const char *file, int line);
 #define snd_use_lock_sync(lockp) snd_use_lock_sync_helper(lockp, __BASE_FILE__, __LINE__)
 
-#else /* SMP || CONFIG_SND_DEBUG */
-
-typedef spinlock_t snd_use_lock_t;	/* dummy */
-#define snd_use_lock_init(lockp) /**/
-#define snd_use_lock_use(lockp) /**/
-#define snd_use_lock_free(lockp) /**/
-#define snd_use_lock_sync(lockp) /**/
-
-#endif /* SMP || CONFIG_SND_DEBUG */
-
 #endif /* __SND_SEQ_LOCK_H */
sound/pci/hda/hda_codec.c +1 -1
index 83741887faa1..3324f98c35f6 100644
@@ -1755,7 +1755,7 @@ static int get_kctl_0dB_offset(struct hda_codec *codec,
 			return -1;
 		if (*step_to_check && *step_to_check != step) {
 			codec_err(codec, "Mismatching dB step for vmaster slave (%d!=%d)\n",
--				   *step_to_check, step);
+				   *step_to_check, step);
 			return -1;
 		}
 		*step_to_check = step;
sound/usb/quirks.c +1 -0
index 1cc20d138dae..9c5368e7ee23 100644
@@ -1305,6 +1305,7 @@ u64 snd_usb_interface_dsd_format_quirks(struct snd_usb_audio *chip,
 	case USB_ID(0x20b1, 0x2008): /* Matrix Audio X-Sabre */
 	case USB_ID(0x20b1, 0x300a): /* Matrix Audio Mini-i Pro */
 	case USB_ID(0x22d9, 0x0416): /* OPPO HA-1 */
+	case USB_ID(0x2772, 0x0230): /* Pro-Ject Pre Box S2 Digital */
 		if (fp->altsetting == 2)
 			return SNDRV_PCM_FMTBIT_DSD_U32_BE;
 		break;