[PATCH] uwb: fix uwb_dev_unlock() missed at an error path in uwb_rc_cmd_async()
There is the only path in uwb_rc_cmd_async() where rc->uwb_dev is left unlocked. Found by Linux Driver Verification project (linuxtesting.org). Signed-off-by: Alexey Khoroshilov --- drivers/uwb/reset.c |1 + 1 file changed, 1 insertion(+) diff --git a/drivers/uwb/reset.c b/drivers/uwb/reset.c index 7032285..8b47c9c 100644 --- a/drivers/uwb/reset.c +++ b/drivers/uwb/reset.c @@ -97,6 +97,7 @@ int uwb_rc_cmd_async(struct uwb_rc *rc, const char *cmd_name, neh = uwb_rc_neh_add(rc, cmd, expected_type, expected_event, cb, arg); if (IS_ERR(neh)) { result = PTR_ERR(neh); + uwb_dev_unlock(&rc->uwb_dev); goto out; } -- 1.7.9.5 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 2/2] pcmcia: synclink_cs: cleanup checkpatch warnings
ERROR: open brace '{' following struct go on the same line ERROR: space required after that ',' ERROR: space prohibited after that open parenthesis '(' WARNING: please, no spaces at the start of a line WARNING: please, no space before tabs Signed-off-by: Alexey Khoroshilov --- drivers/char/pcmcia/synclink_cs.c | 616 +++-- 1 file changed, 310 insertions(+), 306 deletions(-) diff --git a/drivers/char/pcmcia/synclink_cs.c b/drivers/char/pcmcia/synclink_cs.c index 56e4e94..29f6bec 100644 --- a/drivers/char/pcmcia/synclink_cs.c +++ b/drivers/char/pcmcia/synclink_cs.c @@ -102,8 +102,7 @@ static MGSL_PARAMS default_params = { ASYNC_PARITY_NONE /* unsigned char parity; */ }; -typedef struct -{ +typedef struct { int count; unsigned char status; char data[1]; @@ -326,10 +325,10 @@ typedef struct _mgslpc_info { #define write_reg16(info, reg, val) outw((val), (info)->io_base + (reg)) #define set_reg_bits(info, reg, mask) \ -write_reg(info, (reg), \ + write_reg(info, (reg), \ (unsigned char) (read_reg(info, (reg)) | (mask))) #define clear_reg_bits(info, reg, mask) \ -write_reg(info, (reg), \ + write_reg(info, (reg), \ (unsigned char) (read_reg(info, (reg)) & ~(mask))) /* * interrupt enable/disable routines @@ -356,10 +355,10 @@ static void irq_enable(MGSLPC_INFO *info, unsigned char channel, unsigned short } #define port_irq_disable(info, mask) \ - { info->pim_value |= (mask); write_reg(info, PIM, info->pim_value); } + { info->pim_value |= (mask); write_reg(info, PIM, info->pim_value); } #define port_irq_enable(info, mask) \ - { info->pim_value &= ~(mask); write_reg(info, PIM, info->pim_value); } + { info->pim_value &= ~(mask); write_reg(info, PIM, info->pim_value); } static void rx_start(MGSLPC_INFO *info); static void rx_stop(MGSLPC_INFO *info); @@ -514,56 +513,56 @@ static const struct tty_port_operations mgslpc_port_ops = { static int mgslpc_probe(struct pcmcia_device *link) { -MGSLPC_INFO *info; -int ret; - -if (debug_level >= DEBUG_LEVEL_INFO) - printk("mgslpc_attach\n"); - -info = kzalloc(sizeof(MGSLPC_INFO), GFP_KERNEL); -if (!info) { - printk("Error can't allocate device instance data\n"); - return -ENOMEM; -} - -info->magic = MGSLPC_MAGIC; -tty_port_init(&info->port); -info->port.ops = &mgslpc_port_ops; -INIT_WORK(&info->task, bh_handler); -info->max_frame_size = 4096; -info->port.close_delay = 5*HZ/10; -info->port.closing_wait = 30*HZ; -init_waitqueue_head(&info->status_event_wait_q); -init_waitqueue_head(&info->event_wait_q); -spin_lock_init(&info->lock); -spin_lock_init(&info->netlock); -memcpy(&info->params,&default_params,sizeof(MGSL_PARAMS)); -info->idle_mode = HDLC_TXIDLE_FLAGS; -info->imra_value = 0x; -info->imrb_value = 0x; -info->pim_value = 0xff; - -info->p_dev = link; -link->priv = info; - -/* Initialize the struct pcmcia_device structure */ - -ret = mgslpc_config(link); -if (ret != 0) - goto failed; - -ret = mgslpc_add_device(info); -if (ret != 0) - goto failed_release; - -return 0; + MGSLPC_INFO *info; + int ret; + + if (debug_level >= DEBUG_LEVEL_INFO) + printk("mgslpc_attach\n"); + + info = kzalloc(sizeof(MGSLPC_INFO), GFP_KERNEL); + if (!info) { + printk("Error can't allocate device instance data\n"); + return -ENOMEM; + } + + info->magic = MGSLPC_MAGIC; + tty_port_init(&info->port); + info->port.ops = &mgslpc_port_ops; + INIT_WORK(&info->task, bh_handler); + info->max_frame_size = 4096; + info->port.close_delay = 5*HZ/10; + info->port.closing_wait = 30*HZ; + init_waitqueue_head(&info->status_event_wait_q); + init_waitqueue_head(&info->event_wait_q); + spin_lock_init(&info->lock); + spin_lock_init(&info->netlock); + memcpy(&info->params,&default_params,sizeof(MGSL_PARAMS)); + info->idle_mode = HDLC_TXIDLE_FLAGS; + info->imra_value = 0x; + info->imrb_value = 0x; + info->pim_value = 0xff; + + info->p_dev = link; + link->priv = info; + + /* Initialize the struct pcmcia_device structure */ + + ret = mgslpc_config(link); + if (ret != 0) + goto failed; + + ret = mgslpc_add_device(info); + if (ret != 0) + goto failed_release; + + return 0; failed_release: -mgslpc_release((u_long)link); +
[PATCH] staging: dgrp: implement error handling in dgrp_create_class_sysfs_files()
There is no any error handling in dgrp_create_class_sysfs_files(). The patch adds code to check return values and propagate them to dgrp_init_module(). Found by Linux Driver Verification project (linuxtesting.org). Signed-off-by: Alexey Khoroshilov --- drivers/staging/dgrp/dgrp_common.h |2 +- drivers/staging/dgrp/dgrp_driver.c |6 +- drivers/staging/dgrp/dgrp_sysfs.c | 30 +- 3 files changed, 31 insertions(+), 7 deletions(-) diff --git a/drivers/staging/dgrp/dgrp_common.h b/drivers/staging/dgrp/dgrp_common.h index 0583fe9..2832b8e 100644 --- a/drivers/staging/dgrp/dgrp_common.h +++ b/drivers/staging/dgrp/dgrp_common.h @@ -66,7 +66,7 @@ extern void dgrp_register_dpa_hook(struct proc_dir_entry *de); extern void dgrp_dpa_data(struct nd_struct *, int, u8 *, int); /* from dgrp_sysfs.c */ -extern void dgrp_create_class_sysfs_files(void); +extern int dgrp_create_class_sysfs_files(void); extern void dgrp_remove_class_sysfs_files(void); extern void dgrp_create_node_class_sysfs_files(struct nd_struct *nd); diff --git a/drivers/staging/dgrp/dgrp_driver.c b/drivers/staging/dgrp/dgrp_driver.c index aa26258..e456dc6c 100644 --- a/drivers/staging/dgrp/dgrp_driver.c +++ b/drivers/staging/dgrp/dgrp_driver.c @@ -66,6 +66,8 @@ module_exit(dgrp_cleanup_module); */ static int dgrp_init_module(void) { + int ret; + INIT_LIST_HEAD(&nd_struct_list); spin_lock_init(&dgrp_poll_data.poll_lock); @@ -74,7 +76,9 @@ static int dgrp_init_module(void) dgrp_poll_data.timer.function = dgrp_poll_handler; dgrp_poll_data.timer.data = (unsigned long) &dgrp_poll_data; - dgrp_create_class_sysfs_files(); + ret = dgrp_create_class_sysfs_files(); + if (ret) + return ret; dgrp_register_proc(); diff --git a/drivers/staging/dgrp/dgrp_sysfs.c b/drivers/staging/dgrp/dgrp_sysfs.c index be179ad..7d1b36d 100644 --- a/drivers/staging/dgrp/dgrp_sysfs.c +++ b/drivers/staging/dgrp/dgrp_sysfs.c @@ -85,30 +85,50 @@ static struct attribute_group dgrp_global_settings_attribute_group = { -void dgrp_create_class_sysfs_files(void) +int dgrp_create_class_sysfs_files(void) { int ret = 0; int max_majors = 1U << (32 - MINORBITS); dgrp_class = class_create(THIS_MODULE, "digi_realport"); + if (IS_ERR(dgrp_class)) + return PTR_ERR(dgrp_class); ret = class_create_file(dgrp_class, &class_attr_driver_version); + if (ret) + goto err_class; dgrp_class_global_settings_dev = device_create(dgrp_class, NULL, MKDEV(0, max_majors + 1), NULL, "driver_settings"); - + if (IS_ERR(dgrp_class_global_settings_dev)) { + ret = PTR_ERR(dgrp_class_global_settings_dev); + goto err_file; + } ret = sysfs_create_group(&dgrp_class_global_settings_dev->kobj, &dgrp_global_settings_attribute_group); if (ret) { pr_alert("%s: failed to create sysfs global settings device attributes.\n", __func__); - sysfs_remove_group(&dgrp_class_global_settings_dev->kobj, - &dgrp_global_settings_attribute_group); - return; + goto err_dev1; } dgrp_class_nodes_dev = device_create(dgrp_class, NULL, MKDEV(0, max_majors + 2), NULL, "nodes"); + if (IS_ERR(dgrp_class_nodes_dev)) { + ret = PTR_ERR(dgrp_class_nodes_dev); + goto err_group; + } + return 0; +err_group: + sysfs_remove_group(&dgrp_class_global_settings_dev->kobj, + &dgrp_global_settings_attribute_group); +err_dev1: + device_destroy(dgrp_class, MKDEV(0, max_majors + 1)); +err_file: + class_remove_file(dgrp_class, &class_attr_driver_version); +err_class: + class_destroy(dgrp_class); + return ret; } -- 1.7.9.5 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] stmmac: don't return zero on failure path in stmmac_pci_probe()
If stmmac_dvr_probe() fails in stmmac_pci_probe(), it breaks off initialization, deallocates all resources, but returns zero. The patch adds -ENODEV as return value in this case. Found by Linux Driver Verification project (linuxtesting.org). Signed-off-by: Alexey Khoroshilov --- drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c |1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c index 064eaac..19b3a25 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c @@ -102,6 +102,7 @@ static int stmmac_pci_probe(struct pci_dev *pdev, priv = stmmac_dvr_probe(&(pdev->dev), &plat_dat, addr); if (!priv) { pr_err("%s: main driver probe failed", __func__); + ret = -ENODEV; goto err_out; } priv->dev->irq = pdev->irq; -- 1.7.9.5 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] mwifiex: don't return zero on failure paths in mwifiex_pcie_init()
If pci_iomap() fails in mwifiex_pcie_init(), it breaks off initialization, deallocates all resources, but returns zero. The patch adds -EIO as return value in this case. Found by Linux Driver Verification project (linuxtesting.org). Signed-off-by: Alexey Khoroshilov --- drivers/net/wireless/mwifiex/pcie.c |2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/net/wireless/mwifiex/pcie.c b/drivers/net/wireless/mwifiex/pcie.c index 13fbc4e..9d9349c 100644 --- a/drivers/net/wireless/mwifiex/pcie.c +++ b/drivers/net/wireless/mwifiex/pcie.c @@ -1739,6 +1739,7 @@ static int mwifiex_pcie_init(struct mwifiex_adapter *adapter) card->pci_mmap = pci_iomap(pdev, 0, 0); if (!card->pci_mmap) { dev_err(adapter->dev, "iomap(0) error\n"); + ret = -EIO; goto err_iomap0; } ret = pci_request_region(pdev, 2, DRV_NAME); @@ -1749,6 +1750,7 @@ static int mwifiex_pcie_init(struct mwifiex_adapter *adapter) card->pci_mmap1 = pci_iomap(pdev, 2, 0); if (!card->pci_mmap1) { dev_err(adapter->dev, "iomap(2) error\n"); + ret = -EIO; goto err_iomap2; } -- 1.7.9.5 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v2] tty: mxser: improve error handling in mxser_probe() and mxser_module_init()
1. Currently mxser_probe() and mxser_module_init() ignore errors that can happen in tty_port_register_device(). 2. mxser_module_init() does not deallocate resources allocated in mxser_get_ISA_conf() if mxser_initbrd() failed. The patch adds proper error handling in all the cases. Also it moves free_irq() from mxser_release_ISA_res() to mxser_board_remove(), since it makes mxser_release_ISA_res() a counterpart for mxser_get_ISA_conf(), while free_irq() is relevant to both ISA and PCI boards. Found by Linux Driver Verification project (linuxtesting.org). Signed-off-by: Alexey Khoroshilov --- drivers/tty/mxser.c | 42 +++--- 1 file changed, 35 insertions(+), 7 deletions(-) diff --git a/drivers/tty/mxser.c b/drivers/tty/mxser.c index 4011386..deeb5ad 100644 --- a/drivers/tty/mxser.c +++ b/drivers/tty/mxser.c @@ -2364,7 +2364,6 @@ static void mxser_release_vector(struct mxser_board *brd) static void mxser_release_ISA_res(struct mxser_board *brd) { - free_irq(brd->irq, brd); release_region(brd->ports[0].ioaddr, 8 * brd->info->nports); mxser_release_vector(brd); } @@ -2430,6 +2429,7 @@ static void mxser_board_remove(struct mxser_board *brd) tty_unregister_device(mxvar_sdriver, brd->idx + i); tty_port_destroy(&brd->ports[i].port); } + free_irq(brd->irq, brd); } static int __init mxser_get_ISA_conf(int cap, struct mxser_board *brd) @@ -2554,6 +2554,7 @@ static int mxser_probe(struct pci_dev *pdev, struct mxser_board *brd; unsigned int i, j; unsigned long ioaddress; + struct device *tty_dev; int retval = -EINVAL; for (i = 0; i < MXSER_BOARDS; i++) @@ -2637,13 +2638,25 @@ static int mxser_probe(struct pci_dev *pdev, if (retval) goto err_rel3; - for (i = 0; i < brd->info->nports; i++) - tty_port_register_device(&brd->ports[i].port, mxvar_sdriver, - brd->idx + i, &pdev->dev); + for (i = 0; i < brd->info->nports; i++) { + tty_dev = tty_port_register_device(&brd->ports[i].port, + mxvar_sdriver, brd->idx + i, &pdev->dev); + if (IS_ERR(tty_dev)) { + retval = PTR_ERR(tty_dev); + for (; i > 0; i--) + tty_unregister_device(mxvar_sdriver, + brd->idx + i - 1); + goto err_relbrd; + } + } pci_set_drvdata(pdev, brd); return 0; +err_relbrd: + for (i = 0; i < brd->info->nports; i++) + tty_port_destroy(&brd->ports[i].port); + free_irq(brd->irq, brd); err_rel3: pci_release_region(pdev, 3); err_zero: @@ -2665,7 +2678,6 @@ static void mxser_remove(struct pci_dev *pdev) mxser_board_remove(brd); - free_irq(pdev->irq, brd); pci_release_region(pdev, 2); pci_release_region(pdev, 3); pci_disable_device(pdev); @@ -2683,6 +2695,7 @@ static struct pci_driver mxser_driver = { static int __init mxser_module_init(void) { struct mxser_board *brd; + struct device *tty_dev; unsigned int b, i, m; int retval; @@ -2728,14 +2741,29 @@ static int __init mxser_module_init(void) /* mxser_initbrd will hook ISR. */ if (mxser_initbrd(brd, NULL) < 0) { + mxser_release_ISA_res(brd); brd->info = NULL; continue; } brd->idx = m * MXSER_PORTS_PER_BOARD; - for (i = 0; i < brd->info->nports; i++) - tty_port_register_device(&brd->ports[i].port, + for (i = 0; i < brd->info->nports; i++) { + tty_dev = tty_port_register_device(&brd->ports[i].port, mxvar_sdriver, brd->idx + i, NULL); + if (IS_ERR(tty_dev)) { + for (; i > 0; i--) + tty_unregister_device(mxvar_sdriver, + brd->idx + i - 1); + for (i = 0; i < brd->info->nports; i++) + tty_port_destroy(&brd->ports[i].port); + free_irq(brd->irq, brd); + mxser_release_ISA_res(brd); + brd->info = NULL; + break; + } + } + if (brd->info == NULL) + continue; m++; } -- 1.7.9.5 -- To unsubscribe from this list
[PATCH] [media] stv090x: do not unlock unheld mutex in stv090x_sleep()
goto err and goto err_gateoff before mutex_lock(&state->internal->demod_lock) lead to unlock of unheld mutex in stv090x_sleep(). Found by Linux Driver Verification project (linuxtesting.org). Signed-off-by: Alexey Khoroshilov --- drivers/media/dvb-frontends/stv090x.c | 22 -- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/drivers/media/dvb-frontends/stv090x.c b/drivers/media/dvb-frontends/stv090x.c index 13caec0..4f600ac 100644 --- a/drivers/media/dvb-frontends/stv090x.c +++ b/drivers/media/dvb-frontends/stv090x.c @@ -3906,12 +3906,12 @@ static int stv090x_sleep(struct dvb_frontend *fe) reg = stv090x_read_reg(state, STV090x_TSTTNR1); STV090x_SETFIELD(reg, ADC1_PON_FIELD, 0); if (stv090x_write_reg(state, STV090x_TSTTNR1, reg) < 0) - goto err; + goto err_unlock; /* power off DiSEqC 1 */ reg = stv090x_read_reg(state, STV090x_TSTTNR2); STV090x_SETFIELD(reg, DISEQC1_PON_FIELD, 0); if (stv090x_write_reg(state, STV090x_TSTTNR2, reg) < 0) - goto err; + goto err_unlock; /* check whether path 2 is already sleeping, that is when ADC2 is off */ @@ -3930,7 +3930,7 @@ static int stv090x_sleep(struct dvb_frontend *fe) if (full_standby) STV090x_SETFIELD(reg, STOP_CLKFEC_FIELD, 1); if (stv090x_write_reg(state, STV090x_STOPCLK1, reg) < 0) - goto err; + goto err_unlock; reg = stv090x_read_reg(state, STV090x_STOPCLK2); /* sampling 1 clock */ STV090x_SETFIELD(reg, STOP_CLKSAMP1_FIELD, 1); @@ -3941,7 +3941,7 @@ static int stv090x_sleep(struct dvb_frontend *fe) if (full_standby) STV090x_SETFIELD(reg, STOP_CLKTS_FIELD, 1); if (stv090x_write_reg(state, STV090x_STOPCLK2, reg) < 0) - goto err; + goto err_unlock; break; case STV090x_DEMODULATOR_1: @@ -3949,12 +3949,12 @@ static int stv090x_sleep(struct dvb_frontend *fe) reg = stv090x_read_reg(state, STV090x_TSTTNR3); STV090x_SETFIELD(reg, ADC2_PON_FIELD, 0); if (stv090x_write_reg(state, STV090x_TSTTNR3, reg) < 0) - goto err; + goto err_unlock; /* power off DiSEqC 2 */ reg = stv090x_read_reg(state, STV090x_TSTTNR4); STV090x_SETFIELD(reg, DISEQC2_PON_FIELD, 0); if (stv090x_write_reg(state, STV090x_TSTTNR4, reg) < 0) - goto err; + goto err_unlock; /* check whether path 1 is already sleeping, that is when ADC1 is off */ @@ -3973,7 +3973,7 @@ static int stv090x_sleep(struct dvb_frontend *fe) if (full_standby) STV090x_SETFIELD(reg, STOP_CLKFEC_FIELD, 1); if (stv090x_write_reg(state, STV090x_STOPCLK1, reg) < 0) - goto err; + goto err_unlock; reg = stv090x_read_reg(state, STV090x_STOPCLK2); /* sampling 2 clock */ STV090x_SETFIELD(reg, STOP_CLKSAMP2_FIELD, 1); @@ -3984,7 +3984,7 @@ static int stv090x_sleep(struct dvb_frontend *fe) if (full_standby) STV090x_SETFIELD(reg, STOP_CLKTS_FIELD, 1); if (stv090x_write_reg(state, STV090x_STOPCLK2, reg) < 0) - goto err; + goto err_unlock; break; default: @@ -3997,7 +3997,7 @@ static int stv090x_sleep(struct dvb_frontend *fe) reg = stv090x_read_reg(state, STV090x_SYNTCTRL); STV090x_SETFIELD(reg, STANDBY_FIELD, 0x01); if (stv090x_write_reg(state, STV090x_SYNTCTRL, reg) < 0) - goto err; + goto err_unlock; } mutex_unlock(&state->internal->demod_lock); @@ -4005,8 +4005,10 @@ static int stv090x_sleep(struct dvb_frontend *fe) err_gateoff: stv090x_i2c_gate_ctrl(state, 0); -err: + goto err; +err_unlock: mutex_unlock(&state->internal->demod_lock); +err: dprintk(FE_ERROR, 1, "I/O error"); return -1; } -- 1.7.9.5 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH] [media] stv090x: do not unlock unheld mutex in stv090x_sleep()
On 02/20/2013 10:58 AM, Manu Abraham wrote: > Hi, > > On Wed, Feb 20, 2013 at 12:28 AM, Alexey Khoroshilov > wrote: >> goto err and goto err_gateoff before mutex_lock(&state->internal->demod_lock) >> lead to unlock of unheld mutex in stv090x_sleep(). > Out of curiosity, what happens when you try to unlock an unlocked mutex ? > > Regards, > Manu > Bad things can happen if someone else holds the mutex and it becomes unexpectedly unlocked. Also it can result that the next lock() operation leaves the mutex in unlocked state. The both cases can lead to data races with unpredictable consequences. -- Alexey Khoroshilov -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] [SCSI] scsi_dh_hp_sw: return -ENOMEM if kzalloc() failed
If kzalloc() failed, hp_sw_bus_attach() breaks off initialization, but returns zero. The patch adds -ENOMEM as return value in this case. Found by Linux Driver Verification project (linuxtesting.org). Signed-off-by: Alexey Khoroshilov --- drivers/scsi/device_handler/scsi_dh_hp_sw.c |2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/device_handler/scsi_dh_hp_sw.c b/drivers/scsi/device_handler/scsi_dh_hp_sw.c index 084062b..4619473 100644 --- a/drivers/scsi/device_handler/scsi_dh_hp_sw.c +++ b/drivers/scsi/device_handler/scsi_dh_hp_sw.c @@ -364,7 +364,7 @@ static int hp_sw_bus_attach(struct scsi_device *sdev) if (!scsi_dh_data) { sdev_printk(KERN_ERR, sdev, "%s: Attach Failed\n", HP_SW_NAME); - return 0; + return -ENOMEM; } scsi_dh_data->scsi_dh = &hp_sw_dh; -- 1.7.9.5 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] usb: cdc-acm: fix error handling in acm_probe()
acm_probe() ignores errors in tty_port_register_device() and leaves intfdata pointing to freed memory on alloc_fail7 error path. The patch fixes the both issues. Found by Linux Driver Verification project (linuxtesting.org). Signed-off-by: Alexey Khoroshilov --- drivers/usb/class/cdc-acm.c | 19 +-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c index 8ac25ad..c125b61 100644 --- a/drivers/usb/class/cdc-acm.c +++ b/drivers/usb/class/cdc-acm.c @@ -977,6 +977,8 @@ static int acm_probe(struct usb_interface *intf, int num_rx_buf; int i; int combined_interfaces = 0; + struct device *tty_dev; + int rv = -ENOMEM; /* normal quirks */ quirks = (unsigned long)id->driver_info; @@ -1339,11 +1341,24 @@ skip_countries: usb_set_intfdata(data_interface, acm); usb_get_intf(control_interface); - tty_port_register_device(&acm->port, acm_tty_driver, minor, + tty_dev = tty_port_register_device(&acm->port, acm_tty_driver, minor, &control_interface->dev); + if (IS_ERR(tty_dev)) { + rv = PTR_ERR(tty_dev); + goto alloc_fail8; + } return 0; +alloc_fail8: + if (acm->country_codes) { + device_remove_file(&acm->control->dev, + &dev_attr_wCountryCodes); + device_remove_file(&acm->control->dev, + &dev_attr_iCountryCodeRelDate); + } + device_remove_file(&acm->control->dev, &dev_attr_bmCapabilities); alloc_fail7: + usb_set_intfdata(intf, NULL); for (i = 0; i < ACM_NW; i++) usb_free_urb(acm->wb[i].urb); alloc_fail6: @@ -1359,7 +1374,7 @@ alloc_fail2: acm_release_minor(acm); kfree(acm); alloc_fail: - return -ENOMEM; + return rv; } static void stop_data_traffic(struct acm *acm) -- 1.7.9.5 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v2] [SCSI] mpt2sas: fix double mutex lock in NON_BLOCKING state
If state is NON_BLOCKING and mutex_trylock is succeed, the control flow goes to mutex_lock_interruptible() that is a deadlock. The previous version of the patch becomes obsolete after code movement in commit 913809f6. Found by Linux Driver Verification project (linuxtesting.org). Signed-off-by: Alexey Khoroshilov --- drivers/scsi/mpt2sas/mpt2sas_ctl.c |6 -- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/mpt2sas/mpt2sas_ctl.c b/drivers/scsi/mpt2sas/mpt2sas_ctl.c index 49bdd2d..d29ea56 100644 --- a/drivers/scsi/mpt2sas/mpt2sas_ctl.c +++ b/drivers/scsi/mpt2sas/mpt2sas_ctl.c @@ -2181,8 +2181,10 @@ _ctl_ioctl_main(struct file *file, unsigned int cmd, void __user *arg, return -EAGAIN; state = (file->f_flags & O_NONBLOCK) ? NON_BLOCKING : BLOCKING; - if (state == NON_BLOCKING && !mutex_trylock(&ioc->ctl_cmds.mutex)) - return -EAGAIN; + if (state == NON_BLOCKING) { + if (!mutex_trylock(&ioc->ctl_cmds.mutex)) + return -EAGAIN; + } else if (mutex_lock_interruptible(&ioc->ctl_cmds.mutex)) return -ERESTARTSYS; -- 1.7.9.5 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] virtio: console: fix error handling in init() function
If register_virtio_driver() fails, virtio-ports class is not destroyed. The patch adds error handling of register_virtio_driver(). Found by Linux Driver Verification project (linuxtesting.org). Signed-off-by: Alexey Khoroshilov --- drivers/char/virtio_console.c | 12 +++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/drivers/char/virtio_console.c b/drivers/char/virtio_console.c index cdf2f54..060a672 100644 --- a/drivers/char/virtio_console.c +++ b/drivers/char/virtio_console.c @@ -1941,7 +1941,17 @@ static int __init init(void) INIT_LIST_HEAD(&pdrvdata.consoles); INIT_LIST_HEAD(&pdrvdata.portdevs); - return register_virtio_driver(&virtio_console); + err = register_virtio_driver(&virtio_console); + if (err < 0) { + pr_err("Error %d registering virtio driver\n", err); + goto free; + } + return 0; +free: + if (pdrvdata.debugfs_dir) + debugfs_remove_recursive(pdrvdata.debugfs_dir); + class_destroy(pdrvdata.class); + return err; } static void __exit fini(void) -- 1.7.9.5 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] ppdev: ppdev_init: do not return zero in case of failure
Error handling of parport_register_driver() in ppdev_init() is broken because it deallocates all resources but still returns zero. Currently parport_register_driver() always succeeds. Nevertheless it is worth to fix the issue. Found by Linux Driver Verification project (linuxtesting.org). Signed-off-by: Alexey Khoroshilov --- drivers/char/ppdev.c |3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/char/ppdev.c b/drivers/char/ppdev.c index 3fcf80f..d0d824e 100644 --- a/drivers/char/ppdev.c +++ b/drivers/char/ppdev.c @@ -783,7 +783,8 @@ static int __init ppdev_init (void) err = PTR_ERR(ppdev_class); goto out_chrdev; } - if (parport_register_driver(&pp_driver)) { + err = parport_register_driver(&pp_driver); + if (err < 0) { printk (KERN_WARNING CHRDEV ": unable to register with parport\n"); goto out_class; } -- 1.7.9.5 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] staging: bcm: fix error handling in bcm_init()
bcm_init() does not have proper error handling of usb_register(). The patch implements one. Found by Linux Driver Verification project (linuxtesting.org). Signed-off-by: Alexey Khoroshilov --- drivers/staging/bcm/InterfaceInit.c | 12 +++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/drivers/staging/bcm/InterfaceInit.c b/drivers/staging/bcm/InterfaceInit.c index 8f85de6..0049890 100644 --- a/drivers/staging/bcm/InterfaceInit.c +++ b/drivers/staging/bcm/InterfaceInit.c @@ -669,6 +669,8 @@ struct class *bcm_class; static __init int bcm_init(void) { + int retval; + printk(KERN_INFO "%s: %s, %s\n", DRV_NAME, DRV_DESCRIPTION, DRV_VERSION); printk(KERN_INFO "%s\n", DRV_COPYRIGHT); @@ -678,7 +680,15 @@ static __init int bcm_init(void) return PTR_ERR(bcm_class); } - return usb_register(&usbbcm_driver); + retval = usb_register(&usbbcm_driver); + if (retval < 0) { + printk(KERN_ERR DRV_NAME ": could not register usb driver\n"); + goto out_class; + } + return 0; +out_class: + class_destroy(bcm_class); + return retval; } static __exit void bcm_exit(void) -- 1.7.9.5 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v2] staging: bcm: fix error handling in bcm_init()
bcm_init() does not have proper error handling of usb_register(). The patch implements one. Found by Linux Driver Verification project (linuxtesting.org). Signed-off-by: Alexey Khoroshilov --- drivers/staging/bcm/InterfaceInit.c | 10 +- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/drivers/staging/bcm/InterfaceInit.c b/drivers/staging/bcm/InterfaceInit.c index 8f85de6..57452ef 100644 --- a/drivers/staging/bcm/InterfaceInit.c +++ b/drivers/staging/bcm/InterfaceInit.c @@ -669,6 +669,8 @@ struct class *bcm_class; static __init int bcm_init(void) { + int retval; + printk(KERN_INFO "%s: %s, %s\n", DRV_NAME, DRV_DESCRIPTION, DRV_VERSION); printk(KERN_INFO "%s\n", DRV_COPYRIGHT); @@ -678,7 +680,13 @@ static __init int bcm_init(void) return PTR_ERR(bcm_class); } - return usb_register(&usbbcm_driver); + retval = usb_register(&usbbcm_driver); + if (retval < 0) { + printk(KERN_ERR DRV_NAME ": could not register usb driver\n"); + class_destroy(bcm_class); + return retval; + } + return 0; } static __exit void bcm_exit(void) -- 1.7.9.5 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] staging: bcm: use pr_info and pr_err rather than printk
Convert printk(KERN_INFO to pr_info( and printk(KERN_ERR to pr_err(. Signed-off-by: Alexey Khoroshilov --- drivers/staging/bcm/InterfaceInit.c |8 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/staging/bcm/InterfaceInit.c b/drivers/staging/bcm/InterfaceInit.c index 57452ef..dfee0ce 100644 --- a/drivers/staging/bcm/InterfaceInit.c +++ b/drivers/staging/bcm/InterfaceInit.c @@ -671,18 +671,18 @@ static __init int bcm_init(void) { int retval; - printk(KERN_INFO "%s: %s, %s\n", DRV_NAME, DRV_DESCRIPTION, DRV_VERSION); - printk(KERN_INFO "%s\n", DRV_COPYRIGHT); + pr_info("%s: %s, %s\n", DRV_NAME, DRV_DESCRIPTION, DRV_VERSION); + pr_info("%s\n", DRV_COPYRIGHT); bcm_class = class_create(THIS_MODULE, DRV_NAME); if (IS_ERR(bcm_class)) { - printk(KERN_ERR DRV_NAME ": could not create class\n"); + pr_err(DRV_NAME ": could not create class\n"); return PTR_ERR(bcm_class); } retval = usb_register(&usbbcm_driver); if (retval < 0) { - printk(KERN_ERR DRV_NAME ": could not register usb driver\n"); + pr_err(DRV_NAME ": could not register usb driver\n"); class_destroy(bcm_class); return retval; } -- 1.7.9.5 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] USB: omninet: fix potential tty NULL dereference
Add check for return value of tty_port_tty_get, since it can return NULL after port hangup that may happen anytime. Found by Linux Driver Verification project (linuxtesting.org). Signed-off-by: Alexey Khoroshilov --- drivers/usb/serial/omninet.c |8 +--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/usb/serial/omninet.c b/drivers/usb/serial/omninet.c index 6f3d705..493c892 100644 --- a/drivers/usb/serial/omninet.c +++ b/drivers/usb/serial/omninet.c @@ -185,10 +185,12 @@ static void omninet_read_bulk_callback(struct urb *urb) if (urb->actual_length && header->oh_len) { struct tty_struct *tty = tty_port_tty_get(&port->port); - tty_insert_flip_string(tty, data + OMNINET_DATAOFFSET, + if (tty) { + tty_insert_flip_string(tty, data + OMNINET_DATAOFFSET, header->oh_len); - tty_flip_buffer_push(tty); - tty_kref_put(tty); + tty_flip_buffer_push(tty); + tty_kref_put(tty); + } } /* Continue trying to always read */ -- 1.7.9.5 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] pcmcia: synclink_cs: fix potential tty NULL dereference
tty_port_tty_get() can return NULL after port hangup that may happen anytime. The patch adds checks that tty_port_tty_get() returns nonNULL around places where tty is actually used. Found by Linux Driver Verification project (linuxtesting.org). Signed-off-by: Alexey Khoroshilov --- drivers/char/pcmcia/synclink_cs.c | 15 --- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/drivers/char/pcmcia/synclink_cs.c b/drivers/char/pcmcia/synclink_cs.c index 0a484b4..13c9747 100644 --- a/drivers/char/pcmcia/synclink_cs.c +++ b/drivers/char/pcmcia/synclink_cs.c @@ -891,6 +891,9 @@ static void rx_ready_async(MGSLPC_INFO *info, int tcd, struct tty_struct *tty) int work = 0; struct mgsl_icount *icount = &info->icount; + if (!tty) + return; + if (tcd) { /* early termination, get FIFO count from RBCL register */ fifo_count = (unsigned char)(read_reg(info, CHA+RBCL) & 0x1f); @@ -980,7 +983,7 @@ static void tx_done(MGSLPC_INFO *info, struct tty_struct *tty) else #endif { - if (tty->stopped || tty->hw_stopped) { + if (tty && (tty->stopped || tty->hw_stopped)) { tx_stop(info); return; } @@ -1000,7 +1003,7 @@ static void tx_ready(MGSLPC_INFO *info, struct tty_struct *tty) if (!info->tx_active) return; } else { - if (tty->stopped || tty->hw_stopped) { + if (tty && (tty->stopped || tty->hw_stopped)) { tx_stop(info); return; } @@ -1050,13 +1053,12 @@ static void cts_change(MGSLPC_INFO *info, struct tty_struct *tty) wake_up_interruptible(&info->status_event_wait_q); wake_up_interruptible(&info->event_wait_q); - if (info->port.flags & ASYNC_CTS_FLOW) { + if (tty && (info->port.flags & ASYNC_CTS_FLOW)) { if (tty->hw_stopped) { if (info->serial_signals & SerialSignal_CTS) { if (debug_level >= DEBUG_LEVEL_ISR) printk("CTS tx start..."); - if (tty) - tty->hw_stopped = 0; + tty->hw_stopped = 0; tx_start(info, tty); info->pending_bh |= BH_TRANSMIT; return; @@ -1065,8 +1067,7 @@ static void cts_change(MGSLPC_INFO *info, struct tty_struct *tty) if (!(info->serial_signals & SerialSignal_CTS)) { if (debug_level >= DEBUG_LEVEL_ISR) printk("CTS tx stop..."); - if (tty) - tty->hw_stopped = 1; + tty->hw_stopped = 1; tx_stop(info); } } -- 1.7.9.5 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v2] pcmcia: synclink_cs: fix potential tty NULL dereference
tty_port_tty_get() can return NULL after port hangup that may happen anytime. The patch adds checks that tty_port_tty_get() returns nonNULL around places where tty is actually used. I have no actual hardware to test the patch, so I have updated rx side processing from common sense only. v2: rx handling updated according Alan Cox feedback. Found by Linux Driver Verification project (linuxtesting.org). Signed-off-by: Alexey Khoroshilov --- drivers/char/pcmcia/synclink_cs.c | 20 +--- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/drivers/char/pcmcia/synclink_cs.c b/drivers/char/pcmcia/synclink_cs.c index 0a484b4..a6b8dde 100644 --- a/drivers/char/pcmcia/synclink_cs.c +++ b/drivers/char/pcmcia/synclink_cs.c @@ -891,6 +891,14 @@ static void rx_ready_async(MGSLPC_INFO *info, int tcd, struct tty_struct *tty) int work = 0; struct mgsl_icount *icount = &info->icount; + if (!tty) { + /* tty is not available anymore */ + issue_command(info, CHA, CMD_RXRESET); + if (debug_level >= DEBUG_LEVEL_ISR) + printk("%s(%d):rx_ready_async(tty=NULL)\n",__FILE__,__LINE__); + return; + } + if (tcd) { /* early termination, get FIFO count from RBCL register */ fifo_count = (unsigned char)(read_reg(info, CHA+RBCL) & 0x1f); @@ -980,7 +988,7 @@ static void tx_done(MGSLPC_INFO *info, struct tty_struct *tty) else #endif { - if (tty->stopped || tty->hw_stopped) { + if (tty && (tty->stopped || tty->hw_stopped)) { tx_stop(info); return; } @@ -1000,7 +1008,7 @@ static void tx_ready(MGSLPC_INFO *info, struct tty_struct *tty) if (!info->tx_active) return; } else { - if (tty->stopped || tty->hw_stopped) { + if (tty && (tty->stopped || tty->hw_stopped)) { tx_stop(info); return; } @@ -1050,13 +1058,12 @@ static void cts_change(MGSLPC_INFO *info, struct tty_struct *tty) wake_up_interruptible(&info->status_event_wait_q); wake_up_interruptible(&info->event_wait_q); - if (info->port.flags & ASYNC_CTS_FLOW) { + if (tty && (info->port.flags & ASYNC_CTS_FLOW)) { if (tty->hw_stopped) { if (info->serial_signals & SerialSignal_CTS) { if (debug_level >= DEBUG_LEVEL_ISR) printk("CTS tx start..."); - if (tty) - tty->hw_stopped = 0; + tty->hw_stopped = 0; tx_start(info, tty); info->pending_bh |= BH_TRANSMIT; return; @@ -1065,8 +1072,7 @@ static void cts_change(MGSLPC_INFO *info, struct tty_struct *tty) if (!(info->serial_signals & SerialSignal_CTS)) { if (debug_level >= DEBUG_LEVEL_ISR) printk("CTS tx stop..."); - if (tty) - tty->hw_stopped = 1; + tty->hw_stopped = 1; tx_stop(info); } } -- 1.7.9.5 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] extcon: arizona: unlock mutex on error path in arizona_micdet()
If regmap_read() failed, arizona_micdet() returns IRQ_NONE leaving &info->lock mutex locked as opposed to all other return paths. Found by Linux Driver Verification project (linuxtesting.org). Signed-off-by: Alexey Khoroshilov --- drivers/extcon/extcon-arizona.c |1 + 1 file changed, 1 insertion(+) diff --git a/drivers/extcon/extcon-arizona.c b/drivers/extcon/extcon-arizona.c index cdab9e5..d876a54 100644 --- a/drivers/extcon/extcon-arizona.c +++ b/drivers/extcon/extcon-arizona.c @@ -166,6 +166,7 @@ static irqreturn_t arizona_micdet(int irq, void *data) ret = regmap_read(arizona->regmap, ARIZONA_MIC_DETECT_3, &val); if (ret != 0) { dev_err(arizona->dev, "Failed to read MICDET: %d\n", ret); + mutex_unlock(&info->lock); return IRQ_NONE; } -- 1.7.9.5 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] jffs2: Make handling of erase_completion_lock consistent in jffs2_do_reserve_space()
Users of jffs2_do_reserve_space() expect they still held erase_completion_lock after call to it. But there is a path where jffs2_do_reserve_space() leaves erase_completion_lock unlocked. The patch fixes it. Found by Linux Driver Verification project (linuxtesting.org). Signed-off-by: Alexey Khoroshilov --- fs/jffs2/nodemgmt.c |6 -- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/fs/jffs2/nodemgmt.c b/fs/jffs2/nodemgmt.c index 0c96eb5..0331072 100644 --- a/fs/jffs2/nodemgmt.c +++ b/fs/jffs2/nodemgmt.c @@ -417,14 +417,16 @@ static int jffs2_do_reserve_space(struct jffs2_sb_info *c, uint32_t minsize, spin_unlock(&c->erase_completion_lock); ret = jffs2_prealloc_raw_node_refs(c, jeb, 1); - if (ret) - return ret; + /* Just lock it again and continue. Nothing much can change because we hold c->alloc_sem anyway. In fact, it's not entirely clear why we hold c->erase_completion_lock in the majority of this function... but that's a question for another (more caffeine-rich) day. */ spin_lock(&c->erase_completion_lock); + if (ret) + return ret; + waste = jeb->free_size; jffs2_link_node_ref(c, jeb, (jeb->offset + c->sector_size - waste) | REF_OBSOLETE, -- 1.7.9.5 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] staging/gdm72xx: coding style fixes gdm_qos.c
Fix checkpatch.pl warnings: WARNING: Prefer pr_debug(... to printk(KERN_DEBUG, ... WARNING: Prefer pr_warn(... to printk(KERN_WARNING, ... WARNING: Prefer pr_err(... to printk(KERN_ERR, ... Signed-off-by: Alexey Khoroshilov --- drivers/staging/gdm72xx/gdm_qos.c |6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/gdm72xx/gdm_qos.c b/drivers/staging/gdm72xx/gdm_qos.c index 80bde05..ed60138 100644 --- a/drivers/staging/gdm72xx/gdm_qos.c +++ b/drivers/staging/gdm72xx/gdm_qos.c @@ -25,12 +25,12 @@ #define B2H(x) __be16_to_cpu(x) #undef dprintk -#define dprintk(fmt, args ...) printk(KERN_DEBUG "[QoS] " fmt, ## args) +#define dprintk(fmt, args ...) pr_debug("[QoS] " fmt, ## args) #undef wprintk #define wprintk(fmt, args ...) \ - printk(KERN_WARNING "[QoS WARNING] " fmt, ## args) + pr_warn("[QoS WARNING] " fmt, ## args) #undef eprintk -#define eprintk(fmt, args ...) printk(KERN_ERR "[QoS ERROR] " fmt, ## args) +#define eprintk(fmt, args ...) pr_err("[QoS ERROR] " fmt, ## args) #define MAX_FREE_LIST_CNT 32 -- 1.7.9.5 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] staging: sbe-2t3e3: fix error handling in t3e3_init_channel()
t3e3_init_channel() incorrectly handles errors in several places: it returns zero and does not deallocate all required resources. The patch fixes that places. Found by Linux Driver Verification project (linuxtesting.org). Signed-off-by: Alexey Khoroshilov --- drivers/staging/sbe-2t3e3/module.c | 15 +++ 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/drivers/staging/sbe-2t3e3/module.c b/drivers/staging/sbe-2t3e3/module.c index cd778b3..8adb178 100644 --- a/drivers/staging/sbe-2t3e3/module.c +++ b/drivers/staging/sbe-2t3e3/module.c @@ -67,6 +67,7 @@ static int __devinit t3e3_init_channel(struct channel *channel, struct pci_dev * dev = alloc_hdlcdev(channel); if (!dev) { printk(KERN_ERR "SBE 2T3E3" ": Out of memory\n"); + err = -ENOMEM; goto free_regions; } @@ -82,8 +83,9 @@ static int __devinit t3e3_init_channel(struct channel *channel, struct pci_dev * else channel->h.slot = 0; - if (setup_device(dev, channel)) - goto free_regions; + err = setup_device(dev, channel); + if (err) + goto free_dev; pci_read_config_dword(channel->pdev, 0x40, &val); /* mask sleep mode */ pci_write_config_dword(channel->pdev, 0x40, val & 0x3FFF); @@ -92,14 +94,19 @@ static int __devinit t3e3_init_channel(struct channel *channel, struct pci_dev * pci_read_config_dword(channel->pdev, PCI_COMMAND, &channel->h.command); t3e3_init(channel); - if (request_irq(dev->irq, &t3e3_intr, IRQF_SHARED, dev->name, dev)) { + err = request_irq(dev->irq, &t3e3_intr, IRQF_SHARED, dev->name, dev); + if (err) { printk(KERN_WARNING "%s: could not get irq: %d\n", dev->name, dev->irq); - goto free_regions; + goto unregister_dev; } pci_set_drvdata(pdev, channel); return 0; +unregister_dev: + unregister_hdlc_device(dev); +free_dev: + free_netdev(dev); free_regions: pci_release_regions(pdev); disable: -- 1.7.9.5 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] [media] dvb-usb: fix error handling in ttusb_dec_probe()
There is an asymmetry in ttusb_dec_init_usb()-ttusb_init_rc() and ttusb_dec_exit_usb()-ttusb_dec_exit_rc() in terms of resources allocated-deallocated. irq_urb and irq_buffer are allocated in ttusb_dec_init_usb(), while they are deallocated in ttusb_dec_exit_rc(). As a result there is a leak of them in ttusb_dec_probe(). The patch fixes the asymmetry and a leak on a failure path in ttusb_dec_init_usb(). By the way, it - removes usage of -1 as a custom error code, - replaces GFP_ATOMIC by GFP_KERNEL in usb_alloc_coherent() in ttusb_dec_init_usb() as soon as all other memory allocation done with GFP_KERNEL; - refactors ttusb_dec_boot_dsp() in an equivalent way except for returning 0 instead of 1 if ttusb_dec_boot_dsp() succeed in (!mode) branch. Found by Linux Driver Verification project (linuxtesting.org). Signed-off-by: Alexey Khoroshilov --- drivers/media/usb/ttusb-dec/ttusb_dec.c | 152 +--- 1 file changed, 82 insertions(+), 70 deletions(-) diff --git a/drivers/media/usb/ttusb-dec/ttusb_dec.c b/drivers/media/usb/ttusb-dec/ttusb_dec.c index e52c3b9..29724af 100644 --- a/drivers/media/usb/ttusb-dec/ttusb_dec.c +++ b/drivers/media/usb/ttusb-dec/ttusb_dec.c @@ -366,7 +366,7 @@ static int ttusb_dec_get_stb_state (struct ttusb_dec *dec, unsigned int *mode, } return 0; } else { - return -1; + return -ENOENT; } } @@ -1241,6 +1241,8 @@ static void ttusb_dec_init_v_pes(struct ttusb_dec *dec) static int ttusb_dec_init_usb(struct ttusb_dec *dec) { + int result; + dprintk("%s\n", __func__); mutex_init(&dec->usb_mutex); @@ -1258,7 +1260,7 @@ static int ttusb_dec_init_usb(struct ttusb_dec *dec) return -ENOMEM; } dec->irq_buffer = usb_alloc_coherent(dec->udev,IRQ_PACKET_SIZE, - GFP_ATOMIC, &dec->irq_dma_handle); + GFP_KERNEL, &dec->irq_dma_handle); if(!dec->irq_buffer) { usb_free_urb(dec->irq_urb); return -ENOMEM; @@ -1270,7 +1272,13 @@ static int ttusb_dec_init_usb(struct ttusb_dec *dec) dec->irq_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; } - return ttusb_dec_alloc_iso_urbs(dec); + result = ttusb_dec_alloc_iso_urbs(dec); + if (result) { + usb_free_urb(dec->irq_urb); + usb_free_coherent(dec->udev, IRQ_PACKET_SIZE, + dec->irq_buffer, dec->irq_dma_handle); + } + return result; } static int ttusb_dec_boot_dsp(struct ttusb_dec *dec) @@ -1293,10 +1301,11 @@ static int ttusb_dec_boot_dsp(struct ttusb_dec *dec) dprintk("%s\n", __func__); - if (request_firmware(&fw_entry, dec->firmware_name, &dec->udev->dev)) { + result = request_firmware(&fw_entry, dec->firmware_name, &dec->udev->dev); + if (result) { printk(KERN_ERR "%s: Firmware (%s) unavailable.\n", __func__, dec->firmware_name); - return 1; + return result; } firmware = fw_entry->data; @@ -1306,7 +1315,7 @@ static int ttusb_dec_boot_dsp(struct ttusb_dec *dec) printk("%s: firmware size too small for DSP code (%zu < 60).\n", __func__, firmware_size); release_firmware(fw_entry); - return -1; + return -ENOENT; } /* a 32 bit checksum over the first 56 bytes of the DSP Code is stored @@ -1320,7 +1329,7 @@ static int ttusb_dec_boot_dsp(struct ttusb_dec *dec) "0x%08x != 0x%08x in file), file invalid.\n", __func__, crc32_csum, crc32_check); release_firmware(fw_entry); - return -1; + return -ENOENT; } memcpy(idstring, &firmware[36], 20); idstring[20] = '\0'; @@ -1389,55 +1398,48 @@ static int ttusb_dec_init_stb(struct ttusb_dec *dec) dprintk("%s\n", __func__); result = ttusb_dec_get_stb_state(dec, &mode, &model, &version); + if (result) + return result; - if (!result) { - if (!mode) { - if (version == 0xABCDEFAB) - printk(KERN_INFO "ttusb_dec: no version " - "info in Firmware\n"); - else - printk(KERN_INFO "ttusb_dec: Firmware " - "%x.%02x%c%c\n", - version >> 24, (version >>
[PATCH] p54usb: fix leak at failure path in p54u_load_firmware()
If request_firmware_nowait() fails in p54u_load_firmware(), p54u_load_firmware_cb is not called and no one decrements usb_dev refcnt. Found by Linux Driver Verification project (linuxtesting.org). Signed-off-by: Alexey Khoroshilov --- drivers/net/wireless/p54/p54usb.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/wireless/p54/p54usb.c b/drivers/net/wireless/p54/p54usb.c index b9deef6..7fa81d1 100644 --- a/drivers/net/wireless/p54/p54usb.c +++ b/drivers/net/wireless/p54/p54usb.c @@ -979,6 +979,7 @@ static int p54u_load_firmware(struct ieee80211_hw *dev, if (err) { dev_err(&priv->udev->dev, "(p54usb) cannot load firmware %s " "(%d)!\n", p54u_fwlist[i].fw, err); + usb_put_dev(udev); } return err; -- 1.8.1.2 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] can: pcan_usb_core: fix memory leak on failure paths in peak_usb_start()
Tx and rx urbs are not deallocated if something goes wrong in peak_usb_start(). The patch fixes error handling to deallocate all the resources. Found by Linux Driver Verification project (linuxtesting.org). Signed-off-by: Alexey Khoroshilov --- drivers/net/can/usb/peak_usb/pcan_usb_core.c | 15 +++ 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/drivers/net/can/usb/peak_usb/pcan_usb_core.c b/drivers/net/can/usb/peak_usb/pcan_usb_core.c index a0f647f..0b7a4c3 100644 --- a/drivers/net/can/usb/peak_usb/pcan_usb_core.c +++ b/drivers/net/can/usb/peak_usb/pcan_usb_core.c @@ -463,7 +463,7 @@ static int peak_usb_start(struct peak_usb_device *dev) if (i < PCAN_USB_MAX_TX_URBS) { if (i == 0) { netdev_err(netdev, "couldn't setup any tx URB\n"); - return err; + goto err_tx; } netdev_warn(netdev, "tx performance may be slow\n"); @@ -472,7 +472,7 @@ static int peak_usb_start(struct peak_usb_device *dev) if (dev->adapter->dev_start) { err = dev->adapter->dev_start(dev); if (err) - goto failed; + goto err_adapter; } dev->state |= PCAN_USB_STATE_STARTED; @@ -481,19 +481,26 @@ static int peak_usb_start(struct peak_usb_device *dev) if (dev->adapter->dev_set_bus) { err = dev->adapter->dev_set_bus(dev, 1); if (err) - goto failed; + goto err_adapter; } dev->can.state = CAN_STATE_ERROR_ACTIVE; return 0; -failed: +err_adapter: if (err == -ENODEV) netif_device_detach(dev->netdev); netdev_warn(netdev, "couldn't submit control: %d\n", err); + for (i = 0; i < PCAN_USB_MAX_TX_URBS; i++) { + usb_free_urb(dev->tx_contexts[i].urb); + dev->tx_contexts[i].urb = NULL; + } +err_tx: + usb_kill_anchored_urbs(&dev->rx_submitted); + return err; } -- 1.8.1.2 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] net/irda/mcs7780: fix memory leaks in mcs_net_open()
If rx_urb allocation fails in mcs_setup_urbs(), tx_urb leaks. If mcs_receive_start() fails in mcs_net_open(), the both urbs are not deallocated. The patch fixes the issues and by the way fixes label indentation. Found by Linux Driver Verification project (linuxtesting.org). Signed-off-by: Alexey Khoroshilov --- drivers/net/irda/mcs7780.c | 40 +++- 1 file changed, 23 insertions(+), 17 deletions(-) diff --git a/drivers/net/irda/mcs7780.c b/drivers/net/irda/mcs7780.c index f07c340..3f138ca 100644 --- a/drivers/net/irda/mcs7780.c +++ b/drivers/net/irda/mcs7780.c @@ -191,8 +191,8 @@ static inline int mcs_setup_transceiver_vishay(struct mcs_cb *mcs) goto error; ret = 0; - error: - return ret; +error: + return ret; } /* Setup a communication between mcs7780 and agilent chip. */ @@ -501,8 +501,11 @@ static inline int mcs_setup_urbs(struct mcs_cb *mcs) return 0; mcs->rx_urb = usb_alloc_urb(0, GFP_KERNEL); - if (!mcs->rx_urb) + if (!mcs->rx_urb) { + usb_free_urb(mcs->tx_urb); + mcs->tx_urb = NULL; return 0; + } return 1; } @@ -643,9 +646,9 @@ static int mcs_speed_change(struct mcs_cb *mcs) ret = mcs_set_reg(mcs, MCS_MODE_REG, rval); mcs->speed = mcs->new_speed; - error: - mcs->new_speed = 0; - return ret; +error: + mcs->new_speed = 0; + return ret; } /* Ioctl calls not supported at this time. Can be an area of future work. */ @@ -738,17 +741,20 @@ static int mcs_net_open(struct net_device *netdev) ret = mcs_receive_start(mcs); if (ret) - goto error3; + goto error4; netif_start_queue(netdev); return 0; - error3: - irlap_close(mcs->irlap); - error2: - kfree_skb(mcs->rx_buff.skb); - error1: - return ret; +error4: + usb_free_urb(mcs->rx_urb); + usb_free_urb(mcs->tx_urb); +error3: + irlap_close(mcs->irlap); +error2: + kfree_skb(mcs->rx_buff.skb); +error1: + return ret; } /* Receive callback function. */ @@ -946,11 +952,11 @@ static int mcs_probe(struct usb_interface *intf, usb_set_intfdata(intf, mcs); return 0; - error2: - free_netdev(ndev); +error2: + free_netdev(ndev); - error1: - return ret; +error1: + return ret; } /* The current device is removed, the USB layer tells us to shut down. */ -- 1.8.1.2 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v2] [media] dvb_demux: fix deadlock in dmx_section_feed_release_filter()
dmx_section_feed_release_filter() locks dvbdmx->mutex and if the feed is still filtering, it calls feed->stop_filtering(feed). stop_filtering() is implemented by dmx_section_feed_stop_filtering() that first of all try to lock the same mutex: dvbdmx->mutex. That leads to a deadlock. It does not happen often in practice because all callers of release_filter() stop filtering by themselves. So the problem can happen in case of race condition only. The patch releases dvbdmx->mutex before call to feed->stop_filtering(feed) and reacquires the mutex after that. Found by Linux Driver Verification project (linuxtesting.org). Signed-off-by: Alexey Khoroshilov --- drivers/media/dvb-core/dvb_demux.c | 7 ++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/media/dvb-core/dvb_demux.c b/drivers/media/dvb-core/dvb_demux.c index 3485655..6de3bd0 100644 --- a/drivers/media/dvb-core/dvb_demux.c +++ b/drivers/media/dvb-core/dvb_demux.c @@ -1027,8 +1027,13 @@ static int dmx_section_feed_release_filter(struct dmx_section_feed *feed, return -EINVAL; } - if (feed->is_filtering) + if (feed->is_filtering) { + /* release dvbdmx->mutex as far as + it is acquired by stop_filtering() itself */ + mutex_unlock(&dvbdmx->mutex); feed->stop_filtering(feed); + mutex_lock(&dvbdmx->mutex); + } spin_lock_irq(&dvbdmx->lock); f = dvbdmxfeed->filter; -- 1.8.1.2 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] [media] cx231xx: fix double free and leaks on failure path in cx231xx_usb_probe()
There are numerous issues in error handling code of cx231xx initialization. Double free (when cx231xx_init_dev() calls kfree(dev) via cx231xx_release_resources() and then cx231xx_usb_probe() does the same) and memory leaks (e.g. usb_get_dev() before (ifnum != 1) check in cx231xx_usb_probe()) are just a few of them. The patch fixes the issues in cx231xx_usb_probe() and cx231xx_init_dev() by moving usb_get_dev(interface_to_usbdev(interface)) below in code and implementing proper error handling. Found by Linux Driver Verification project (linuxtesting.org). Signed-off-by: Alexey Khoroshilov --- drivers/media/usb/cx231xx/cx231xx-cards.c | 110 -- 1 file changed, 57 insertions(+), 53 deletions(-) diff --git a/drivers/media/usb/cx231xx/cx231xx-cards.c b/drivers/media/usb/cx231xx/cx231xx-cards.c index a384f80..e9d017b 100644 --- a/drivers/media/usb/cx231xx/cx231xx-cards.c +++ b/drivers/media/usb/cx231xx/cx231xx-cards.c @@ -978,7 +978,6 @@ static int cx231xx_init_dev(struct cx231xx *dev, struct usb_device *udev, int minor) { int retval = -ENOMEM; - int errCode; unsigned int maxh, maxw; dev->udev = udev; @@ -1014,8 +1013,8 @@ static int cx231xx_init_dev(struct cx231xx *dev, struct usb_device *udev, /* Cx231xx pre card setup */ cx231xx_pre_card_setup(dev); - errCode = cx231xx_config(dev); - if (errCode) { + retval = cx231xx_config(dev); + if (retval) { cx231xx_errdev("error configuring device\n"); return -ENOMEM; } @@ -1024,12 +1023,11 @@ static int cx231xx_init_dev(struct cx231xx *dev, struct usb_device *udev, dev->norm = dev->board.norm; /* register i2c bus */ - errCode = cx231xx_dev_init(dev); - if (errCode < 0) { - cx231xx_dev_uninit(dev); + retval = cx231xx_dev_init(dev); + if (retval) { cx231xx_errdev("%s: cx231xx_i2c_register - errCode [%d]!\n", - __func__, errCode); - return errCode; + __func__, retval); + goto err_dev_init; } /* Do board specific init */ @@ -1047,11 +1045,11 @@ static int cx231xx_init_dev(struct cx231xx *dev, struct usb_device *udev, dev->interlaced = 0; dev->video_input = 0; - errCode = cx231xx_config(dev); - if (errCode < 0) { + retval = cx231xx_config(dev); + if (retval) { cx231xx_errdev("%s: cx231xx_config - errCode [%d]!\n", - __func__, errCode); - return errCode; + __func__, retval); + goto err_dev_init; } /* init video dma queues */ @@ -1075,9 +1073,9 @@ static int cx231xx_init_dev(struct cx231xx *dev, struct usb_device *udev, } retval = cx231xx_register_analog_devices(dev); - if (retval < 0) { - cx231xx_release_resources(dev); - return retval; + if (retval) { + cx231xx_release_analog_resources(dev); + goto err_analog; } cx231xx_ir_init(dev); @@ -1085,6 +1083,11 @@ static int cx231xx_init_dev(struct cx231xx *dev, struct usb_device *udev, cx231xx_init_extension(dev); return 0; +err_analog: + cx231xx_remove_from_devlist(dev); +err_dev_init: + cx231xx_dev_uninit(dev); + return retval; } #if defined(CONFIG_MODULES) && defined(MODULE) @@ -1132,7 +1135,6 @@ static int cx231xx_usb_probe(struct usb_interface *interface, char *speed; struct usb_interface_assoc_descriptor *assoc_desc; - udev = usb_get_dev(interface_to_usbdev(interface)); ifnum = interface->altsetting[0].desc.bInterfaceNumber; /* @@ -1161,6 +1163,8 @@ static int cx231xx_usb_probe(struct usb_interface *interface, return -ENOMEM; } + udev = usb_get_dev(interface_to_usbdev(interface)); + snprintf(dev->name, 29, "cx231xx #%d", nr); dev->devno = nr; dev->model = id->driver_info; @@ -1223,10 +1227,8 @@ static int cx231xx_usb_probe(struct usb_interface *interface, if (assoc_desc->bFirstInterface != ifnum) { cx231xx_err(DRIVER_NAME ": Not found " "matching IAD interface\n"); - clear_bit(dev->devno, &cx231xx_devused); - kfree(dev); - dev = NULL; - return -ENODEV; + retval = -ENODEV; + goto err_if; } cx231xx_info("registering interface %d\n", ifnum); @@ -1242,22 +1244,13 @@ static int cx231xx_usb_probe(struct usb_interface *interface, retval = v4l2_device_register(&interface->dev, &d
[PATCH 1/2] staging: gdm7240: alloc_mux_rx() does not need GFP_ATOMIC
As far as alloc_mux_rx() is called from probe() only there is no need in GFP_ATOMIC here. Found by Linux Driver Verification project (linuxtesting.org). Signed-off-by: Alexey Khoroshilov --- drivers/staging/gdm724x/gdm_mux.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/gdm724x/gdm_mux.c b/drivers/staging/gdm724x/gdm_mux.c index 5b1ef40..5221cf9 100644 --- a/drivers/staging/gdm724x/gdm_mux.c +++ b/drivers/staging/gdm724x/gdm_mux.c @@ -96,12 +96,12 @@ static struct mux_rx *alloc_mux_rx(void) { struct mux_rx *r = NULL; - r = kzalloc(sizeof(struct mux_rx), GFP_ATOMIC); + r = kzalloc(sizeof(struct mux_rx), GFP_KERNEL); if (!r) return NULL; - r->urb = usb_alloc_urb(0, GFP_ATOMIC); - r->buf = kmalloc(MUX_RX_MAX_SIZE, GFP_ATOMIC); + r->urb = usb_alloc_urb(0, GFP_KERNEL); + r->buf = kmalloc(MUX_RX_MAX_SIZE, GFP_KERNEL); if (!r->urb || !r->buf) { usb_free_urb(r->urb); kfree(r->buf); -- 1.8.1.2 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 2/2] staging: gdm7240: fix memory leak on failure path
init_usb() may fail after some of mux_rxes already allocated. So we need to release them on the failure path. Found by Linux Driver Verification project (linuxtesting.org). Signed-off-by: Alexey Khoroshilov --- drivers/staging/gdm724x/gdm_mux.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/gdm724x/gdm_mux.c b/drivers/staging/gdm724x/gdm_mux.c index 5221cf9..69813c7 100644 --- a/drivers/staging/gdm724x/gdm_mux.c +++ b/drivers/staging/gdm724x/gdm_mux.c @@ -541,7 +541,7 @@ static int gdm_mux_probe(struct usb_interface *intf, const struct usb_device_id ret = init_usb(mux_dev); if (ret) - goto err_free_tty; + goto err_free_usb; tty_dev->priv_dev = (void *)mux_dev; tty_dev->send_func = gdm_mux_send; @@ -565,8 +565,8 @@ static int gdm_mux_probe(struct usb_interface *intf, const struct usb_device_id err_unregister_tty: unregister_lte_tty_device(tty_dev); +err_free_usb: release_usb(mux_dev); -err_free_tty: kfree(tty_dev); err_free_mux: kfree(mux_dev); -- 1.8.1.2 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] rtl8187: fix use after free on failure path in rtl8187_init_urbs()
In case of __dev_alloc_skb() failure rtl8187_init_urbs() calls usb_free_urb(entry) where 'entry' can points to urb allocated at the previous iteration. That means refcnt will be decremented incorrectly and the urb can be used after memory deallocation. The patch fixes the issue and implements error handling of init_urbs in rtl8187_start(). Found by Linux Driver Verification project (linuxtesting.org). Signed-off-by: Alexey Khoroshilov --- drivers/net/wireless/rtl818x/rtl8187/dev.c | 15 ++- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/drivers/net/wireless/rtl818x/rtl8187/dev.c b/drivers/net/wireless/rtl818x/rtl8187/dev.c index f49220e..e83d53c 100644 --- a/drivers/net/wireless/rtl818x/rtl8187/dev.c +++ b/drivers/net/wireless/rtl818x/rtl8187/dev.c @@ -438,17 +438,16 @@ static int rtl8187_init_urbs(struct ieee80211_hw *dev) skb_queue_tail(&priv->rx_queue, skb); usb_anchor_urb(entry, &priv->anchored); ret = usb_submit_urb(entry, GFP_KERNEL); + usb_free_urb(entry); if (ret) { skb_unlink(skb, &priv->rx_queue); usb_unanchor_urb(entry); goto err; } - usb_free_urb(entry); } return ret; err: - usb_free_urb(entry); kfree_skb(skb); usb_kill_anchored_urbs(&priv->anchored); return ret; @@ -956,8 +955,12 @@ static int rtl8187_start(struct ieee80211_hw *dev) (RETRY_COUNT << 8 /* short retry limit */) | (RETRY_COUNT << 0 /* long retry limit */) | (7 << 21 /* MAX TX DMA */)); - rtl8187_init_urbs(dev); - rtl8187b_init_status_urb(dev); + ret = rtl8187_init_urbs(dev); + if (ret) + goto rtl8187_start_exit; + ret = rtl8187b_init_status_urb(dev); + if (ret) + usb_kill_anchored_urbs(&priv->anchored); goto rtl8187_start_exit; } @@ -966,7 +969,9 @@ static int rtl8187_start(struct ieee80211_hw *dev) rtl818x_iowrite32(priv, &priv->map->MAR[0], ~0); rtl818x_iowrite32(priv, &priv->map->MAR[1], ~0); - rtl8187_init_urbs(dev); + ret = rtl8187_init_urbs(dev); + if (ret) + goto rtl8187_start_exit; reg = RTL818X_RX_CONF_ONLYERLPKT | RTL818X_RX_CONF_RX_AUTORESETPHY | -- 1.8.1.2 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH] rtl8187: fix use after free on failure path in rtl8187_init_urbs()
On 01.09.2013 10:51, Hin-Tak Leung wrote: -- On Sat, Aug 31, 2013 22:18 BST Alexey Khoroshilov wrote: In case of __dev_alloc_skb() failure rtl8187_init_urbs() calls usb_free_urb(entry) where 'entry' can points to urb allocated at the previous iteration. That means refcnt will be decremented incorrectly and the urb can be used after memory deallocation. The patch fixes the issue and implements error handling of init_urbs in rtl8187_start(). Found by Linux Driver Verification project (linuxtesting.org). Signed-off-by: Alexey Khoroshilov --- drivers/net/wireless/rtl818x/rtl8187/dev.c | 15 ++- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/drivers/net/wireless/rtl818x/rtl8187/dev.c b/drivers/net/wireless/rtl818x/rtl8187/dev.c index f49220e..e83d53c 100644 --- a/drivers/net/wireless/rtl818x/rtl8187/dev.c +++ b/drivers/net/wireless/rtl818x/rtl8187/dev.c @@ -438,17 +438,16 @@ static int rtl8187_init_urbs(struct ieee80211_hw *dev) skb_queue_tail(&priv->rx_queue, skb); usb_anchor_urb(entry, &priv->anchored); ret = usb_submit_urb(entry, GFP_KERNEL); +usb_free_urb(entry); if (ret) { skb_unlink(skb, &priv->rx_queue); usb_unanchor_urb(entry); goto err; } -usb_free_urb(entry); } return ret; err: -usb_free_urb(entry); kfree_skb(skb); usb_kill_anchored_urbs(&priv->anchored); return ret; This part looks wrong - you free_urb(entry) then unanchor_urb(entry). I do not see any problems here. usb_free_urb() just decrements refcnt of the urb. While usb_anchor_urb() and usb_unanchor_urb() increment and decrement it as well. So actual memory deallocation will happen in usb_unanchor_urb(). @@ -956,8 +955,12 @@ static int rtl8187_start(struct ieee80211_hw *dev) (RETRY_COUNT < 8 /* short retry limit */) | (RETRY_COUNT < 0 /* long retry limit */) | (7 < 21 /* MAX TX DMA */)); -rtl8187_init_urbs(dev); -rtl8187b_init_status_urb(dev); +ret = rtl8187_init_urbs(dev); +if (ret) +goto rtl8187_start_exit; +ret = rtl8187b_init_status_urb(dev); +if (ret) +usb_kill_anchored_urbs(&priv->anchored); goto rtl8187_start_exit; } @@ -966,7 +969,9 @@ static int rtl8187_start(struct ieee80211_hw *dev) rtl818x_iowrite32(priv, &priv->map->MAR[0], ~0); rtl818x_iowrite32(priv, &priv->map->MAR[1], ~0); -rtl8187_init_urbs(dev); +ret = rtl8187_init_urbs(dev); +if (ret) +goto rtl8187_start_exit; reg = RTL818X_RX_CONF_ONLYERLPKT | RTL818X_RX_CONF_RX_AUTORESETPHY | -- 1.8.1.2 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH] rtl8187: fix use after free on failure path in rtl8187_init_urbs()
On 02.09.2013 10:34, Hin-Tak Leung wrote: -- On Mon, Sep 2, 2013 05:06 BST Alexey Khoroshilov wrote: On 01.09.2013 10:51, Hin-Tak Leung wrote: -- On Sat, Aug 31, 2013 22:18 BST Alexey Khoroshilov wrote: In case of __dev_alloc_skb() failure rtl8187_init_urbs() calls usb_free_urb(entry) where 'entry' can points to urb allocated at the previous iteration. That means refcnt will be decremented incorrectly and the urb can be used after memory deallocation. The patch fixes the issue and implements error handling of init_urbs in rtl8187_start(). Found by Linux Driver Verification project (linuxtesting.org). Signed-off-by: Alexey Khoroshilov --- drivers/net/wireless/rtl818x/rtl8187/dev.c | 15 ++- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/drivers/net/wireless/rtl818x/rtl8187/dev.c b/drivers/net/wireless/rtl818x/rtl8187/dev.c index f49220e..e83d53c 100644 --- a/drivers/net/wireless/rtl818x/rtl8187/dev.c +++ b/drivers/net/wireless/rtl818x/rtl8187/dev.c @@ -438,17 +438,16 @@ static int rtl8187_init_urbs(struct ieee80211_hw *dev) skb_queue_tail(&priv->rx_queue, skb); usb_anchor_urb(entry, &priv->anchored); ret = usb_submit_urb(entry, GFP_KERNEL); +usb_free_urb(entry); if (ret) { skb_unlink(skb, &priv->rx_queue); usb_unanchor_urb(entry); goto err; } -usb_free_urb(entry); } return ret; err: -usb_free_urb(entry); kfree_skb(skb); usb_kill_anchored_urbs(&priv->anchored); return ret; This part looks wrong - you free_urb(entry) then unanchor_urb(entry). I do not see any problems here. usb_free_urb() just decrements refcnt of the urb. While usb_anchor_urb() and usb_unanchor_urb() increment and decrement it as well. So actual memory deallocation will happen in usb_unanchor_urb(). If the routines work as you say, they probably are misnamed, and/or prototyped wrongly? Also, you are making assumptions about how they are implemented, and relying on the implementation details to be fixed for eternity. I am just saying, XXX_free(some_entity); if(condtion) do_stuff(some_entity); looks wrong, and if that's intentional, those routines really shouldn't be named as such. There is an alias for usb_free_urb() named usb_put_urb(). I will resend the patch with such substitution. -- Alexey -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v2] rtl8187: fix use after free on failure path in rtl8187_init_urbs()
In case of __dev_alloc_skb() failure rtl8187_init_urbs() calls usb_free_urb(entry) where 'entry' can points to urb allocated at the previous iteration. That means refcnt will be decremented incorrectly and the urb can be used after memory deallocation. The patch fixes the issue and implements error handling of init_urbs in rtl8187_start(). Found by Linux Driver Verification project (linuxtesting.org). Signed-off-by: Alexey Khoroshilov --- drivers/net/wireless/rtl818x/rtl8187/dev.c | 15 ++- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/drivers/net/wireless/rtl818x/rtl8187/dev.c b/drivers/net/wireless/rtl818x/rtl8187/dev.c index f49220e..a668c0e 100644 --- a/drivers/net/wireless/rtl818x/rtl8187/dev.c +++ b/drivers/net/wireless/rtl818x/rtl8187/dev.c @@ -438,17 +438,16 @@ static int rtl8187_init_urbs(struct ieee80211_hw *dev) skb_queue_tail(&priv->rx_queue, skb); usb_anchor_urb(entry, &priv->anchored); ret = usb_submit_urb(entry, GFP_KERNEL); + usb_put_urb(entry); if (ret) { skb_unlink(skb, &priv->rx_queue); usb_unanchor_urb(entry); goto err; } - usb_free_urb(entry); } return ret; err: - usb_free_urb(entry); kfree_skb(skb); usb_kill_anchored_urbs(&priv->anchored); return ret; @@ -956,8 +955,12 @@ static int rtl8187_start(struct ieee80211_hw *dev) (RETRY_COUNT << 8 /* short retry limit */) | (RETRY_COUNT << 0 /* long retry limit */) | (7 << 21 /* MAX TX DMA */)); - rtl8187_init_urbs(dev); - rtl8187b_init_status_urb(dev); + ret = rtl8187_init_urbs(dev); + if (ret) + goto rtl8187_start_exit; + ret = rtl8187b_init_status_urb(dev); + if (ret) + usb_kill_anchored_urbs(&priv->anchored); goto rtl8187_start_exit; } @@ -966,7 +969,9 @@ static int rtl8187_start(struct ieee80211_hw *dev) rtl818x_iowrite32(priv, &priv->map->MAR[0], ~0); rtl818x_iowrite32(priv, &priv->map->MAR[1], ~0); - rtl8187_init_urbs(dev); + ret = rtl8187_init_urbs(dev); + if (ret) + goto rtl8187_start_exit; reg = RTL818X_RX_CONF_ONLYERLPKT | RTL818X_RX_CONF_RX_AUTORESETPHY | -- 1.8.1.2 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] carl9170: fix leaks at failure path in carl9170_usb_probe()
carl9170_usb_probe() does not handle request_firmware_nowait() failure that leads to several leaks in this case. The patch adds all required deallocations. Found by Linux Driver Verification project (linuxtesting.org). Signed-off-by: Alexey Khoroshilov --- drivers/net/wireless/ath/carl9170/usb.c | 8 +++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/carl9170/usb.c b/drivers/net/wireless/ath/carl9170/usb.c index 307bc0d..3c76de1 100644 --- a/drivers/net/wireless/ath/carl9170/usb.c +++ b/drivers/net/wireless/ath/carl9170/usb.c @@ -1076,8 +1076,14 @@ static int carl9170_usb_probe(struct usb_interface *intf, carl9170_set_state(ar, CARL9170_STOPPED); - return request_firmware_nowait(THIS_MODULE, 1, CARL9170FW_NAME, + err = request_firmware_nowait(THIS_MODULE, 1, CARL9170FW_NAME, &ar->udev->dev, GFP_KERNEL, ar, carl9170_usb_firmware_step2); + if (err) { + usb_put_dev(udev); + usb_put_dev(udev); + carl9170_free(ar); + } + return err; } static void carl9170_usb_disconnect(struct usb_interface *intf) -- 1.8.1.2 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH] carl9170: fix leaks at failure path in carl9170_usb_probe()
On 28.09.2013 00:17, Fabio Estevam wrote: On Sat, Sep 28, 2013 at 12:51 AM, Alexey Khoroshilov wrote: - return request_firmware_nowait(THIS_MODULE, 1, CARL9170FW_NAME, + err = request_firmware_nowait(THIS_MODULE, 1, CARL9170FW_NAME, &ar->udev->dev, GFP_KERNEL, ar, carl9170_usb_firmware_step2); + if (err) { + usb_put_dev(udev); + usb_put_dev(udev); You are doing the same free twice. Yes, because it was get twice. I guess you meant to also free: usb_put_dev(ar->udev) udev and ar->udev are equal, so technically the patch is correct. I agree that there is some inconsistency, but I would prefer to fix it at usb_get_dev() side with a comment about reasons for the double get. -- Alexey -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] p54pci: don't return zero on failure path in p54p_probe()
If pci_set_dma_mask() or pci_set_consistent_dma_mask() fails in p54p_probe(), it breaks off initialization, deallocates all resources, but returns zero. The patch implements proper error code propagation. Found by Linux Driver Verification project (linuxtesting.org). Signed-off-by: Alexey Khoroshilov --- drivers/net/wireless/p54/p54pci.c |6 -- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/p54/p54pci.c b/drivers/net/wireless/p54/p54pci.c index 933e5d9..fef69ea 100644 --- a/drivers/net/wireless/p54/p54pci.c +++ b/drivers/net/wireless/p54/p54pci.c @@ -568,8 +568,10 @@ static int p54p_probe(struct pci_dev *pdev, goto err_disable_dev; } - if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32)) || - pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32))) { + err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)); + if (!err) + err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32)); + if (err) { dev_err(&pdev->dev, "No suitable DMA available\n"); goto err_free_reg; } -- 1.7.9.5 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH] p54pci: don't return zero on failure path in p54p_probe()
On 01/02/2013 01:45 AM, Christian Lamparter wrote: On Tuesday 01 January 2013 22:11:01 Alexey Khoroshilov wrote: If pci_set_dma_mask() or pci_set_consistent_dma_mask() fails in p54p_probe(), it breaks off initialization, deallocates all resources, but returns zero. The patch implements proper error code propagation. Uh, Thanks! But wait, I think there's another return 0 in the error path. See p54pci.c @ line 558: mem_len = pci_resource_len(pdev, 0); if (mem_len < sizeof(...)) { dev_err(...) goto err_disabled_dev; } Do you think you can add a err = -EINVAL; before the goto too? You are right! But I would say -ENODEV is more popular error code in this case. [I wonder why this wasn't found by the verification project as well? Could it be that pci_resource_len(...) < sizeof(...) is somehow always true and this is a dead branch?] Actually it was found, but I have no direct access to the results at the moment. My fault. Would you like I resend the patch to fix both? -- Best regards, Alexey -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v2] p54pci: don't return zero on failure paths in p54p_probe()
If pci_set_dma_mask() or pci_set_consistent_dma_mask() fails in p54p_probe(), it breaks off initialization, deallocates all resources, but returns zero. Similar issue is if check for returned value of pci_resource_len() fails. The patch implements proper error code propagation. Found by Linux Driver Verification project (linuxtesting.org). Signed-off-by: Alexey Khoroshilov Acked-by: Christian Lamparter --- drivers/net/wireless/p54/p54pci.c |7 +-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/p54/p54pci.c b/drivers/net/wireless/p54/p54pci.c index 933e5d9..57e3af8 100644 --- a/drivers/net/wireless/p54/p54pci.c +++ b/drivers/net/wireless/p54/p54pci.c @@ -559,6 +559,7 @@ static int p54p_probe(struct pci_dev *pdev, mem_len = pci_resource_len(pdev, 0); if (mem_len < sizeof(struct p54p_csr)) { dev_err(&pdev->dev, "Too short PCI resources\n"); + err = -ENODEV; goto err_disable_dev; } @@ -568,8 +569,10 @@ static int p54p_probe(struct pci_dev *pdev, goto err_disable_dev; } - if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32)) || - pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32))) { + err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)); + if (!err) + err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32)); + if (err) { dev_err(&pdev->dev, "No suitable DMA available\n"); goto err_free_reg; } -- 1.7.9.5 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] mei: fix mismatch in mutex unlock-lock in mei_amthif_read()
Users of mei_amthif_read() expect it leaves dev->device_lock held, while there is a path where mei_amthif_read() unlocks device_lock and returns -ERESTARTSYS. The patch move code locking device_lock back before the return. Found by Linux Driver Verification project (linuxtesting.org). Signed-off-by: Alexey Khoroshilov --- drivers/misc/mei/amthif.c |6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/misc/mei/amthif.c b/drivers/misc/mei/amthif.c index 18794ae..e40ffd9 100644 --- a/drivers/misc/mei/amthif.c +++ b/drivers/misc/mei/amthif.c @@ -187,13 +187,13 @@ int mei_amthif_read(struct mei_device *dev, struct file *file, wait_ret = wait_event_interruptible(dev->iamthif_cl.wait, (cb = mei_amthif_find_read_list_entry(dev, file))); + /* Locking again the Mutex */ + mutex_lock(&dev->device_lock); + if (wait_ret) return -ERESTARTSYS; dev_dbg(&dev->pdev->dev, "woke up from sleep\n"); - - /* Locking again the Mutex */ - mutex_lock(&dev->device_lock); } -- 1.7.9.5 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] e1000e: fix mismatch in mutex lock-unlock in e1000_reset_hw_82571()
If e1000_get_hw_semaphore_82574() succeed, it acquires swflag_mutex, otherwise it does not. But the returned value of e1000_get_hw_semaphore_82574() is ignored, so unlocking of swflag_mutex happens anyway. The patch fixes the issue by breaking reset if MIC ownership is not acquired. Found by Linux Driver Verification project (linuxtesting.org). Signed-off-by: Alexey Khoroshilov --- drivers/net/ethernet/intel/e1000e/82571.c |4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/intel/e1000e/82571.c b/drivers/net/ethernet/intel/e1000e/82571.c index 2faffbd..a6bd80e 100644 --- a/drivers/net/ethernet/intel/e1000e/82571.c +++ b/drivers/net/ethernet/intel/e1000e/82571.c @@ -1003,8 +1003,10 @@ static s32 e1000_reset_hw_82571(struct e1000_hw *hw) default: break; } - if (ret_val) + if (ret_val) { e_dbg("Cannot acquire MDIO ownership\n"); + return ret_val; + } ctrl = er32(CTRL); -- 1.7.9.5 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] ext4: unregister extents status shrinker if mount failed
If ext4_fill_super() failed after extents status shrinker has been registered, the shrinker is left in a global list while the memory, it sits in, is already freed. Oops is not so bad scenario after that. Found by Linux File System Verification project (linuxtesting.org). Signed-off-by: Alexey Khoroshilov --- fs/ext4/super.c |6 -- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/fs/ext4/super.c b/fs/ext4/super.c index 5d6d5357..5f9cb30 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c @@ -3757,7 +3757,7 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) if (EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_MMP) && !(sb->s_flags & MS_RDONLY)) if (ext4_multi_mount_protect(sb, le64_to_cpu(es->s_mmp_block))) - goto failed_mount3; + goto failed_mount_shr; /* * The first inode we look at is the journal inode. Don't try @@ -3766,7 +3766,7 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) if (!test_opt(sb, NOLOAD) && EXT4_HAS_COMPAT_FEATURE(sb, EXT4_FEATURE_COMPAT_HAS_JOURNAL)) { if (ext4_load_journal(sb, es, journal_devnum)) - goto failed_mount3; + goto failed_mount_shr; } else if (test_opt(sb, NOLOAD) && !(sb->s_flags & MS_RDONLY) && EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER)) { ext4_msg(sb, KERN_ERR, "required journal recovery " @@ -4009,6 +4009,8 @@ failed_mount_wq: jbd2_journal_destroy(sbi->s_journal); sbi->s_journal = NULL; } +failed_mount_shr: + ext4_es_unregister_shrinker(sb); failed_mount3: del_timer(&sbi->s_err_report); if (sbi->s_flex_groups) -- 1.7.9.5 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] orinoco_usb: fix memory leak in ezusb_access_ltv() when device disconnected
If "device is disconnected" check occurs to be true in ezusb_access_ltv(), it just return -ENODEV. But that means request_context is leaked since there are no any references to it anymore. The patch adds a call to ezusb_request_context_put() before return. Found by Linux Driver Verification project (linuxtesting.org). Signed-off-by: Alexey Khoroshilov --- drivers/net/wireless/orinoco/orinoco_usb.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/orinoco/orinoco_usb.c b/drivers/net/wireless/orinoco/orinoco_usb.c index 1f9cb55..bdfe637 100644 --- a/drivers/net/wireless/orinoco/orinoco_usb.c +++ b/drivers/net/wireless/orinoco/orinoco_usb.c @@ -881,7 +881,8 @@ static int ezusb_access_ltv(struct ezusb_priv *upriv, if (!upriv->udev) { dbg("Device disconnected"); - return -ENODEV; + retval = -ENODEV; + goto exit; } if (upriv->read_urb->status != -EINPROGRESS) -- 1.8.1.2 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] USB: fix PTR_ERR translation in init_usb_class()
There is a misprint in init_usb_class(): IS_ERR is used to get error code instead of PTR_ERR. Found by Linux Driver Verification project (linuxtesting.org). Signed-off-by: Alexey Khoroshilov --- drivers/usb/core/file.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/core/file.c b/drivers/usb/core/file.c index e5387a4..6a4c407 100644 --- a/drivers/usb/core/file.c +++ b/drivers/usb/core/file.c @@ -94,7 +94,7 @@ static int init_usb_class(void) kref_init(&usb_class->kref); usb_class->class = class_create(THIS_MODULE, "usbmisc"); if (IS_ERR(usb_class->class)) { - result = IS_ERR(usb_class->class); + result = PTR_ERR(usb_class->class); printk(KERN_ERR "class_create failed for usb devices\n"); kfree(usb_class); usb_class = NULL; -- 1.8.1.2 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] tty/serial/sirf: fix error propagation in sirfsoc_uart_probe()
If pinctrl_get_select_default() fails, sirfsoc_uart_probe() returns IS_ERR(result) instead of PTR_ERR(result). Found by Linux Driver Verification project (linuxtesting.org). Signed-off-by: Alexey Khoroshilov --- drivers/tty/serial/sirfsoc_uart.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/tty/serial/sirfsoc_uart.c b/drivers/tty/serial/sirfsoc_uart.c index 03465b6..1fd564b 100644 --- a/drivers/tty/serial/sirfsoc_uart.c +++ b/drivers/tty/serial/sirfsoc_uart.c @@ -687,9 +687,10 @@ int sirfsoc_uart_probe(struct platform_device *pdev) if (sirfport->hw_flow_ctrl) { sirfport->p = pinctrl_get_select_default(&pdev->dev); - ret = IS_ERR(sirfport->p); - if (ret) + if (IS_ERR(sirfport->p)) { + ret = PTR_ERR(sirfport->p); goto err; + } } sirfport->clk = clk_get(&pdev->dev, NULL); -- 1.8.1.2 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] GFS2: fix error propagation in init_threads()
If kthread_run() fails, init_threads() returns IS_ERR(p) instead of PTR_ERR(p). Found by Linux Driver Verification project (linuxtesting.org). Signed-off-by: Alexey Khoroshilov --- fs/gfs2/ops_fstype.c | 8 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/fs/gfs2/ops_fstype.c b/fs/gfs2/ops_fstype.c index 60ede2a..0262c19 100644 --- a/fs/gfs2/ops_fstype.c +++ b/fs/gfs2/ops_fstype.c @@ -916,16 +916,16 @@ static int init_threads(struct gfs2_sbd *sdp, int undo) goto fail_quotad; p = kthread_run(gfs2_logd, sdp, "gfs2_logd"); - error = IS_ERR(p); - if (error) { + if (IS_ERR(p)) { + error = PTR_ERR(p); fs_err(sdp, "can't start logd thread: %d\n", error); return error; } sdp->sd_logd_process = p; p = kthread_run(gfs2_quotad, sdp, "gfs2_quotad"); - error = IS_ERR(p); - if (error) { + if (IS_ERR(p)) { + error = PTR_ERR(p); fs_err(sdp, "can't start quotad thread: %d\n", error); goto fail; } -- 1.8.1.2 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] spi/sirf: fix error propagation in spi_sirfsoc_probe()
If pinctrl_get_select_default() fails, spi_sirfsoc_probe() returns IS_ERR(sspi->p) instead of PTR_ERR(sspi->p). Found by Linux Driver Verification project (linuxtesting.org). Signed-off-by: Alexey Khoroshilov --- drivers/spi/spi-sirf.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/spi/spi-sirf.c b/drivers/spi/spi-sirf.c index 0808cd5..94c3920 100644 --- a/drivers/spi/spi-sirf.c +++ b/drivers/spi/spi-sirf.c @@ -559,9 +559,10 @@ static int spi_sirfsoc_probe(struct platform_device *pdev) sspi->bitbang.master->dev.of_node = pdev->dev.of_node; sspi->p = pinctrl_get_select_default(&pdev->dev); - ret = IS_ERR(sspi->p); - if (ret) + if (IS_ERR(sspi->p)) { + ret = PTR_ERR(sspi->p); goto free_master; + } sspi->clk = clk_get(&pdev->dev, NULL); if (IS_ERR(sspi->clk)) { -- 1.8.1.2 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] GFS2: minor readability improvement in gfs2_mount()
The patch makes usage pattern of IS_ERR-PTR_ERR more typical. Signed-off-by: Alexey Khoroshilov --- fs/gfs2/ops_fstype.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/fs/gfs2/ops_fstype.c b/fs/gfs2/ops_fstype.c index 0262c19..0d30e8e 100644 --- a/fs/gfs2/ops_fstype.c +++ b/fs/gfs2/ops_fstype.c @@ -1313,9 +1313,10 @@ static struct dentry *gfs2_mount(struct file_system_type *fs_type, int flags, } s = sget(fs_type, test_gfs2_super, set_gfs2_super, flags, bdev); mutex_unlock(&bdev->bd_fsfreeze_mutex); - error = PTR_ERR(s); - if (IS_ERR(s)) + if (IS_ERR(s)) { + error = PTR_ERR(s); goto error_bdev; + } if (s->s_root) blkdev_put(bdev, mode); -- 1.8.1.2 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH] GFS2: minor readability improvement in gfs2_mount()
Hi Steve, On 06/06/2013 01:24 PM, Steven Whitehouse wrote: > Hi, > > On Thu, 2013-06-06 at 01:29 +0400, Alexey Khoroshilov wrote: >> The patch makes usage pattern of IS_ERR-PTR_ERR more typical. >> >> Signed-off-by: Alexey Khoroshilov >> --- >> fs/gfs2/ops_fstype.c | 5 +++-- >> 1 file changed, 3 insertions(+), 2 deletions(-) >> >> diff --git a/fs/gfs2/ops_fstype.c b/fs/gfs2/ops_fstype.c >> index 0262c19..0d30e8e 100644 >> --- a/fs/gfs2/ops_fstype.c >> +++ b/fs/gfs2/ops_fstype.c >> @@ -1313,9 +1313,10 @@ static struct dentry *gfs2_mount(struct >> file_system_type *fs_type, int flags, >> } >> s = sget(fs_type, test_gfs2_super, set_gfs2_super, flags, bdev); >> mutex_unlock(&bdev->bd_fsfreeze_mutex); >> -error = PTR_ERR(s); >> -if (IS_ERR(s)) >> +if (IS_ERR(s)) { >> +error = PTR_ERR(s); >> goto error_bdev; >> +} > I'm not sure what you are getting at here. Why add a jump into the fast > path? My experiments with gcc 4.7.3 on x86-64 do not show any difference in code generated with patch and without it. 227a:e8 00 00 00 00 callq 227f 227b: R_X86_64_PC32sget-0x4 227f:4c 89 f7 mov%r14,%rdi 2282:49 89 c4 mov%rax,%r12 2285:e8 00 00 00 00 callq 228a 2286: R_X86_64_PC32mutex_unlock-0x4 228a:49 81 fc 00 f0 ff ff cmp$0xf000,%r12 2291:0f 87 2a 01 00 00ja 23c1 2297:49 83 7c 24 60 00cmpq $0x0,0x60(%r12) 229d:74 0bje 22aa 229f:44 89 ee mov%r13d,%esi 22a2:48 89 df mov%rbx,%rdi 22a5:e8 00 00 00 00 callq 22aa 22a6: R_X86_64_PC32blkdev_put-0x4 It looks like 'error = PTR_ERR(s);' assignment is just ignored because s and error share the same register %r12. So the only point of the patch is to improve readability. -- Best regards, Alexey -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] [media] go7007: fix return 0 for unsupported devices in go7007_usb_probe()
probe() should not return 0 for unsupported devices, but go7007_usb_probe() does. The patch fixes it to return -ENODEV. Found by Linux Driver Verification project (linuxtesting.org). Signed-off-by: Alexey Khoroshilov --- drivers/staging/media/go7007/go7007-usb.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/media/go7007/go7007-usb.c b/drivers/staging/media/go7007/go7007-usb.c index 50066e0..46ed832 100644 --- a/drivers/staging/media/go7007/go7007-usb.c +++ b/drivers/staging/media/go7007/go7007-usb.c @@ -1124,7 +1124,7 @@ static int go7007_usb_probe(struct usb_interface *intf, case GO7007_BOARDID_LIFEVIEW_LR192: printk(KERN_ERR "go7007-usb: The Lifeview TV Walker Ultra " "is not supported. Sorry!\n"); - return 0; + return -ENODEV; name = "Lifeview TV Walker Ultra"; board = &board_lifeview_lr192; break; @@ -1140,7 +1140,7 @@ static int go7007_usb_probe(struct usb_interface *intf, default: printk(KERN_ERR "go7007-usb: unknown board ID %d!\n", (unsigned int)id->driver_info); - return 0; + return -ENODEV; } go = go7007_alloc(&board->main_info, &intf->dev); -- 1.8.1.2 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] usb: gadget: r8a66597-udc: do not unlock unheld spinlock in r8a66597_sudmac_irq()
r8a66597_irq() processes sudmac part (r8a66597_sudmac_irq()) before locking r8a66597->lock. But transfer_complete(), that is called inside (r8a66597_sudmac_irq()->sudmac_finish()->transfer_complete()), expects r8a66597->lock is locked. As a result unheld spinlock can be unlocked. The patch just moves locking before calling r8a66597_sudmac_irq(). Found by Linux Driver Verification project (linuxtesting.org). Signed-off-by: Alexey Khoroshilov --- drivers/usb/gadget/r8a66597-udc.c |4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/usb/gadget/r8a66597-udc.c b/drivers/usb/gadget/r8a66597-udc.c index 7ff7d9c..2dd213c 100644 --- a/drivers/usb/gadget/r8a66597-udc.c +++ b/drivers/usb/gadget/r8a66597-udc.c @@ -1469,11 +1469,11 @@ static irqreturn_t r8a66597_irq(int irq, void *_r8a66597) u16 savepipe; u16 mask0; + spin_lock(&r8a66597->lock); + if (r8a66597_is_sudmac(r8a66597)) r8a66597_sudmac_irq(r8a66597); - spin_lock(&r8a66597->lock); - intsts0 = r8a66597_read(r8a66597, INTSTS0); intenb0 = r8a66597_read(r8a66597, INTENB0); -- 1.7.9.5 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] staging/media: lirc_imon: fix leaks in imon_probe()
Error handling of usb_submit_urb() is not as all others in imon_probe(). It just unlocks mutexes and returns nonzero leaving all already allocated resources unfreed. The patch makes sure all the resources are deallocated. Found by Linux Driver Verification project (linuxtesting.org). Signed-off-by: Alexey Khoroshilov --- drivers/staging/media/lirc/lirc_imon.c | 7 --- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/staging/media/lirc/lirc_imon.c b/drivers/staging/media/lirc/lirc_imon.c index 0a2c45d..4afa7da 100644 --- a/drivers/staging/media/lirc/lirc_imon.c +++ b/drivers/staging/media/lirc/lirc_imon.c @@ -911,8 +911,8 @@ static int imon_probe(struct usb_interface *interface, if (retval) { dev_err(dev, "%s: usb_submit_urb failed for intf0 (%d)\n", __func__, retval); - mutex_unlock(&context->ctx_lock); - goto exit; + alloc_status = 8; + goto unlock; } usb_set_intfdata(interface, context); @@ -937,6 +937,8 @@ unlock: alloc_status_switch: switch (alloc_status) { + case 8: + lirc_unregister_driver(driver->minor); case 7: usb_free_urb(tx_urb); case 6: @@ -959,7 +961,6 @@ alloc_status_switch: retval = 0; } -exit: mutex_unlock(&driver_lock); return retval; -- 1.8.1.2 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 1/2] [media] tlg2300: implement error handling in poseidon_probe()
All poseidon init functions properly return error codes, but they are ignored by poseidon_probe(). The patch implements handling of error cases. Found by Linux Driver Verification project (linuxtesting.org). Signed-off-by: Alexey Khoroshilov --- drivers/media/usb/tlg2300/pd-main.c | 27 --- 1 file changed, 24 insertions(+), 3 deletions(-) diff --git a/drivers/media/usb/tlg2300/pd-main.c b/drivers/media/usb/tlg2300/pd-main.c index e07e4c6..ca5e1bc 100644 --- a/drivers/media/usb/tlg2300/pd-main.c +++ b/drivers/media/usb/tlg2300/pd-main.c @@ -436,12 +436,22 @@ static int poseidon_probe(struct usb_interface *interface, /* register v4l2 device */ ret = v4l2_device_register(&interface->dev, &pd->v4l2_dev); + if (ret) + goto err_v4l2; /* register devices in directory /dev */ ret = pd_video_init(pd); - poseidon_audio_init(pd); - poseidon_fm_init(pd); - pd_dvb_usb_device_init(pd); + if (ret) + goto err_video; + ret = poseidon_audio_init(pd); + if (ret) + goto err_audio; + ret = poseidon_fm_init(pd); + if (ret) + goto err_fm; + ret = pd_dvb_usb_device_init(pd); + if (ret) + goto err_dvb; INIT_LIST_HEAD(&pd->device_list); list_add_tail(&pd->device_list, &pd_device_list); @@ -459,6 +469,17 @@ static int poseidon_probe(struct usb_interface *interface, } #endif return 0; +err_dvb: + poseidon_fm_exit(pd); +err_fm: + poseidon_audio_free(pd); +err_audio: + pd_video_exit(pd); +err_video: + v4l2_device_unregister(&pd->v4l2_dev); +err_v4l2: + kfree(pd); + return ret; } static void poseidon_disconnect(struct usb_interface *interface) -- 1.8.1.2 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 2/2] [media] tlg2300: fix checking firmware in poseidon_probe()
check_firmware() makes sure firmware is in a device. It returns zero on success and error code otherwise. Also it sets down_firmware flag to 1 if downloading occurs. The only caller poseidon_probe() checks down_firmware flag and returns 0 without any initialization if it is set. That looks very strange, so the patch removes down_firmware argument of check_firmware() and returns error code if check_firmware() fails in poseidon_probe(). Not tested on real hardware. Found by Linux Driver Verification project (linuxtesting.org). Signed-off-by: Alexey Khoroshilov --- drivers/media/usb/tlg2300/pd-main.c | 10 -- 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/drivers/media/usb/tlg2300/pd-main.c b/drivers/media/usb/tlg2300/pd-main.c index ca5e1bc..95f94e5 100644 --- a/drivers/media/usb/tlg2300/pd-main.c +++ b/drivers/media/usb/tlg2300/pd-main.c @@ -375,7 +375,7 @@ static inline void set_map_flags(struct poseidon *pd, struct usb_device *udev) } #endif -static int check_firmware(struct usb_device *udev, int *down_firmware) +static int check_firmware(struct usb_device *udev) { void *buf; int ret; @@ -395,10 +395,8 @@ static int check_firmware(struct usb_device *udev, int *down_firmware) USB_CTRL_GET_TIMEOUT); kfree(buf); - if (ret < 0) { - *down_firmware = 1; + if (ret < 0) return firmware_download(udev); - } return 0; } @@ -411,9 +409,9 @@ static int poseidon_probe(struct usb_interface *interface, int new_one = 0; /* download firmware */ - check_firmware(udev, &ret); + ret = check_firmware(udev); if (ret) - return 0; + return ret; /* Do I recovery from the hibernate ? */ pd = find_old_poseidon(udev); -- 1.8.1.2 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] staging: ft1000: fix memory leak on error path in ft1000_probe()
ft1000dev->tx_urb and ft1000dev->rx_urb are not deallocated if something goes wrong in ft1000_probe(). Also there is no check for success of urb allocation. The patch fixes the both issues. By the way, there is no sense in GFP_ATOMIC for urb allocation here, so it is changed to GFP_KERNEL. Found by Linux Driver Verification project (linuxtesting.org). Signed-off-by: Alexey Khoroshilov --- drivers/staging/ft1000/ft1000-usb/ft1000_usb.c | 10 -- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_usb.c b/drivers/staging/ft1000/ft1000-usb/ft1000_usb.c index 614db55..29a7cd2 100644 --- a/drivers/staging/ft1000/ft1000-usb/ft1000_usb.c +++ b/drivers/staging/ft1000/ft1000-usb/ft1000_usb.c @@ -79,8 +79,12 @@ static int ft1000_probe(struct usb_interface *interface, ft1000dev->dev = dev; ft1000dev->status = 0; ft1000dev->net = NULL; - ft1000dev->tx_urb = usb_alloc_urb(0, GFP_ATOMIC); - ft1000dev->rx_urb = usb_alloc_urb(0, GFP_ATOMIC); + ft1000dev->tx_urb = usb_alloc_urb(0, GFP_KERNEL); + ft1000dev->rx_urb = usb_alloc_urb(0, GFP_KERNEL); + if (!ft1000dev->tx_urb || !ft1000dev->rx_urb) { + ret = -ENOMEM; + goto err_fw; + } DEBUG("ft1000_probe is called\n"); numaltsetting = interface->num_altsetting; @@ -209,6 +213,8 @@ err_thread: err_load: kfree(pFileStart); err_fw: + usb_free_urb(ft1000dev->rx_urb); + usb_free_urb(ft1000dev->tx_urb); kfree(ft1000dev); return ret; } -- 1.8.1.2 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] [media] ttusb-budget: fix memory leak in ttusb_probe()
If something goes wrong starting from i2c_add_adapter(), ttusb->iso_urb[] and ttusb itself are not deallocated. Found by Linux Driver Verification project (linuxtesting.org). Signed-off-by: Alexey Khoroshilov --- drivers/media/usb/ttusb-budget/dvb-ttusb-budget.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/media/usb/ttusb-budget/dvb-ttusb-budget.c b/drivers/media/usb/ttusb-budget/dvb-ttusb-budget.c index 21b9049..f8a60c1 100644 --- a/drivers/media/usb/ttusb-budget/dvb-ttusb-budget.c +++ b/drivers/media/usb/ttusb-budget/dvb-ttusb-budget.c @@ -1768,6 +1768,8 @@ err_i2c_del_adapter: i2c_del_adapter(&ttusb->i2c_adap); err_unregister_adapter: dvb_unregister_adapter (&ttusb->adapter); + ttusb_free_iso_urbs(ttusb); + kfree(ttusb); return result; } -- 1.8.1.2 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] [media] usbvision-video: fix memory leak of alt_max_pkt_size
1. usbvision->alt_max_pkt_size is not deallocated anywhere. 2. if allocation of usbvision->alt_max_pkt_size fails, there is no proper deallocation of already acquired resources. The patch adds kfree(usbvision->alt_max_pkt_size) to usbvision_release() as soon as other deallocations happen there. It calls usbvision_release() if allocation of usbvision->alt_max_pkt_size fails as soon as usbvision_release() is safe to work with incompletely initialized usbvision structure. Found by Linux Driver Verification project (linuxtesting.org). Signed-off-by: Alexey Khoroshilov --- drivers/media/usb/usbvision/usbvision-video.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/media/usb/usbvision/usbvision-video.c b/drivers/media/usb/usbvision/usbvision-video.c index d34c2af..443e783 100644 --- a/drivers/media/usb/usbvision/usbvision-video.c +++ b/drivers/media/usb/usbvision/usbvision-video.c @@ -1459,6 +1459,7 @@ static void usbvision_release(struct usb_usbvision *usbvision) usbvision_remove_sysfs(usbvision->vdev); usbvision_unregister_video(usbvision); + kfree(usbvision->alt_max_pkt_size); usb_free_urb(usbvision->ctrl_urb); @@ -1574,6 +1575,7 @@ static int usbvision_probe(struct usb_interface *intf, usbvision->alt_max_pkt_size = kmalloc(32 * usbvision->num_alt, GFP_KERNEL); if (usbvision->alt_max_pkt_size == NULL) { dev_err(&intf->dev, "usbvision: out of memory!\n"); + usbvision_release(usbvision); return -ENOMEM; } -- 1.8.1.2 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] ath9k_htc: fix data race between request_firmware_nowait() callback and suspend()
ath9k_hif_usb_probe() requests firmware asynchronically and there is some initialization postponed till firmware is ready. In particular, ath9k_hif_usb_firmware_cb() callback initializes hif_dev->tx.tx_buf and hif_dev->tx.tx_pending lists. At the same time, ath9k_hif_usb_suspend() iterates that lists through ath9k_hif_usb_dealloc_urbs(). If suspend happens before request_firmware_nowait() callback is called, it can lead to oops. Similar issue could be in ath9k_hif_usb_disconnect(), but it is prevented using hif_dev->fw_done completion and HIF_USB_READY flag. The patch extends this approach to suspend() as well. Found by Linux Driver Verification project (linuxtesting.org). Signed-off-by: Alexey Khoroshilov --- drivers/net/wireless/ath/ath9k/hif_usb.c | 9 ++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.c b/drivers/net/wireless/ath/ath9k/hif_usb.c index f5dda84..fcd9aa5 100644 --- a/drivers/net/wireless/ath/ath9k/hif_usb.c +++ b/drivers/net/wireless/ath/ath9k/hif_usb.c @@ -1076,7 +1076,7 @@ static void ath9k_hif_usb_firmware_fail(struct hif_device_usb *hif_dev) struct device *dev = &hif_dev->udev->dev; struct device *parent = dev->parent; - complete(&hif_dev->fw_done); + complete_all(&hif_dev->fw_done); if (parent) device_lock(parent); @@ -1125,7 +1125,7 @@ static void ath9k_hif_usb_firmware_cb(const struct firmware *fw, void *context) release_firmware(fw); hif_dev->flags |= HIF_USB_READY; - complete(&hif_dev->fw_done); + complete_all(&hif_dev->fw_done); return; @@ -1310,7 +1310,10 @@ static int ath9k_hif_usb_suspend(struct usb_interface *interface, if (!(hif_dev->flags & HIF_USB_START)) ath9k_htc_suspend(hif_dev->htc_handle); - ath9k_hif_usb_dealloc_urbs(hif_dev); + wait_for_completion(&hif_dev->fw_done); + + if (hif_dev->flags & HIF_USB_READY) + ath9k_hif_usb_dealloc_urbs(hif_dev); return 0; } -- 1.8.1.2 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] [media] hdpvr: fix iteration over uninitialized lists in hdpvr_probe()
free_buff_list and rec_buff_list are initialized in the middle of hdpvr_probe(), but if something bad happens before that, error handling code calls hdpvr_delete(), which contains iteration over the lists (via hdpvr_free_buffers()). The patch moves the lists initialization to the beginning and by the way fixes goto label in error handling of registering videodev. Found by Linux Driver Verification project (linuxtesting.org). Signed-off-by: Alexey Khoroshilov --- drivers/media/usb/hdpvr/hdpvr-core.c | 11 ++- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/drivers/media/usb/hdpvr/hdpvr-core.c b/drivers/media/usb/hdpvr/hdpvr-core.c index 8247c19..77d7b7f 100644 --- a/drivers/media/usb/hdpvr/hdpvr-core.c +++ b/drivers/media/usb/hdpvr/hdpvr-core.c @@ -311,6 +311,11 @@ static int hdpvr_probe(struct usb_interface *interface, dev->workqueue = 0; + /* init video transfer queues first of all */ + /* to prevent oops in hdpvr_delete() on error paths */ + INIT_LIST_HEAD(&dev->free_buff_list); + INIT_LIST_HEAD(&dev->rec_buff_list); + /* register v4l2_device early so it can be used for printks */ if (v4l2_device_register(&interface->dev, &dev->v4l2_dev)) { dev_err(&interface->dev, "v4l2_device_register failed\n"); @@ -333,10 +338,6 @@ static int hdpvr_probe(struct usb_interface *interface, if (!dev->workqueue) goto error; - /* init video transfer queues */ - INIT_LIST_HEAD(&dev->free_buff_list); - INIT_LIST_HEAD(&dev->rec_buff_list); - dev->options = hdpvr_default_options; if (default_video_input < HDPVR_VIDEO_INPUTS) @@ -413,7 +414,7 @@ static int hdpvr_probe(struct usb_interface *interface, video_nr[atomic_inc_return(&dev_nr)]); if (retval < 0) { v4l2_err(&dev->v4l2_dev, "registering videodev failed\n"); - goto error; + goto reg_fail; } /* let the user know what node this device is now attached to */ -- 1.8.1.2 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] SUNRPC/cache: add module_put() on error path in cache_open()
If kmalloc() fails in cache_open(), module cd->owner left locked. The patch adds module_put(cd->owner) on this path. Found by Linux Driver Verification project (linuxtesting.org). Signed-off-by: Alexey Khoroshilov --- net/sunrpc/cache.c |4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/net/sunrpc/cache.c b/net/sunrpc/cache.c index 25d58e76..1d3c514 100644 --- a/net/sunrpc/cache.c +++ b/net/sunrpc/cache.c @@ -986,8 +986,10 @@ static int cache_open(struct inode *inode, struct file *filp, nonseekable_open(inode, filp); if (filp->f_mode & FMODE_READ) { rp = kmalloc(sizeof(*rp), GFP_KERNEL); - if (!rp) + if (!rp) { + module_put(cd->owner); return -ENOMEM; + } rp->offset = 0; rp->q.reader = 1; atomic_inc(&cd->readers); -- 1.7.9.5 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] via-ircc: don't return zero if via_ircc_open() failed
If via_ircc_open() fails, data structures of the driver left uninitialized, but probe (via_init_one()) returns zero. That can lead to null pointer dereference in via_remove_one(), since it does not check drvdata for NULL. The patch implements proper error code propagation. Found by Linux Driver Verification project (linuxtesting.org). Signed-off-by: Alexey Khoroshilov --- drivers/net/irda/via-ircc.c | 6 ++ 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/net/irda/via-ircc.c b/drivers/net/irda/via-ircc.c index 51f2bc3..2dcc60f 100644 --- a/drivers/net/irda/via-ircc.c +++ b/drivers/net/irda/via-ircc.c @@ -210,8 +210,7 @@ static int via_init_one(struct pci_dev *pcidev, const struct pci_device_id *id) pci_write_config_byte(pcidev,0x42,(bTmp | 0xf0)); pci_write_config_byte(pcidev,0x5a,0xc0); WriteLPCReg(0x28, 0x70 ); - if (via_ircc_open(pcidev, &info, 0x3076) == 0) - rc=0; + rc = via_ircc_open(pcidev, &info, 0x3076); } else rc = -ENODEV; //IR not turn on } else { //Not VT1211 @@ -249,8 +248,7 @@ static int via_init_one(struct pci_dev *pcidev, const struct pci_device_id *id) info.irq=FirIRQ; info.dma=FirDRQ1; info.dma2=FirDRQ0; - if (via_ircc_open(pcidev, &info, 0x3096) == 0) - rc=0; + rc = via_ircc_open(pcidev, &info, 0x3096); } else rc = -ENODEV; //IR not turn on ! }//Not VT1211 -- 1.8.1.2 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] [media] dvb_demux: fix deadlock in dmx_section_feed_release_filter()
dmx_section_feed_release_filter() locks dvbdmx->mutex and if the feed is still filtering, it calls feed->stop_filtering(feed). stop_filtering() is implemented by dmx_section_feed_stop_filtering() that first of all try to lock the same mutex: dvbdmx->mutex. That leads to a deadlock. It does not happen often in practice because all callers of release_filter() stop filtering by themselves. So the problem can happen in case of race condition only. The patch proposes to unlock dvbdmx->mutex before call feed->stop_filtering(feed) and recheck feed->is_filtering after reacquiring mutex. Found by Linux Driver Verification project (linuxtesting.org). Signed-off-by: Alexey Khoroshilov --- drivers/media/dvb-core/dvb_demux.c | 5 - 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/media/dvb-core/dvb_demux.c b/drivers/media/dvb-core/dvb_demux.c index 3485655..9d517af 100644 --- a/drivers/media/dvb-core/dvb_demux.c +++ b/drivers/media/dvb-core/dvb_demux.c @@ -1027,8 +1027,11 @@ static int dmx_section_feed_release_filter(struct dmx_section_feed *feed, return -EINVAL; } - if (feed->is_filtering) + while (feed->is_filtering) { + mutex_unlock(&dvbdmx->mutex); feed->stop_filtering(feed); + mutex_lock(&dvbdmx->mutex); + } spin_lock_irq(&dvbdmx->lock); f = dvbdmxfeed->filter; -- 1.8.1.2 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] can: usb_8dev: fix urb leak on failure path in usb_8dev_start()
If usb_8dev_start() fails to submit urb, it unanchors the urb but forgets to free it. Found by Linux Driver Verification project (linuxtesting.org). Signed-off-by: Alexey Khoroshilov --- drivers/net/can/usb/usb_8dev.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/can/usb/usb_8dev.c b/drivers/net/can/usb/usb_8dev.c index cbd388e..8becd3d 100644 --- a/drivers/net/can/usb/usb_8dev.c +++ b/drivers/net/can/usb/usb_8dev.c @@ -779,6 +779,7 @@ static int usb_8dev_start(struct usb_8dev_priv *priv) usb_unanchor_urb(urb); usb_free_coherent(priv->udev, RX_BUFFER_SIZE, buf, urb->transfer_dma); + usb_free_urb(urb); break; } -- 1.8.1.2 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] libceph: fix deadlock in ceph_build_auth()
ceph_build_auth() locks ac->mutex and then calls ceph_auth_build_hello() that locks the same mutex, i.e. bring itself to deadlock. The patch moves actual code from ceph_auth_build_hello() to ceph_build_hello_auth_request() that should be called with ac->mutex held and makes ceph_build_auth() calling it. ceph_auth_build_hello() is left with untouched semantics as a wrapper around ceph_build_hello_auth_request(). Found by Linux Driver Verification project (linuxtesting.org). Signed-off-by: Alexey Khoroshilov --- net/ceph/auth.c | 17 + 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/net/ceph/auth.c b/net/ceph/auth.c index 6b923bc..59594a6 100644 --- a/net/ceph/auth.c +++ b/net/ceph/auth.c @@ -98,14 +98,14 @@ int ceph_entity_name_encode(const char *name, void **p, void *end) * Initiate protocol negotiation with monitor. Include entity name * and list supported protocols. */ -int ceph_auth_build_hello(struct ceph_auth_client *ac, void *buf, size_t len) +static int ceph_build_hello_auth_request(struct ceph_auth_client *ac, +void *buf, size_t len) { struct ceph_mon_request_header *monhdr = buf; void *p = monhdr + 1, *end = buf + len, *lenp; int i, num; int ret; - mutex_lock(&ac->mutex); dout("auth_build_hello\n"); monhdr->have_version = 0; monhdr->session_mon = cpu_to_le16(-1); @@ -133,7 +133,6 @@ int ceph_auth_build_hello(struct ceph_auth_client *ac, void *buf, size_t len) ceph_encode_32(&lenp, p - lenp - sizeof(u32)); ret = p - buf; out: - mutex_unlock(&ac->mutex); return ret; bad: @@ -141,6 +140,16 @@ bad: goto out; } +int ceph_auth_build_hello(struct ceph_auth_client *ac, void *buf, size_t len) +{ + int ret; + + mutex_lock(&ac->mutex); + ret = ceph_build_hello_auth_request(ac, buf, len); + mutex_unlock(&ac->mutex); + return ret; +} + static int ceph_build_auth_request(struct ceph_auth_client *ac, void *msg_buf, size_t msg_len) { @@ -260,7 +269,7 @@ int ceph_build_auth(struct ceph_auth_client *ac, mutex_lock(&ac->mutex); if (!ac->protocol) - ret = ceph_auth_build_hello(ac, msg_buf, msg_len); + ret = ceph_build_hello_auth_request(ac, msg_buf, msg_len); else if (ac->ops->should_authenticate(ac)) ret = ceph_build_auth_request(ac, msg_buf, msg_len); mutex_unlock(&ac->mutex); -- 1.8.1.2 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH] usb: gadget: mv_u3d_core: fix violation of locking discipline in mv_u3d_ep_disable()
On 07/29/2013 04:52 PM, Felipe Balbi wrote: > Hi, > > On Fri, Jul 26, 2013 at 07:26:05PM +0400, Alexey Khoroshilov wrote: >> On 07/25/2013 09:30 PM, Felipe Balbi wrote: >>> On Wed, Jul 24, 2013 at 12:20:17AM +0400, Alexey Khoroshilov wrote: >>>> mv_u3d_nuke() expects to be calles with ep->u3d->lock held, >>>> because mv_u3d_done() does. But mv_u3d_ep_disable() calls it >>>> without lock that can lead to unpleasant consequences. >>>> >>>> Found by Linux Driver Verification project (linuxtesting.org). >>>> >>>> Signed-off-by: Alexey Khoroshilov >>> which commit introduced the bug ? Which kernels are affected by this bug ? >> The bug is present from the very beginning: commit 3d4eb9d of 15 June 2012. >> So it is in the mainline since v3.5. > Alright, do you want to have the same fix in stable kernels ? Is it > necessary at all or do we consider it 'never worked before' and send it > in the next merge window ? It is a tricky point. From one point of view it 'never worked before', but as far as the bug leads to a data race with unpredictable consequences I would prefer to have it fixed within 3.11 timeframe. -- Alexey -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] usb: gadget: amd5536udc: unconditionally use GFP_ATOMIC in udc_queue()
As far as prep_dma() is called with spinlock held, we have to pass GFP_ATOMIC regardless of gfp argument. Found by Linux Driver Verification project (linuxtesting.org). Signed-off-by: Alexey Khoroshilov --- drivers/usb/gadget/amd5536udc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/usb/gadget/amd5536udc.c b/drivers/usb/gadget/amd5536udc.c index f52dcfe..a9a4346 100644 --- a/drivers/usb/gadget/amd5536udc.c +++ b/drivers/usb/gadget/amd5536udc.c @@ -1122,7 +1122,7 @@ udc_queue(struct usb_ep *usbep, struct usb_request *usbreq, gfp_t gfp) goto finished; } if (ep->dma) { - retval = prep_dma(ep, req, gfp); + retval = prep_dma(ep, req, GFP_ATOMIC); if (retval != 0) goto finished; /* write desc pointer to enable DMA */ @@ -1190,7 +1190,7 @@ udc_queue(struct usb_ep *usbep, struct usb_request *usbreq, gfp_t gfp) * for PPB modes, because of chain creation reasons */ if (ep->in) { - retval = prep_dma(ep, req, gfp); + retval = prep_dma(ep, req, GFP_ATOMIC); if (retval != 0) goto finished; } -- 1.8.1.2 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] hostap: do not return positive number on failure path in prism2_open()
prism2_open() as an .ndo_open handler should not return positive numbers in case of failure, but it does return 1 in a couple of places. Found by Linux Driver Verification project (linuxtesting.org). Signed-off-by: Alexey Khoroshilov --- drivers/net/wireless/hostap/hostap_main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/hostap/hostap_main.c b/drivers/net/wireless/hostap/hostap_main.c index 15f0fad..e4f56ad 100644 --- a/drivers/net/wireless/hostap/hostap_main.c +++ b/drivers/net/wireless/hostap/hostap_main.c @@ -667,7 +667,7 @@ static int prism2_open(struct net_device *dev) if (local->no_pri) { printk(KERN_DEBUG "%s: could not set interface UP - no PRI " "f/w\n", dev->name); - return 1; + return -ENODEV; } if ((local->func->card_present && !local->func->card_present(local)) || @@ -682,7 +682,7 @@ static int prism2_open(struct net_device *dev) printk(KERN_WARNING "%s: could not enable MAC port\n", dev->name); prism2_close(dev); - return 1; + return -ENODEV; } if (!local->dev_enabled) prism2_callback(local, PRISM2_CALLBACK_ENABLE); -- 1.8.1.2 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH] hostap: do not return positive number on failure path in prism2_open()
Please ignore this mail, there is a misprint in signed-off line. I will resend the patch. On 08/05/2013 07:02 AM, Alexey Khoroshilov wrote: > prism2_open() as an .ndo_open handler should not return positive numbers > in case of failure, but it does return 1 in a couple of places. > > Found by Linux Driver Verification project (linuxtesting.org). > > Signed-off-by: Alexey Khoroshilov > --- > drivers/net/wireless/hostap/hostap_main.c | 4 ++-- > 1 file changed, 2 insertions(+), 2 deletions(-) > > diff --git a/drivers/net/wireless/hostap/hostap_main.c > b/drivers/net/wireless/hostap/hostap_main.c > index 15f0fad..e4f56ad 100644 > --- a/drivers/net/wireless/hostap/hostap_main.c > +++ b/drivers/net/wireless/hostap/hostap_main.c > @@ -667,7 +667,7 @@ static int prism2_open(struct net_device *dev) > if (local->no_pri) { > printk(KERN_DEBUG "%s: could not set interface UP - no PRI " > "f/w\n", dev->name); > - return 1; > + return -ENODEV; > } > > if ((local->func->card_present && !local->func->card_present(local)) || > @@ -682,7 +682,7 @@ static int prism2_open(struct net_device *dev) > printk(KERN_WARNING "%s: could not enable MAC port\n", > dev->name); > prism2_close(dev); > - return 1; > + return -ENODEV; > } > if (!local->dev_enabled) > prism2_callback(local, PRISM2_CALLBACK_ENABLE); -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] hostap: do not return positive number on failure path in prism2_open()
prism2_open() as an .ndo_open handler should not return positive numbers in case of failure, but it does return 1 in a couple of places. Found by Linux Driver Verification project (linuxtesting.org). Signed-off-by: Alexey Khoroshilov --- drivers/net/wireless/hostap/hostap_main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/hostap/hostap_main.c b/drivers/net/wireless/hostap/hostap_main.c index 15f0fad..e4f56ad 100644 --- a/drivers/net/wireless/hostap/hostap_main.c +++ b/drivers/net/wireless/hostap/hostap_main.c @@ -667,7 +667,7 @@ static int prism2_open(struct net_device *dev) if (local->no_pri) { printk(KERN_DEBUG "%s: could not set interface UP - no PRI " "f/w\n", dev->name); - return 1; + return -ENODEV; } if ((local->func->card_present && !local->func->card_present(local)) || @@ -682,7 +682,7 @@ static int prism2_open(struct net_device *dev) printk(KERN_WARNING "%s: could not enable MAC port\n", dev->name); prism2_close(dev); - return 1; + return -ENODEV; } if (!local->dev_enabled) prism2_callback(local, PRISM2_CALLBACK_ENABLE); -- 1.8.1.2 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH] hostap: do not return positive number on failure path in prism2_open()
On 08/05/2013 07:33 AM, Joe Perches wrote: > On Mon, 2013-08-05 at 07:18 +0400, Alexey Khoroshilov wrote: >> prism2_open() as an .ndo_open handler should not return positive numbers >> in case of failure, but it does return 1 in a couple of places. >> >> Found by Linux Driver Verification project (linuxtesting.org). > How? > > http://linuxtesting.org/project/ldv > http://linuxtesting.org/results/ldv > > Shows defects and patches to fix them, but not any script > used to find it. There is a link to build instructions there: http://forge.ispras.ru/projects/ldv/wiki/Downloading_and_Building_LDV Currently it requires some efforts to install all the dependencies, the simplest way is to use puppet script for Ubuntu 12.04 that you can find in the repository. -- Alexey -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] [media] gspca: fix dev_open() error path
If v4l2_fh_open() fails in dev_open(), gspca_dev->module left locked. The patch adds module_put(gspca_dev->module) on this path. Found by Linux Driver Verification project (linuxtesting.org). Signed-off-by: Alexey Khoroshilov --- drivers/media/usb/gspca/gspca.c | 6 +- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/media/usb/gspca/gspca.c b/drivers/media/usb/gspca/gspca.c index b7ae872..048507b 100644 --- a/drivers/media/usb/gspca/gspca.c +++ b/drivers/media/usb/gspca/gspca.c @@ -1266,6 +1266,7 @@ static void gspca_release(struct v4l2_device *v4l2_device) static int dev_open(struct file *file) { struct gspca_dev *gspca_dev = video_drvdata(file); + int ret; PDEBUG(D_STREAM, "[%s] open", current->comm); @@ -1273,7 +1274,10 @@ static int dev_open(struct file *file) if (!try_module_get(gspca_dev->module)) return -ENODEV; - return v4l2_fh_open(file); + ret = v4l2_fh_open(file); + if (ret) + module_put(gspca_dev->module); + return ret; } static int dev_close(struct file *file) -- 1.8.1.2 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] usb: gadget: mv_u3d_core: fix violation of locking discipline in mv_u3d_ep_disable()
mv_u3d_nuke() expects to be calles with ep->u3d->lock held, because mv_u3d_done() does. But mv_u3d_ep_disable() calls it without lock that can lead to unpleasant consequences. Found by Linux Driver Verification project (linuxtesting.org). Signed-off-by: Alexey Khoroshilov --- drivers/usb/gadget/mv_u3d_core.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/usb/gadget/mv_u3d_core.c b/drivers/usb/gadget/mv_u3d_core.c index 07fdb3e..650847d 100644 --- a/drivers/usb/gadget/mv_u3d_core.c +++ b/drivers/usb/gadget/mv_u3d_core.c @@ -645,6 +645,7 @@ static int mv_u3d_ep_disable(struct usb_ep *_ep) struct mv_u3d_ep *ep; struct mv_u3d_ep_context *ep_context; u32 epxcr, direction; + unsigned long flags; if (!_ep) return -EINVAL; @@ -661,7 +662,9 @@ static int mv_u3d_ep_disable(struct usb_ep *_ep) direction = mv_u3d_ep_dir(ep); /* nuke all pending requests (does flush) */ + spin_lock_irqsave(&u3d->lock, flags); mv_u3d_nuke(ep, -ESHUTDOWN); + spin_unlock_irqrestore(&u3d->lock, flags); /* Disable the endpoint for Rx or Tx and reset the endpoint type */ if (direction == MV_U3D_EP_DIR_OUT) { -- 1.8.1.2 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH] usb: gadget: mv_u3d_core: fix violation of locking discipline in mv_u3d_ep_disable()
Hi Felipe, On 07/25/2013 09:30 PM, Felipe Balbi wrote: > On Wed, Jul 24, 2013 at 12:20:17AM +0400, Alexey Khoroshilov wrote: >> mv_u3d_nuke() expects to be calles with ep->u3d->lock held, >> because mv_u3d_done() does. But mv_u3d_ep_disable() calls it >> without lock that can lead to unpleasant consequences. >> >> Found by Linux Driver Verification project (linuxtesting.org). >> >> Signed-off-by: Alexey Khoroshilov > which commit introduced the bug ? Which kernels are affected by this bug ? The bug is present from the very beginning: commit 3d4eb9d of 15 June 2012. So it is in the mainline since v3.5. -- Alexey -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] drbd: add module_put() on error path in drbd_proc_open()
If single_open() fails in drbd_proc_open(), module refcount is left incremented. The patch adds module_put() on the error path. Found by Linux Driver Verification project (linuxtesting.org). Signed-off-by: Alexey Khoroshilov --- drivers/block/drbd/drbd_proc.c | 10 -- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/drivers/block/drbd/drbd_proc.c b/drivers/block/drbd/drbd_proc.c index 56672a6..30fe0a5 100644 --- a/drivers/block/drbd/drbd_proc.c +++ b/drivers/block/drbd/drbd_proc.c @@ -313,8 +313,14 @@ static int drbd_seq_show(struct seq_file *seq, void *v) static int drbd_proc_open(struct inode *inode, struct file *file) { - if (try_module_get(THIS_MODULE)) - return single_open(file, drbd_seq_show, PDE(inode)->data); + int err; + + if (try_module_get(THIS_MODULE)) { + err = single_open(file, drbd_seq_show, PDE(inode)->data); + if (err) + module_put(THIS_MODULE); + return err; + } return -ENODEV; } -- 1.7.9.5 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 0/2] ext4: deadlocks after allocation failure in ext4_init_io_end()
Hi, Ted! Our tests for ext4 with targeted fault injection were stalled in Uninterruptible Sleep State when they simulate a memory allocation failure in ext4_init_io_end() while it is called from mpage_da_submit_io() or ext4_writepage(). It looks like the problems are that pages left locked after failure handling. I am not completely sure that my patches take into account all required aspects, but the tests are passed if the patches are applied. Please find below syslog excerpt for the first issue. Found by Linux File System Verification project (linuxtesting.org/spruce). -- Alexey Khoroshilov Linux Verification Center, ISPRAS web: http://linuxtesting.org [ 1212.454601] Failure is simulated in the following location [ 1212.454675] Call Trace: [ 1212.454681] [] dump_stack+0x19/0x1b [ 1212.454687] [] warn_slowpath_common+0x70/0xa0 [ 1212.454691] [] ? indicator_simulate+0x29/0x1a0 [kedr_fsim_indicator_common] [ 1212.454701] [] ? ext4_init_io_end+0x23/0x50 [ext4] [ 1212.454705] [] warn_slowpath_fmt+0x46/0x50 [ 1212.454710] [] ? kedr_fsim_point_simulate+0x7e/0xa0 [kedr_fault_simulation] [ 1212.454715] [] ? kedr_fsim_point_simulate+0x5/0xa0 [kedr_fault_simulation] [ 1212.454719] [] kedr_repl_kmem_cache_alloc+0x7a/0xb0 [kedr_fsim_cmm] [ 1212.454727] [] ? ext4_init_io_end+0x23/0x50 [ext4] [ 1212.454732] [] kedr_intermediate_func_kmem_cache_alloc+0x73/0xd0 [kedr_lc_common_mm] [ 1212.454740] [] ? ext4_init_io_end+0x23/0x50 [ext4] [ 1212.454746] [] ext4_init_io_end+0x23/0x50 [ext4] [ 1212.454753] [] mpage_da_submit_io+0x6f/0x380 [ext4] [ 1212.454762] [] ? __ext4_handle_dirty_metadata+0xab/0x140 [ext4] [ 1212.454769] [] ? jbd2_journal_get_write_access+0x3b/0x50 [jbd2] [ 1212.454777] [] ? ext4_mark_iloc_dirty+0x468/0x660 [ext4] [ 1212.454784] [] ? ext4_mark_inode_dirty+0x9a/0x270 [ext4] [ 1212.454790] [] ? mpage_da_map_and_submit+0x1fc/0x430 [ext4] [ 1212.454798] [] mpage_da_map_and_submit+0x10e/0x430 [ext4] [ 1212.454804] [] ? ext4_da_writepages+0x377/0x6a0 [ext4] [ 1212.454811] [] ext4_da_writepages+0x3cc/0x6a0 [ext4] [ 1212.454815] [] ? __do_fault+0x14a/0x470 [ 1212.454820] [] do_writepages+0x23/0x40 [ 1212.454824] [] __filemap_fdatawrite_range+0x59/0x60 [ 1212.454828] [] filemap_write_and_wait_range+0x3a/0x80 [ 1212.454835] [] ext4_punch_hole+0x1f5/0x5c0 [ext4] [ 1212.454839] [] ? __do_page_fault+0x108/0x550 [ 1212.454843] [] ? do_fallocate+0x101/0x190 [ 1212.454847] [] ? do_fallocate+0x101/0x190 [ 1212.454855] [] ext4_fallocate+0x30c/0x5d0 [ext4] [ 1212.454858] [] ? do_fallocate+0x101/0x190 [ 1212.454862] [] ? __fput+0x16d/0x2e0 [ 1212.454865] [] do_fallocate+0x117/0x190 [ 1212.454869] [] SyS_fallocate+0x57/0x90 [ 1212.454877] [] system_call_fastpath+0x16/0x1b [ 1212.454880] ---[ end trace 16f55656139fb9de ]--- [ 1443.148536] INFO: task flush-8:16:11233 blocked for more than 120 seconds. [ 1443.148628] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message. [ 1443.148646] flush-8:16 D 8112d160 0 11233 2 0x [ 1443.148669] 88002fe5d768 0046 880082f8b4b8 [ 1443.148692] 8800300b9fb0 88002fe5dfd8 88002fe5dfd8 88002fe5dfd8 [ 1443.148712] 88002ed75f10 8800300b9fb0 88002fe5d768 880082a144e0 [ 1443.148733] Call Trace: [ 1443.148764] [] ? __lock_page+0x70/0x70 [ 1443.148770] [] schedule+0x29/0x70 [ 1443.148773] [] io_schedule+0x8f/0xd0 [ 1443.148777] [] sleep_on_page+0xe/0x20 [ 1443.148781] [] __wait_on_bit_lock+0x5a/0xc0 [ 1443.148785] [] ? find_get_pages_tag+0x2e/0x1e0 [ 1443.148790] [] ? __block_write_full_page+0x211/0x390 [ 1443.148794] [] __lock_page+0x67/0x70 [ 1443.148799] [] ? autoremove_wake_function+0x50/0x50 [ 1443.148809] [] ext4_num_dirty_pages.isra.53+0x1fe/0x210 [ext4] [ 1443.148814] [] ? pagevec_lookup_tag+0x25/0x40 [ 1443.148818] [] ? write_cache_pages+0x144/0x4e0 [ 1443.148825] [] ext4_da_writepages+0x63d/0x6a0 [ext4] [ 1443.148829] [] ? set_page_dirty_lock+0x70/0x70 [ 1443.148833] [] ? __writeback_single_inode+0x63/0x310 [ 1443.148837] [] ? __writeback_single_inode+0x63/0x310 [ 1443.148841] [] ? writeback_sb_inodes+0x13c/0x550 [ 1443.148845] [] do_writepages+0x23/0x40 [ 1443.148849] [] __writeback_single_inode+0x45/0x310 [ 1443.148853] [] writeback_sb_inodes+0x2c8/0x550 [ 1443.148856] [] __writeback_inodes_wb+0x9e/0xd0 [ 1443.148860] [] wb_writeback+0x34b/0x370 [ 1443.148864] [] ? get_nr_inodes+0x5e/0xb0 [ 1443.148868] [] wb_check_old_data_flush+0x9f/0xb0 [ 1443.148872] [] wb_do_writeback+0x179/0x200 [ 1443.148877] [] ? debug_object_assert_init+0x7a/0xf0 [ 1443.148881] [] ? del_timer+0x2b/0x80 [ 1443.148887] [] bdi_writeback_thread+0xac/0x300 [ 1443.148894] [] ? wb_do_writeback+0x200/0x200 [ 1443.148900] [] kthread+0xea/0xf0 [ 1443.148905] [] ? flush_kthread_worker+0x150/0x150 [ 1443.148919] INFO: task ext4lazyinit:2065 blocked for more than 120 seconds. [ 1443.148921] "
[PATCH 1/2] ext4: do not left pages locked in mpage_da_submit_io()
If call to ext4_init_io_end() is failed under memory pressure, mpage_da_submit_io() just returns -ENOMEM and left all pages from the extent locked. That leads to a deadlock as soon as callers of mpage_da_submit_io() expect it unlocks all the pages. Found by Linux File System Verification project (linuxtesting.org). Signed-off-by: Alexey Khoroshilov --- fs/ext4/inode.c | 16 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index 793d44b..aeca439 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -1489,8 +1489,9 @@ static int mpage_da_submit_io(struct mpage_da_data *mpd, BUG_ON(mpd->next_page <= mpd->first_page); ext4_io_submit_init(&io_submit, mpd->wbc); io_submit.io_end = ext4_init_io_end(inode, GFP_NOFS); + /* In case of error we still have to unlock pages */ if (!io_submit.io_end) - return -ENOMEM; + ret = -ENOMEM; /* * We need to start from the first_page to the next_page - 1 * to make sure we also write the mapped dirty buffer_heads. @@ -1512,6 +1513,11 @@ static int mpage_da_submit_io(struct mpage_da_data *mpd, index = page->index; if (index > end) break; + if (!io_submit.io_end) { + unlock_page(page); + index++; + continue; + } if (index == size >> PAGE_CACHE_SHIFT) len = size & ~PAGE_CACHE_MASK; @@ -1577,9 +1583,11 @@ static int mpage_da_submit_io(struct mpage_da_data *mpd, } pagevec_release(&pvec); } - ext4_io_submit(&io_submit); - /* Drop io_end reference we got from init */ - ext4_put_io_end_defer(io_submit.io_end); + if (io_submit.io_end) { + ext4_io_submit(&io_submit); + /* Drop io_end reference we got from init */ + ext4_put_io_end_defer(io_submit.io_end); + } return ret; } -- 1.7.9.5 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 2/2] ext4: do not left pages locked in ext4_writepage()
If call to ext4_init_io_end() is failed under memory pressure, ext4_writepage() calls redirty_page_for_writepage() but left the page locked. That leads to a deadlock since it is expected the page is unlocked after writepage(). Found by Linux File System Verification project (linuxtesting.org). Signed-off-by: Alexey Khoroshilov --- fs/ext4/inode.c |1 + 1 file changed, 1 insertion(+) diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index aeca439..c6bc999 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -2250,6 +2250,7 @@ static int ext4_writepage(struct page *page, io_submit.io_end = ext4_init_io_end(inode, GFP_NOFS); if (!io_submit.io_end) { redirty_page_for_writepage(wbc, page); + unlock_page(page); return -ENOMEM; } ret = ext4_bio_write_page(&io_submit, page, len, wbc); -- 1.7.9.5 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH] hfs: add error checking for hfs_find_init()
Hi Vyacheslav, On 03/30/2013 03:35 PM, Vyacheslav Dubeyko wrote: Found by Linux Driver Verification project (linuxtesting.org). Signed-off-by: Alexey Khoroshilov --- fs/hfs/catalog.c | 12 +--- fs/hfs/dir.c |8 ++-- fs/hfs/extent.c | 48 +--- fs/hfs/hfs_fs.h |2 +- fs/hfs/inode.c | 11 +-- fs/hfs/super.c |4 +++- 6 files changed, 61 insertions(+), 24 deletions(-) diff --git a/fs/hfs/catalog.c b/fs/hfs/catalog.c index 424b033..9569b39 100644 --- a/fs/hfs/catalog.c +++ b/fs/hfs/catalog.c @@ -92,7 +92,9 @@ int hfs_cat_create(u32 cnid, struct inode *dir, struct qstr *str, struct inode * return -ENOSPC; sb = dir->i_sb; - hfs_find_init(HFS_SB(sb)->cat_tree, &fd); + err = hfs_find_init(HFS_SB(sb)->cat_tree, &fd); + if (err) + return err; hfs_cat_build_key(sb, fd.search_key, cnid, NULL); entry_size = hfs_cat_build_thread(sb, &entry, S_ISDIR(inode->i_mode) ? @@ -214,7 +216,9 @@ int hfs_cat_delete(u32 cnid, struct inode *dir, struct qstr *str) dprint(DBG_CAT_MOD, "delete_cat: %s,%u\n", str ? str->name : NULL, cnid); sb = dir->i_sb; - hfs_find_init(HFS_SB(sb)->cat_tree, &fd); + res = hfs_find_init(HFS_SB(sb)->cat_tree, &fd); + if (res) + return res; hfs_cat_build_key(sb, fd.search_key, dir->i_ino, str); res = hfs_brec_find(&fd); @@ -281,7 +285,9 @@ int hfs_cat_move(u32 cnid, struct inode *src_dir, struct qstr *src_name, dprint(DBG_CAT_MOD, "rename_cat: %u - %lu,%s - %lu,%s\n", cnid, src_dir->i_ino, src_name->name, dst_dir->i_ino, dst_name->name); sb = src_dir->i_sb; - hfs_find_init(HFS_SB(sb)->cat_tree, &src_fd); + err = hfs_find_init(HFS_SB(sb)->cat_tree, &src_fd); + if (err) + return err; dst_fd = src_fd; /* find the old dir entry and read the data */ diff --git a/fs/hfs/dir.c b/fs/hfs/dir.c index 5f7f1ab..e1c8048 100644 --- a/fs/hfs/dir.c +++ b/fs/hfs/dir.c @@ -25,7 +25,9 @@ static struct dentry *hfs_lookup(struct inode *dir, struct dentry *dentry, struct inode *inode = NULL; int res; - hfs_find_init(HFS_SB(dir->i_sb)->cat_tree, &fd); + res = hfs_find_init(HFS_SB(dir->i_sb)->cat_tree, &fd); + if (res) + return ERR_PTR(res); hfs_cat_build_key(dir->i_sb, fd.search_key, dir->i_ino, &dentry->d_name); res = hfs_brec_read(&fd, &rec, sizeof(rec)); if (res) { @@ -63,7 +65,9 @@ static int hfs_readdir(struct file *filp, void *dirent, filldir_t filldir) if (filp->f_pos >= inode->i_size) return 0; - hfs_find_init(HFS_SB(sb)->cat_tree, &fd); + err = hfs_find_init(HFS_SB(sb)->cat_tree, &fd); + if (err) + return err; hfs_cat_build_key(sb, fd.search_key, inode->i_ino, NULL); err = hfs_brec_find(&fd); if (err) diff --git a/fs/hfs/extent.c b/fs/hfs/extent.c index a67955a..813447b 100644 --- a/fs/hfs/extent.c +++ b/fs/hfs/extent.c @@ -107,7 +107,7 @@ static u16 hfs_ext_lastblock(struct hfs_extent *ext) return be16_to_cpu(ext->block) + be16_to_cpu(ext->count); } -static void __hfs_ext_write_extent(struct inode *inode, struct hfs_find_data *fd) +static int __hfs_ext_write_extent(struct inode *inode, struct hfs_find_data *fd) { int res; @@ -116,26 +116,31 @@ static void __hfs_ext_write_extent(struct inode *inode, struct hfs_find_data *fd res = hfs_brec_find(fd); if (HFS_I(inode)->flags & HFS_FLG_EXT_NEW) { if (res != -ENOENT) - return; + return res; hfs_brec_insert(fd, HFS_I(inode)->cached_extents, sizeof(hfs_extent_rec)); HFS_I(inode)->flags &= ~(HFS_FLG_EXT_DIRTY|HFS_FLG_EXT_NEW); } else { if (res) - return; + return res; hfs_bnode_write(fd->bnode, HFS_I(inode)->cached_extents, fd->entryoffset, fd->entrylength); HFS_I(inode)->flags &= ~HFS_FLG_EXT_DIRTY; } + return 0; } As I see, this fix makes sense and for hfsplus also. Please, make it and for hfsplus. Sorry, I did not catch which fix do you mean. Could you please clarify it. Thank you, Alexey -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] tty: mxser: fix cycle termination condition in mxser_probe() and mxser_module_init()
There is a bug in resources deallocation code in mxser_probe() and mxser_module_init(). As soon as variable 'i' is unsigned int, cycle termination condition i >= 0 is always true. The patch fixes the issue. Signed-off-by: Alexey Khoroshilov --- drivers/tty/mxser.c |8 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/tty/mxser.c b/drivers/tty/mxser.c index 484b6a3..302909c 100644 --- a/drivers/tty/mxser.c +++ b/drivers/tty/mxser.c @@ -2643,9 +2643,9 @@ static int mxser_probe(struct pci_dev *pdev, mxvar_sdriver, brd->idx + i, &pdev->dev); if (IS_ERR(tty_dev)) { retval = PTR_ERR(tty_dev); - for (i--; i >= 0; i--) + for (; i > 0; i--) tty_unregister_device(mxvar_sdriver, - brd->idx + i); + brd->idx + i - 1); goto err_relbrd; } } @@ -2751,9 +2751,9 @@ static int __init mxser_module_init(void) tty_dev = tty_port_register_device(&brd->ports[i].port, mxvar_sdriver, brd->idx + i, NULL); if (IS_ERR(tty_dev)) { - for (i--; i >= 0; i--) + for (; i > 0; i--) tty_unregister_device(mxvar_sdriver, - brd->idx + i); + brd->idx + i - 1); for (i = 0; i < brd->info->nports; i++) tty_port_destroy(&brd->ports[i].port); free_irq(brd->irq, brd); -- 1.7.9.5 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 1/2] hfsplus: add error propagation to __hfsplus_ext_write_extent()
__hfsplus_ext_write_extent() suppresses errors coming from hfs_brec_find(). The patch implements error code propagation. Signed-off-by: Alexey Khoroshilov --- fs/hfsplus/extents.c | 21 + 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/fs/hfsplus/extents.c b/fs/hfsplus/extents.c index a94f0f7..fed73f7 100644 --- a/fs/hfsplus/extents.c +++ b/fs/hfsplus/extents.c @@ -83,7 +83,7 @@ static u32 hfsplus_ext_lastblock(struct hfsplus_extent *ext) return be32_to_cpu(ext->start_block) + be32_to_cpu(ext->block_count); } -static void __hfsplus_ext_write_extent(struct inode *inode, +static int __hfsplus_ext_write_extent(struct inode *inode, struct hfs_find_data *fd) { struct hfsplus_inode_info *hip = HFSPLUS_I(inode); @@ -98,13 +98,13 @@ static void __hfsplus_ext_write_extent(struct inode *inode, res = hfs_brec_find(fd, hfs_find_rec_by_key); if (hip->extent_state & HFSPLUS_EXT_NEW) { if (res != -ENOENT) - return; + return res; hfs_brec_insert(fd, hip->cached_extents, sizeof(hfsplus_extent_rec)); hip->extent_state &= ~(HFSPLUS_EXT_DIRTY | HFSPLUS_EXT_NEW); } else { if (res) - return; + return res; hfs_bnode_write(fd->bnode, hip->cached_extents, fd->entryoffset, fd->entrylength); hip->extent_state &= ~HFSPLUS_EXT_DIRTY; @@ -117,11 +117,13 @@ static void __hfsplus_ext_write_extent(struct inode *inode, * to explicily mark the inode dirty, too. */ set_bit(HFSPLUS_I_EXT_DIRTY, &hip->flags); + + return 0; } static int hfsplus_ext_write_extent_locked(struct inode *inode) { - int res; + int res = 0; if (HFSPLUS_I(inode)->extent_state & HFSPLUS_EXT_DIRTY) { struct hfs_find_data fd; @@ -129,10 +131,10 @@ static int hfsplus_ext_write_extent_locked(struct inode *inode) res = hfs_find_init(HFSPLUS_SB(inode->i_sb)->ext_tree, &fd); if (res) return res; - __hfsplus_ext_write_extent(inode, &fd); + res = __hfsplus_ext_write_extent(inode, &fd); hfs_find_exit(&fd); } - return 0; + return res; } int hfsplus_ext_write_extent(struct inode *inode) @@ -175,8 +177,11 @@ static inline int __hfsplus_ext_cache_extent(struct hfs_find_data *fd, WARN_ON(!mutex_is_locked(&hip->extents_lock)); - if (hip->extent_state & HFSPLUS_EXT_DIRTY) - __hfsplus_ext_write_extent(inode, fd); + if (hip->extent_state & HFSPLUS_EXT_DIRTY) { + res = __hfsplus_ext_write_extent(inode, fd); + if (res) + return res; + } res = __hfsplus_ext_read_extent(fd, hip->cached_extents, inode->i_ino, block, HFSPLUS_IS_RSRC(inode) ? -- 1.7.9.5 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 2/2] hfsplus: add printk to log allocation failure in hfs_find_init()
Add printk to log allocation failure in hfs_find_init(), "so that there is a sign in dmesg when the error condition is triggered". (per Hin-Tak Leung request) Signed-off-by: Alexey Khoroshilov --- fs/hfsplus/bfind.c |4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/fs/hfsplus/bfind.c b/fs/hfsplus/bfind.c index d73c98d..067ddb5 100644 --- a/fs/hfsplus/bfind.c +++ b/fs/hfsplus/bfind.c @@ -18,8 +18,10 @@ int hfs_find_init(struct hfs_btree *tree, struct hfs_find_data *fd) fd->tree = tree; fd->bnode = NULL; ptr = kmalloc(tree->max_key_len * 2 + 4, GFP_KERNEL); - if (!ptr) + if (!ptr) { + printk(KERN_ERR "hfs: allocation failed in hfs_find_init()\n"); return -ENOMEM; + } fd->search_key = ptr; fd->key = ptr + tree->max_key_len + 2; dprint(DBG_BNODE_REFS, "find_init: %d (%p)\n", -- 1.7.9.5 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [patch] tty: mxser: forever loops on error
Hi Dan, Thank you for the patch. We are also trying to fix the issue: https://lkml.org/lkml/2013/2/19/29 https://lkml.org/lkml/2013/4/8/55 and the fix is finally in Greg's tty git tree since yesterday: git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty.git (tty-linus branch). Best regards, Alexey On 04/09/2013 09:18 AM, Dan Carpenter wrote: > There were a couple signedness bugs decrementing "i" which would lead to > a forever loops. > > I've made a couple other variables signed as well because they are all > related array offsets and it would be weird if they weren't the same > type. > > Signed-off-by: Dan Carpenter > > diff --git a/drivers/tty/mxser.c b/drivers/tty/mxser.c > index d996038..a095859 100644 > --- a/drivers/tty/mxser.c > +++ b/drivers/tty/mxser.c > @@ -2556,9 +2556,9 @@ static int mxser_probe(struct pci_dev *pdev, > { > #ifdef CONFIG_PCI > struct mxser_board *brd; > - unsigned int i, j; > unsigned long ioaddress; > struct device *tty_dev; > + int i, j; > int retval = -EINVAL; > > for (i = 0; i < MXSER_BOARDS; i++) > @@ -2700,7 +2700,7 @@ static int __init mxser_module_init(void) > { > struct mxser_board *brd; > struct device *tty_dev; > - unsigned int b, i, m; > + int b, i, m; > int retval; > > mxvar_sdriver = alloc_tty_driver(MXSER_PORTS + 1); > -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 1/2] hfs: add error checking for hfs_find_init()
hfs_find_init() may fail with ENOMEM, but there are places, where the returned value is not checked. The consequences can be very unpleasant, e.g. kfree uninitialized pointer and inappropriate mutex unlocking. The patch adds checks for errors in hfs_find_init(). Found by Linux Driver Verification project (linuxtesting.org). Signed-off-by: Alexey Khoroshilov --- fs/hfs/catalog.c | 12 +--- fs/hfs/dir.c |8 ++-- fs/hfs/extent.c | 48 +--- fs/hfs/hfs_fs.h |2 +- fs/hfs/inode.c | 11 +-- fs/hfs/super.c |4 +++- 6 files changed, 61 insertions(+), 24 deletions(-) diff --git a/fs/hfs/catalog.c b/fs/hfs/catalog.c index 424b033..9569b39 100644 --- a/fs/hfs/catalog.c +++ b/fs/hfs/catalog.c @@ -92,7 +92,9 @@ int hfs_cat_create(u32 cnid, struct inode *dir, struct qstr *str, struct inode * return -ENOSPC; sb = dir->i_sb; - hfs_find_init(HFS_SB(sb)->cat_tree, &fd); + err = hfs_find_init(HFS_SB(sb)->cat_tree, &fd); + if (err) + return err; hfs_cat_build_key(sb, fd.search_key, cnid, NULL); entry_size = hfs_cat_build_thread(sb, &entry, S_ISDIR(inode->i_mode) ? @@ -214,7 +216,9 @@ int hfs_cat_delete(u32 cnid, struct inode *dir, struct qstr *str) dprint(DBG_CAT_MOD, "delete_cat: %s,%u\n", str ? str->name : NULL, cnid); sb = dir->i_sb; - hfs_find_init(HFS_SB(sb)->cat_tree, &fd); + res = hfs_find_init(HFS_SB(sb)->cat_tree, &fd); + if (res) + return res; hfs_cat_build_key(sb, fd.search_key, dir->i_ino, str); res = hfs_brec_find(&fd); @@ -281,7 +285,9 @@ int hfs_cat_move(u32 cnid, struct inode *src_dir, struct qstr *src_name, dprint(DBG_CAT_MOD, "rename_cat: %u - %lu,%s - %lu,%s\n", cnid, src_dir->i_ino, src_name->name, dst_dir->i_ino, dst_name->name); sb = src_dir->i_sb; - hfs_find_init(HFS_SB(sb)->cat_tree, &src_fd); + err = hfs_find_init(HFS_SB(sb)->cat_tree, &src_fd); + if (err) + return err; dst_fd = src_fd; /* find the old dir entry and read the data */ diff --git a/fs/hfs/dir.c b/fs/hfs/dir.c index 5f7f1ab..e1c8048 100644 --- a/fs/hfs/dir.c +++ b/fs/hfs/dir.c @@ -25,7 +25,9 @@ static struct dentry *hfs_lookup(struct inode *dir, struct dentry *dentry, struct inode *inode = NULL; int res; - hfs_find_init(HFS_SB(dir->i_sb)->cat_tree, &fd); + res = hfs_find_init(HFS_SB(dir->i_sb)->cat_tree, &fd); + if (res) + return ERR_PTR(res); hfs_cat_build_key(dir->i_sb, fd.search_key, dir->i_ino, &dentry->d_name); res = hfs_brec_read(&fd, &rec, sizeof(rec)); if (res) { @@ -63,7 +65,9 @@ static int hfs_readdir(struct file *filp, void *dirent, filldir_t filldir) if (filp->f_pos >= inode->i_size) return 0; - hfs_find_init(HFS_SB(sb)->cat_tree, &fd); + err = hfs_find_init(HFS_SB(sb)->cat_tree, &fd); + if (err) + return err; hfs_cat_build_key(sb, fd.search_key, inode->i_ino, NULL); err = hfs_brec_find(&fd); if (err) diff --git a/fs/hfs/extent.c b/fs/hfs/extent.c index a67955a..813447b 100644 --- a/fs/hfs/extent.c +++ b/fs/hfs/extent.c @@ -107,7 +107,7 @@ static u16 hfs_ext_lastblock(struct hfs_extent *ext) return be16_to_cpu(ext->block) + be16_to_cpu(ext->count); } -static void __hfs_ext_write_extent(struct inode *inode, struct hfs_find_data *fd) +static int __hfs_ext_write_extent(struct inode *inode, struct hfs_find_data *fd) { int res; @@ -116,26 +116,31 @@ static void __hfs_ext_write_extent(struct inode *inode, struct hfs_find_data *fd res = hfs_brec_find(fd); if (HFS_I(inode)->flags & HFS_FLG_EXT_NEW) { if (res != -ENOENT) - return; + return res; hfs_brec_insert(fd, HFS_I(inode)->cached_extents, sizeof(hfs_extent_rec)); HFS_I(inode)->flags &= ~(HFS_FLG_EXT_DIRTY|HFS_FLG_EXT_NEW); } else { if (res) - return; + return res; hfs_bnode_write(fd->bnode, HFS_I(inode)->cached_extents, fd->entryoffset, fd->entrylength); HFS_I(inode)->flags &= ~HFS_FLG_EXT_DIRTY; } + return 0; } -void hfs_ext_write_extent(struct inode *inode) +int hfs_ext_write_extent(struct inode *inode) { struct hfs_find_data fd; + int res = 0; if (HFS_I(inode)->flags & HFS_FLG_EXT_DIRTY) { - hfs_find_init(HFS_SB(inode->i_sb)->ext_tree, &fd); - __hfs_ext_write_extent(inode, &
[PATCH 2/2] hfsplus: add error propagation to __hfsplus_ext_write_extent()
__hfsplus_ext_write_extent() suppresses errors coming from hfs_brec_find(). The patch implements error code propagation. Signed-off-by: Alexey Khoroshilov --- fs/hfsplus/extents.c | 21 + 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/fs/hfsplus/extents.c b/fs/hfsplus/extents.c index a94f0f7..fed73f7 100644 --- a/fs/hfsplus/extents.c +++ b/fs/hfsplus/extents.c @@ -83,7 +83,7 @@ static u32 hfsplus_ext_lastblock(struct hfsplus_extent *ext) return be32_to_cpu(ext->start_block) + be32_to_cpu(ext->block_count); } -static void __hfsplus_ext_write_extent(struct inode *inode, +static int __hfsplus_ext_write_extent(struct inode *inode, struct hfs_find_data *fd) { struct hfsplus_inode_info *hip = HFSPLUS_I(inode); @@ -98,13 +98,13 @@ static void __hfsplus_ext_write_extent(struct inode *inode, res = hfs_brec_find(fd, hfs_find_rec_by_key); if (hip->extent_state & HFSPLUS_EXT_NEW) { if (res != -ENOENT) - return; + return res; hfs_brec_insert(fd, hip->cached_extents, sizeof(hfsplus_extent_rec)); hip->extent_state &= ~(HFSPLUS_EXT_DIRTY | HFSPLUS_EXT_NEW); } else { if (res) - return; + return res; hfs_bnode_write(fd->bnode, hip->cached_extents, fd->entryoffset, fd->entrylength); hip->extent_state &= ~HFSPLUS_EXT_DIRTY; @@ -117,11 +117,13 @@ static void __hfsplus_ext_write_extent(struct inode *inode, * to explicily mark the inode dirty, too. */ set_bit(HFSPLUS_I_EXT_DIRTY, &hip->flags); + + return 0; } static int hfsplus_ext_write_extent_locked(struct inode *inode) { - int res; + int res = 0; if (HFSPLUS_I(inode)->extent_state & HFSPLUS_EXT_DIRTY) { struct hfs_find_data fd; @@ -129,10 +131,10 @@ static int hfsplus_ext_write_extent_locked(struct inode *inode) res = hfs_find_init(HFSPLUS_SB(inode->i_sb)->ext_tree, &fd); if (res) return res; - __hfsplus_ext_write_extent(inode, &fd); + res = __hfsplus_ext_write_extent(inode, &fd); hfs_find_exit(&fd); } - return 0; + return res; } int hfsplus_ext_write_extent(struct inode *inode) @@ -175,8 +177,11 @@ static inline int __hfsplus_ext_cache_extent(struct hfs_find_data *fd, WARN_ON(!mutex_is_locked(&hip->extents_lock)); - if (hip->extent_state & HFSPLUS_EXT_DIRTY) - __hfsplus_ext_write_extent(inode, fd); + if (hip->extent_state & HFSPLUS_EXT_DIRTY) { + res = __hfsplus_ext_write_extent(inode, fd); + if (res) + return res; + } res = __hfsplus_ext_read_extent(fd, hip->cached_extents, inode->i_ino, block, HFSPLUS_IS_RSRC(inode) ? -- 1.7.9.5 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] ext4: implement error handling of ext4_mb_new_preallocation()
If memory allocation in ext4_mb_new_group_pa() is failed, it returns error code, ext4_mb_new_preallocation() propages it, but ext4_mb_new_blocks() ignores it. An observed result was: - allocation fail means ext4_mb_new_group_pa() does not update ext4_allocation_context; - ext4_mb_new_blocks() sets ext4_allocation_request->len (ar->len = ac->ac_b_ex.fe_len;) to number of blocks preallocated (512) instead of number of blocks requested (1); - that activates update cycle in ext4_splice_branch(): for (i = 1; i < blks; i++) <-- blks is 512 instead of 1 here *(where->p + i) = cpu_to_le32(current_block++); - it iterates 511 times and corrupts a chunk of memory including inode structure; - page fault happens at EXT4_SB(inode->i_sb) in ext4_mark_inode_dirty(); - system hangs with 'scheduling while atomic' BUG. The patch implements a check for ext4_mb_new_preallocation() error code and handles its failure as if ext4_mb_regular_allocator() fails. Found by Linux File System Verification project (linuxtesting.org). Signed-off-by: Alexey Khoroshilov --- fs/ext4/mballoc.c | 15 --- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c index b1ed9e0..95c6b0d 100644 --- a/fs/ext4/mballoc.c +++ b/fs/ext4/mballoc.c @@ -4401,17 +4401,18 @@ ext4_fsblk_t ext4_mb_new_blocks(handle_t *handle, repeat: /* allocate space in core */ *errp = ext4_mb_regular_allocator(ac); + if (!*errp) { + /* as we've just preallocated more space than +* user requested orinally, we store allocated +* space in a special descriptor */ + if (ac->ac_status == AC_STATUS_FOUND && + ac->ac_o_ex.fe_len < ac->ac_b_ex.fe_len) + *errp = ext4_mb_new_preallocation(ac); + } if (*errp) { ext4_discard_allocated_blocks(ac); goto errout; } - - /* as we've just preallocated more space than -* user requested orinally, we store allocated -* space in a special descriptor */ - if (ac->ac_status == AC_STATUS_FOUND && - ac->ac_o_ex.fe_len < ac->ac_b_ex.fe_len) - ext4_mb_new_preallocation(ac); } if (likely(ac->ac_status == AC_STATUS_FOUND)) { *errp = ext4_mb_mark_diskspace_used(ac, handle, reserv_clstrs); -- 1.7.9.5 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] [media] wl128x: do not call copy_to_user() while holding spinlocks
copy_to_user() must not be called with spinlocks held, but it is in fmc_transfer_rds_from_internal_buff(). The patch copies data to tmpbuf, releases spinlock and then passes it to userspace. By the way there is a small unification: replace a couple of hardcoded constants by a macro. Found by Linux Driver Verification project (linuxtesting.org). Signed-off-by: Alexey Khoroshilov --- drivers/media/radio/wl128x/fmdrv_common.c | 24 ++-- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/drivers/media/radio/wl128x/fmdrv_common.c b/drivers/media/radio/wl128x/fmdrv_common.c index a002234..253f307 100644 --- a/drivers/media/radio/wl128x/fmdrv_common.c +++ b/drivers/media/radio/wl128x/fmdrv_common.c @@ -715,7 +715,7 @@ static void fm_irq_handle_rdsdata_getcmd_resp(struct fmdev *fmdev) struct fm_rdsdata_format rds_fmt; struct fm_rds *rds = &fmdev->rx.rds; unsigned long group_idx, flags; - u8 *rds_data, meta_data, tmpbuf[3]; + u8 *rds_data, meta_data, tmpbuf[FM_RDS_BLK_SIZE]; u8 type, blk_idx; u16 cur_picode; u32 rds_len; @@ -1073,6 +1073,7 @@ int fmc_transfer_rds_from_internal_buff(struct fmdev *fmdev, struct file *file, u8 __user *buf, size_t count) { u32 block_count; + u8 tmpbuf[FM_RDS_BLK_SIZE]; unsigned long flags; int ret; @@ -1087,29 +1088,32 @@ int fmc_transfer_rds_from_internal_buff(struct fmdev *fmdev, struct file *file, } /* Calculate block count from byte count */ - count /= 3; + count /= FM_RDS_BLK_SIZE; block_count = 0; ret = 0; - spin_lock_irqsave(&fmdev->rds_buff_lock, flags); - while (block_count < count) { - if (fmdev->rx.rds.wr_idx == fmdev->rx.rds.rd_idx) - break; + spin_lock_irqsave(&fmdev->rds_buff_lock, flags); - if (copy_to_user(buf, &fmdev->rx.rds.buff[fmdev->rx.rds.rd_idx], - FM_RDS_BLK_SIZE)) + if (fmdev->rx.rds.wr_idx == fmdev->rx.rds.rd_idx) { + spin_unlock_irqrestore(&fmdev->rds_buff_lock, flags); break; - + } + memcpy(tmpbuf, &fmdev->rx.rds.buff[fmdev->rx.rds.rd_idx], + FM_RDS_BLK_SIZE); fmdev->rx.rds.rd_idx += FM_RDS_BLK_SIZE; if (fmdev->rx.rds.rd_idx >= fmdev->rx.rds.buf_size) fmdev->rx.rds.rd_idx = 0; + spin_unlock_irqrestore(&fmdev->rds_buff_lock, flags); + + if (copy_to_user(buf, tmpbuf, FM_RDS_BLK_SIZE)) + break; + block_count++; buf += FM_RDS_BLK_SIZE; ret += FM_RDS_BLK_SIZE; } - spin_unlock_irqrestore(&fmdev->rds_buff_lock, flags); return ret; } -- 1.7.9.5 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] staging: wlags49_h2: fix error handling in pcmcia probe function
wl_adapter_attach() ignores some important issues such as register_netdev() failure. The patch fixes it. Found by Linux Driver Verification project (linuxtesting.org). Signed-off-by: Alexey Khoroshilov --- drivers/staging/wlags49_h2/wl_cs.c | 13 - drivers/staging/wlags49_h2/wl_cs.h |4 ++-- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/drivers/staging/wlags49_h2/wl_cs.c b/drivers/staging/wlags49_h2/wl_cs.c index 7c7c77f..f9e5fd3 100644 --- a/drivers/staging/wlags49_h2/wl_cs.c +++ b/drivers/staging/wlags49_h2/wl_cs.c @@ -133,6 +133,7 @@ static int wl_adapter_attach(struct pcmcia_device *link) { struct net_device *dev; struct wl_private *lp; + int ret; /**/ DBG_FUNC("wl_adapter_attach"); @@ -154,10 +155,12 @@ static int wl_adapter_attach(struct pcmcia_device *link) lp = wl_priv(dev); lp->link = link; - wl_adapter_insert(link); + ret = wl_adapter_insert(link); + if (ret != 0) + wl_device_dealloc(dev); DBG_LEAVE(DbgInfo); - return 0; + return ret; } /* wl_adapter_attach */ /**/ @@ -224,7 +227,7 @@ static int wl_adapter_resume(struct pcmcia_device *link) return 0; } /* wl_adapter_resume */ -void wl_adapter_insert(struct pcmcia_device *link) +int wl_adapter_insert(struct pcmcia_device *link) { struct net_device *dev; int ret; @@ -267,13 +270,13 @@ void wl_adapter_insert(struct pcmcia_device *link) " %pM\n", dev->name, dev->base_addr, dev->irq, dev->dev_addr); DBG_LEAVE(DbgInfo); - return; + return 0; failed: wl_adapter_release(link); DBG_LEAVE(DbgInfo); - return; + return ret; } /* wl_adapter_insert */ /**/ diff --git a/drivers/staging/wlags49_h2/wl_cs.h b/drivers/staging/wlags49_h2/wl_cs.h index a7ab579..081cc6f 100644 --- a/drivers/staging/wlags49_h2/wl_cs.h +++ b/drivers/staging/wlags49_h2/wl_cs.h @@ -65,10 +65,10 @@ /*** - * function protoypes + * function prototypes **/ -void wl_adapter_insert(struct pcmcia_device *link); +int wl_adapter_insert(struct pcmcia_device *link); void wl_adapter_release(struct pcmcia_device *link); -- 1.7.9.5 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] [media] cx88: Fix unsafe locking in suspend-resume
Legacy PCI suspend-resume handlers are called with interrupts enabled. But cx8800_suspend/cx8800_resume and cx8802_suspend_common/cx8802_resume_common use spin_lock/spin_unlock functions to acquire dev->slock, while the same lock is acquired in the corresponding irq-handlers: cx8800_irq and cx8802_irq. That means a deadlock is possible if an interrupt happens while suspend or resume owns the lock. The patch replaces spin_lock/spin_unlock with spin_lock_irqsave/spin_unlock_irqrestore. Found by Linux Driver Verification project (linuxtesting.org). Signed-off-by: Alexey Khoroshilov --- drivers/media/pci/cx88/cx88-mpeg.c | 10 ++ drivers/media/pci/cx88/cx88-video.c | 10 ++ 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/drivers/media/pci/cx88/cx88-mpeg.c b/drivers/media/pci/cx88/cx88-mpeg.c index c9d3182..c6cdbdb 100644 --- a/drivers/media/pci/cx88/cx88-mpeg.c +++ b/drivers/media/pci/cx88/cx88-mpeg.c @@ -532,16 +532,17 @@ static int cx8802_suspend_common(struct pci_dev *pci_dev, pm_message_t state) { struct cx8802_dev *dev = pci_get_drvdata(pci_dev); struct cx88_core *core = dev->core; + unsigned long flags; /* stop mpeg dma */ - spin_lock(&dev->slock); + spin_lock_irqsave(&dev->slock,flags); if (!list_empty(&dev->mpegq.active)) { dprintk( 2, "suspend\n" ); printk("%s: suspend mpeg\n", core->name); cx8802_stop_dma(dev); del_timer(&dev->mpegq.timeout); } - spin_unlock(&dev->slock); + spin_unlock_irqrestore(&dev->slock,flags); /* FIXME -- shutdown device */ cx88_shutdown(dev->core); @@ -558,6 +559,7 @@ static int cx8802_resume_common(struct pci_dev *pci_dev) { struct cx8802_dev *dev = pci_get_drvdata(pci_dev); struct cx88_core *core = dev->core; + unsigned long flags; int err; if (dev->state.disabled) { @@ -584,12 +586,12 @@ static int cx8802_resume_common(struct pci_dev *pci_dev) cx88_reset(dev->core); /* restart video+vbi capture */ - spin_lock(&dev->slock); + spin_lock_irqsave(&dev->slock,flags); if (!list_empty(&dev->mpegq.active)) { printk("%s: resume mpeg\n", core->name); cx8802_restart_queue(dev,&dev->mpegq); } - spin_unlock(&dev->slock); + spin_unlock_irqrestore(&dev->slock,flags); return 0; } diff --git a/drivers/media/pci/cx88/cx88-video.c b/drivers/media/pci/cx88/cx88-video.c index bc78354..d72b403 100644 --- a/drivers/media/pci/cx88/cx88-video.c +++ b/drivers/media/pci/cx88/cx88-video.c @@ -1957,9 +1957,10 @@ static int cx8800_suspend(struct pci_dev *pci_dev, pm_message_t state) { struct cx8800_dev *dev = pci_get_drvdata(pci_dev); struct cx88_core *core = dev->core; + unsigned long flags; /* stop video+vbi capture */ - spin_lock(&dev->slock); + spin_lock_irqsave(&dev->slock,flags); if (!list_empty(&dev->vidq.active)) { printk("%s/0: suspend video\n", core->name); stop_video_dma(dev); @@ -1970,7 +1971,7 @@ static int cx8800_suspend(struct pci_dev *pci_dev, pm_message_t state) cx8800_stop_vbi_dma(dev); del_timer(&dev->vbiq.timeout); } - spin_unlock(&dev->slock); + spin_unlock_irqrestore(&dev->slock,flags); if (core->ir) cx88_ir_stop(core); @@ -1989,6 +1990,7 @@ static int cx8800_resume(struct pci_dev *pci_dev) { struct cx8800_dev *dev = pci_get_drvdata(pci_dev); struct cx88_core *core = dev->core; + unsigned long flags; int err; if (dev->state.disabled) { @@ -2019,7 +2021,7 @@ static int cx8800_resume(struct pci_dev *pci_dev) cx_set(MO_PCI_INTMSK, core->pci_irqmask); /* restart video+vbi capture */ - spin_lock(&dev->slock); + spin_lock_irqsave(&dev->slock,flags); if (!list_empty(&dev->vidq.active)) { printk("%s/0: resume video\n", core->name); restart_video_queue(dev,&dev->vidq); @@ -2028,7 +2030,7 @@ static int cx8800_resume(struct pci_dev *pci_dev) printk("%s/0: resume vbi\n", core->name); cx8800_restart_vbi_queue(dev,&dev->vbiq); } - spin_unlock(&dev->slock); + spin_unlock_irqrestore(&dev->slock,flags); return 0; } -- 1.7.9.5 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] hfs: add error checking for hfs_find_init()
hfs_find_init() may fail with ENOMEM, but there are places, where the returned value is not checked. The consequences can be very unpleasant, e.g. kfree uninitialized pointer and inappropriate mutex unlocking. The patch adds checks for errors in hfs_find_init(). Found by Linux Driver Verification project (linuxtesting.org). Signed-off-by: Alexey Khoroshilov --- fs/hfs/catalog.c | 12 +--- fs/hfs/dir.c |8 ++-- fs/hfs/extent.c | 48 +--- fs/hfs/hfs_fs.h |2 +- fs/hfs/inode.c | 11 +-- fs/hfs/super.c |4 +++- 6 files changed, 61 insertions(+), 24 deletions(-) diff --git a/fs/hfs/catalog.c b/fs/hfs/catalog.c index 424b033..9569b39 100644 --- a/fs/hfs/catalog.c +++ b/fs/hfs/catalog.c @@ -92,7 +92,9 @@ int hfs_cat_create(u32 cnid, struct inode *dir, struct qstr *str, struct inode * return -ENOSPC; sb = dir->i_sb; - hfs_find_init(HFS_SB(sb)->cat_tree, &fd); + err = hfs_find_init(HFS_SB(sb)->cat_tree, &fd); + if (err) + return err; hfs_cat_build_key(sb, fd.search_key, cnid, NULL); entry_size = hfs_cat_build_thread(sb, &entry, S_ISDIR(inode->i_mode) ? @@ -214,7 +216,9 @@ int hfs_cat_delete(u32 cnid, struct inode *dir, struct qstr *str) dprint(DBG_CAT_MOD, "delete_cat: %s,%u\n", str ? str->name : NULL, cnid); sb = dir->i_sb; - hfs_find_init(HFS_SB(sb)->cat_tree, &fd); + res = hfs_find_init(HFS_SB(sb)->cat_tree, &fd); + if (res) + return res; hfs_cat_build_key(sb, fd.search_key, dir->i_ino, str); res = hfs_brec_find(&fd); @@ -281,7 +285,9 @@ int hfs_cat_move(u32 cnid, struct inode *src_dir, struct qstr *src_name, dprint(DBG_CAT_MOD, "rename_cat: %u - %lu,%s - %lu,%s\n", cnid, src_dir->i_ino, src_name->name, dst_dir->i_ino, dst_name->name); sb = src_dir->i_sb; - hfs_find_init(HFS_SB(sb)->cat_tree, &src_fd); + err = hfs_find_init(HFS_SB(sb)->cat_tree, &src_fd); + if (err) + return err; dst_fd = src_fd; /* find the old dir entry and read the data */ diff --git a/fs/hfs/dir.c b/fs/hfs/dir.c index 5f7f1ab..e1c8048 100644 --- a/fs/hfs/dir.c +++ b/fs/hfs/dir.c @@ -25,7 +25,9 @@ static struct dentry *hfs_lookup(struct inode *dir, struct dentry *dentry, struct inode *inode = NULL; int res; - hfs_find_init(HFS_SB(dir->i_sb)->cat_tree, &fd); + res = hfs_find_init(HFS_SB(dir->i_sb)->cat_tree, &fd); + if (res) + return ERR_PTR(res); hfs_cat_build_key(dir->i_sb, fd.search_key, dir->i_ino, &dentry->d_name); res = hfs_brec_read(&fd, &rec, sizeof(rec)); if (res) { @@ -63,7 +65,9 @@ static int hfs_readdir(struct file *filp, void *dirent, filldir_t filldir) if (filp->f_pos >= inode->i_size) return 0; - hfs_find_init(HFS_SB(sb)->cat_tree, &fd); + err = hfs_find_init(HFS_SB(sb)->cat_tree, &fd); + if (err) + return err; hfs_cat_build_key(sb, fd.search_key, inode->i_ino, NULL); err = hfs_brec_find(&fd); if (err) diff --git a/fs/hfs/extent.c b/fs/hfs/extent.c index a67955a..813447b 100644 --- a/fs/hfs/extent.c +++ b/fs/hfs/extent.c @@ -107,7 +107,7 @@ static u16 hfs_ext_lastblock(struct hfs_extent *ext) return be16_to_cpu(ext->block) + be16_to_cpu(ext->count); } -static void __hfs_ext_write_extent(struct inode *inode, struct hfs_find_data *fd) +static int __hfs_ext_write_extent(struct inode *inode, struct hfs_find_data *fd) { int res; @@ -116,26 +116,31 @@ static void __hfs_ext_write_extent(struct inode *inode, struct hfs_find_data *fd res = hfs_brec_find(fd); if (HFS_I(inode)->flags & HFS_FLG_EXT_NEW) { if (res != -ENOENT) - return; + return res; hfs_brec_insert(fd, HFS_I(inode)->cached_extents, sizeof(hfs_extent_rec)); HFS_I(inode)->flags &= ~(HFS_FLG_EXT_DIRTY|HFS_FLG_EXT_NEW); } else { if (res) - return; + return res; hfs_bnode_write(fd->bnode, HFS_I(inode)->cached_extents, fd->entryoffset, fd->entrylength); HFS_I(inode)->flags &= ~HFS_FLG_EXT_DIRTY; } + return 0; } -void hfs_ext_write_extent(struct inode *inode) +int hfs_ext_write_extent(struct inode *inode) { struct hfs_find_data fd; + int res = 0; if (HFS_I(inode)->flags & HFS_FLG_EXT_DIRTY) { - hfs_find_init(HFS_SB(inode->i_sb)->ext_tree, &fd); - __hfs_ext_write_extent(inode, &
[PATCH] usb/core/devio.c: Don't use GFP_KERNEL while we cannot reset a storage device
As it was described by Oliver Neukum in commit acbe2fe "USB: Don't use GFP_KERNEL while we cannot reset a storage device": Memory allocations with GFP_KERNEL can cause IO to a storage device which can fail resulting in a need to reset the device. Therefore GFP_KERNEL cannot be safely used between usb_lock_device() and usb_unlock_device(). Replace by GFP_NOIO. The patch fixes the same issue in usb/core/devio.c. All the allocations fixed are under usb_lock_device() from usbdev_do_ioctl(). Found by Linux Driver Verification project (linuxtesting.org). Signed-off-by: Alexey Khoroshilov --- drivers/usb/core/devio.c | 22 +++--- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c index 8823e98..4be27e3 100644 --- a/drivers/usb/core/devio.c +++ b/drivers/usb/core/devio.c @@ -275,10 +275,10 @@ static struct async *alloc_async(unsigned int numisoframes) { struct async *as; - as = kzalloc(sizeof(struct async), GFP_KERNEL); + as = kzalloc(sizeof(struct async), GFP_NOIO); if (!as) return NULL; - as->urb = usb_alloc_urb(numisoframes, GFP_KERNEL); + as->urb = usb_alloc_urb(numisoframes, GFP_NOIO); if (!as->urb) { kfree(as); return NULL; @@ -887,7 +887,7 @@ static int proc_control(struct dev_state *ps, void __user *arg) sizeof(struct usb_ctrlrequest)); if (ret) return ret; - tbuf = (unsigned char *)__get_free_page(GFP_KERNEL); + tbuf = (unsigned char *)__get_free_page(GFP_NOIO); if (!tbuf) { ret = -ENOMEM; goto done; @@ -983,7 +983,7 @@ static int proc_bulk(struct dev_state *ps, void __user *arg) ret = usbfs_increase_memory_usage(len1 + sizeof(struct urb)); if (ret) return ret; - if (!(tbuf = kmalloc(len1, GFP_KERNEL))) { + if (!(tbuf = kmalloc(len1, GFP_NOIO))) { ret = -ENOMEM; goto done; } @@ -1211,7 +1211,7 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb, /* min 8 byte setup packet */ if (uurb->buffer_length < 8) return -EINVAL; - dr = kmalloc(sizeof(struct usb_ctrlrequest), GFP_KERNEL); + dr = kmalloc(sizeof(struct usb_ctrlrequest), GFP_NOIO); if (!dr) return -ENOMEM; if (copy_from_user(dr, uurb->buffer, 8)) { @@ -1278,7 +1278,7 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb, return -EINVAL; isofrmlen = sizeof(struct usbdevfs_iso_packet_desc) * uurb->number_of_packets; - if (!(isopkt = kmalloc(isofrmlen, GFP_KERNEL))) + if (!(isopkt = kmalloc(isofrmlen, GFP_NOIO))) return -ENOMEM; if (copy_from_user(isopkt, iso_frame_desc, isofrmlen)) { ret = -EFAULT; @@ -1326,7 +1326,7 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb, if (num_sgs) { as->urb->sg = kmalloc(num_sgs * sizeof(struct scatterlist), - GFP_KERNEL); + GFP_NOIO); if (!as->urb->sg) { ret = -ENOMEM; goto error; @@ -1337,7 +1337,7 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb, totlen = uurb->buffer_length; for (i = 0; i < as->urb->num_sgs; i++) { u = (totlen > USB_SG_SIZE) ? USB_SG_SIZE : totlen; - buf = kmalloc(u, GFP_KERNEL); + buf = kmalloc(u, GFP_NOIO); if (!buf) { ret = -ENOMEM; goto error; @@ -1355,7 +1355,7 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb, } } else if (uurb->buffer_length > 0) { as->urb->transfer_buffer = kmalloc(uurb->buffer_length, - GFP_KERNEL); + GFP_NOIO); if (!as->urb->transfer_buffer) { ret = -ENOMEM; goto error; @@ -1467,7 +1467,7 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb, ret = usb_submit_urb(as->urb, GFP_ATOMIC); spin_unlock_irq(&ps->lock); } else { - ret = usb_submit_urb(as->urb, GFP_KERNEL); + ret = usb_submit_urb(as->urb, GFP_NOIO); } if (
[RESEND PATCH] [SCSI] mpt2sas: fix double mutex lock in NON_BLOCKING state
If state is NON_BLOCKING and mutex_trylock is succeed, the control flow goes to mutex_lock_interruptible() that is a deadlock. Found by Linux Driver Verification project (linuxtesting.org). Acked-by: "Nandigama, Nagalakshmi" Signed-off-by: Alexey Khoroshilov --- drivers/scsi/mpt2sas/mpt2sas_ctl.c |6 -- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/mpt2sas/mpt2sas_ctl.c b/drivers/scsi/mpt2sas/mpt2sas_ctl.c index 49bdd2d..d29ea56 100644 --- a/drivers/scsi/mpt2sas/mpt2sas_ctl.c +++ b/drivers/scsi/mpt2sas/mpt2sas_ctl.c @@ -2181,8 +2181,10 @@ _ctl_ioctl_main(struct file *file, unsigned int cmd, void __user *arg, return -EAGAIN; state = (file->f_flags & O_NONBLOCK) ? NON_BLOCKING : BLOCKING; - if (state == NON_BLOCKING && !mutex_trylock(&ioc->ctl_cmds.mutex)) - return -EAGAIN; + if (state == NON_BLOCKING) { + if (!mutex_trylock(&ioc->ctl_cmds.mutex)) + return -EAGAIN; + } else if (mutex_lock_interruptible(&ioc->ctl_cmds.mutex)) return -ERESTARTSYS; -- 1.7.9.5 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] drm/edid: Fix potential memory leak in edid_load()
Do not leak memory by updating pointer with potentially NULL realloc return value. Found by Linux Driver Verification project (linuxtesting.org). Signed-off-by: Alexey Khoroshilov --- drivers/gpu/drm/drm_edid_load.c |8 +--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/drm_edid_load.c b/drivers/gpu/drm/drm_edid_load.c index 66d4a28..0303935 100644 --- a/drivers/gpu/drm/drm_edid_load.c +++ b/drivers/gpu/drm/drm_edid_load.c @@ -119,7 +119,7 @@ static int edid_load(struct drm_connector *connector, char *name, { const struct firmware *fw; struct platform_device *pdev; - u8 *fwdata = NULL, *edid; + u8 *fwdata = NULL, *edid, *new_edid; int fwsize, expected; int builtin = 0, err = 0; int i, valid_extensions = 0; @@ -195,12 +195,14 @@ static int edid_load(struct drm_connector *connector, char *name, "\"%s\" for connector \"%s\"\n", valid_extensions, edid[0x7e], name, connector_name); edid[0x7e] = valid_extensions; - edid = krealloc(edid, (valid_extensions + 1) * EDID_LENGTH, + new_edid = krealloc(edid, (valid_extensions + 1) * EDID_LENGTH, GFP_KERNEL); - if (edid == NULL) { + if (new_edid == NULL) { err = -ENOMEM; + kfree(edid); goto relfw_out; } + edid = new_edid; } connector->display_info.raw_edid = edid; -- 1.7.9.5 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] iio/adjd_s311: Fix potential memory leak in adjd_s311_update_scan_mode()
Do not leak memory by updating pointer with potentially NULL realloc return value. Found by Linux Driver Verification project (linuxtesting.org). Signed-off-by: Alexey Khoroshilov --- drivers/iio/light/adjd_s311.c | 14 ++ 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/drivers/iio/light/adjd_s311.c b/drivers/iio/light/adjd_s311.c index 1cbb449..0adda5b 100644 --- a/drivers/iio/light/adjd_s311.c +++ b/drivers/iio/light/adjd_s311.c @@ -271,12 +271,18 @@ static int adjd_s311_update_scan_mode(struct iio_dev *indio_dev, const unsigned long *scan_mask) { struct adjd_s311_data *data = iio_priv(indio_dev); - data->buffer = krealloc(data->buffer, indio_dev->scan_bytes, + u16 *new_buffer; + int ret = 0; + + new_buffer = krealloc(data->buffer, indio_dev->scan_bytes, GFP_KERNEL); - if (!data->buffer) - return -ENOMEM; + if (new_buffer == NULL) { + kfree(data->buffer); + ret = -ENOMEM; + } + data->buffer = new_buffer; - return 0; + return ret; } static const struct iio_info adjd_s311_info = { -- 1.7.9.5 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] USB: whci-hcd: Fix potential memory leak in qset_add_urb_sg()
Do not leak memory by updating pointer with potentially NULL realloc return value. By the way remove unused local variable: struct whc_page_list_entry *entry; More precisely, it was used to increment uninitialized value within one of cycles. Found by Linux Driver Verification project (linuxtesting.org). Signed-off-by: Alexey Khoroshilov --- drivers/usb/host/whci/qset.c | 11 +++ 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/drivers/usb/host/whci/qset.c b/drivers/usb/host/whci/qset.c index 76083ae..dc31c42 100644 --- a/drivers/usb/host/whci/qset.c +++ b/drivers/usb/host/whci/qset.c @@ -436,7 +436,7 @@ static int qset_add_urb_sg(struct whc *whc, struct whc_qset *qset, struct urb *u int i; int ntds = 0; struct whc_std *std = NULL; - struct whc_page_list_entry *entry; + struct whc_page_list_entry *new_pl_virt; dma_addr_t prev_end = 0; size_t pl_len; int p = 0; @@ -508,12 +508,15 @@ static int qset_add_urb_sg(struct whc *whc, struct whc_qset *qset, struct urb *u pl_len = std->num_pointers * sizeof(struct whc_page_list_entry); - std->pl_virt = krealloc(std->pl_virt, pl_len, mem_flags); - if (std->pl_virt == NULL) { + new_pl_virt = krealloc(std->pl_virt, pl_len, mem_flags); + if (new_pl_virt == NULL) { + kfree(std->pl_virt); + std->pl_virt = NULL; return -ENOMEM; } + std->pl_virt = new_pl_virt; - for (;p < std->num_pointers; p++, entry++) { + for (;p < std->num_pointers; p++) { std->pl_virt[p].buf_ptr = cpu_to_le64(dma_addr); dma_addr = (dma_addr + WHCI_PAGE_SIZE) & ~(WHCI_PAGE_SIZE-1); } -- 1.7.9.5 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH] iio/adjd_s311: Fix potential memory leak in adjd_s311_update_scan_mode()
On 08/08/2012 11:17 AM, Peter Meerwald wrote: >> Do not leak memory by updating pointer with potentially >> NULL realloc return value. > I agree > > use of krealloc() was suggested in driver review (see > http://www.spinics.net/lists/linux-iio/msg05930.html) to shorten the code; > unfortunately, I misunderstood the semantics of krealloc() in case > allocation fails > > this is the original code: > > kfree(data->buffer); > data->buffer = kmalloc(indio_dev->scan_bytes, GFP_KERNEL); > if (!data->buffer) > return -ENOMEM; > > I suggest to switch back to that original code, there is no need preserve > the data in the buffer as krealloc does That is fine. >> Found by Linux Driver Verification project (linuxtesting.org). >> >> Signed-off-by: Alexey Khoroshilov >> --- >> drivers/iio/light/adjd_s311.c | 14 ++ >> 1 file changed, 10 insertions(+), 4 deletions(-) >> >> diff --git a/drivers/iio/light/adjd_s311.c b/drivers/iio/light/adjd_s311.c >> index 1cbb449..0adda5b 100644 >> --- a/drivers/iio/light/adjd_s311.c >> +++ b/drivers/iio/light/adjd_s311.c >> @@ -271,12 +271,18 @@ static int adjd_s311_update_scan_mode(struct iio_dev >> *indio_dev, >> const unsigned long *scan_mask) >> { >> struct adjd_s311_data *data = iio_priv(indio_dev); >> -data->buffer = krealloc(data->buffer, indio_dev->scan_bytes, >> +u16 *new_buffer; >> +int ret = 0; >> + >> +new_buffer = krealloc(data->buffer, indio_dev->scan_bytes, >> GFP_KERNEL); >> -if (!data->buffer) >> -return -ENOMEM; >> +if (new_buffer == NULL) { >> +kfree(data->buffer); >> +ret = -ENOMEM; >> +} >> +data->buffer = new_buffer; >> >> -return 0; >> +return ret; >> } >> >> static const struct iio_info adjd_s311_info = { >> -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v2] iio/adjd_s311: Fix potential memory leak in adjd_s311_update_scan_mode()
Do not leak memory by updating pointer with potentially NULL realloc return value. There is no need to preserve data in the buffer, so replace krealloc() by kfree()-kmalloc() pair. Found by Linux Driver Verification project (linuxtesting.org). Signed-off-by: Alexey Khoroshilov --- drivers/iio/light/adjd_s311.c |7 --- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/iio/light/adjd_s311.c b/drivers/iio/light/adjd_s311.c index 1cbb449..9a99f43 100644 --- a/drivers/iio/light/adjd_s311.c +++ b/drivers/iio/light/adjd_s311.c @@ -271,9 +271,10 @@ static int adjd_s311_update_scan_mode(struct iio_dev *indio_dev, const unsigned long *scan_mask) { struct adjd_s311_data *data = iio_priv(indio_dev); - data->buffer = krealloc(data->buffer, indio_dev->scan_bytes, - GFP_KERNEL); - if (!data->buffer) + + kfree(data->buffer); + data->buffer = kmalloc(indio_dev->scan_bytes, GFP_KERNEL); + if (data->buffer == NULL) return -ENOMEM; return 0; -- 1.7.9.5 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] net/core: Fix potential memory leak in dev_set_alias()
Do not leak memory by updating pointer with potentially NULL realloc return value. Found by Linux Driver Verification project (linuxtesting.org). Signed-off-by: Alexey Khoroshilov --- net/core/dev.c |7 +-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/net/core/dev.c b/net/core/dev.c index 0cb3fe8..3bcc5da 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -1055,6 +1055,8 @@ rollback: */ int dev_set_alias(struct net_device *dev, const char *alias, size_t len) { + char *new_ifalias; + ASSERT_RTNL(); if (len >= IFALIASZ) @@ -1068,9 +1070,10 @@ int dev_set_alias(struct net_device *dev, const char *alias, size_t len) return 0; } - dev->ifalias = krealloc(dev->ifalias, len + 1, GFP_KERNEL); - if (!dev->ifalias) + new_ifalias = krealloc(dev->ifalias, len + 1, GFP_KERNEL); + if (!new_ifalias) return -ENOMEM; + dev->ifalias = new_ifalias; strlcpy(dev->ifalias, alias, len+1); return len; -- 1.7.9.5 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] wusb: Fix potential memory leak in wusb_dev_sec_add()
Do not leak memory by updating pointer with potentially NULL realloc return value. Found by Linux Driver Verification project (linuxtesting.org). Signed-off-by: Alexey Khoroshilov --- drivers/usb/wusbcore/security.c |7 --- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/usb/wusbcore/security.c b/drivers/usb/wusbcore/security.c index fa810a8..dd88441 100644 --- a/drivers/usb/wusbcore/security.c +++ b/drivers/usb/wusbcore/security.c @@ -202,7 +202,7 @@ int wusb_dev_sec_add(struct wusbhc *wusbhc, { int result, bytes, secd_size; struct device *dev = &usb_dev->dev; - struct usb_security_descriptor *secd; + struct usb_security_descriptor *secd, *new_secd; const struct usb_encryption_descriptor *etd, *ccm1_etd = NULL; const void *itr, *top; char buf[64]; @@ -221,11 +221,12 @@ int wusb_dev_sec_add(struct wusbhc *wusbhc, goto out; } secd_size = le16_to_cpu(secd->wTotalLength); - secd = krealloc(secd, secd_size, GFP_KERNEL); - if (secd == NULL) { + new_secd = krealloc(secd, secd_size, GFP_KERNEL); + if (new_secd == NULL) { dev_err(dev, "Can't allocate space for security descriptors\n"); goto out; } + secd = new_secd; result = usb_get_descriptor(usb_dev, USB_DT_SECURITY, 0, secd, secd_size); if (result < secd_size) { -- 1.7.9.5 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] can/softing: Fix potential memory leak in softing_load_fw()
Do not leak memory by updating pointer with potentially NULL realloc return value. Found by Linux Driver Verification project (linuxtesting.org). Signed-off-by: Alexey Khoroshilov --- drivers/net/can/softing/softing_fw.c |7 --- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/net/can/softing/softing_fw.c b/drivers/net/can/softing/softing_fw.c index 3105961..b595d34 100644 --- a/drivers/net/can/softing/softing_fw.c +++ b/drivers/net/can/softing/softing_fw.c @@ -150,7 +150,7 @@ int softing_load_fw(const char *file, struct softing *card, const uint8_t *mem, *end, *dat; uint16_t type, len; uint32_t addr; - uint8_t *buf = NULL; + uint8_t *buf = NULL, *new_buf; int buflen = 0; int8_t type_end = 0; @@ -199,11 +199,12 @@ int softing_load_fw(const char *file, struct softing *card, if (len > buflen) { /* align buflen */ buflen = (len + (1024-1)) & ~(1024-1); - buf = krealloc(buf, buflen, GFP_KERNEL); - if (!buf) { + new_buf = krealloc(buf, buflen, GFP_KERNEL); + if (!new_buf) { ret = -ENOMEM; goto failed; } + buf = new_buf; } /* verify record data */ memcpy_fromio(buf, &dpram[addr + offset], len); -- 1.7.9.5 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/