Commit d6d1b650 authored by Rusty Russell's avatar Rusty Russell

param: simple locking for sysfs-writable charp parameters

Since the writing to sysfs can free the old one, we need to block that
when we access the charp variables.
Signed-off-by: default avatarRusty Russell <rusty@rustcorp.com.au>
Reviewed-by: default avatarTakashi Iwai <tiwai@suse.de>
Tested-by: default avatarPhil Carmody <ext-phil.2.carmody@nokia.com>
Cc: Jeff Dike <jdike@addtoit.com>
Cc: Dan Williams <dcbw@redhat.com>
Cc: John W. Linville <linville@tuxdriver.com>
Cc: Jing Huang <huangj@brocade.com>
Cc: James E.J. Bottomley <James.Bottomley@suse.de>
Cc: Greg Kroah-Hartman <gregkh@suse.de>
Cc: Johannes Berg <johannes@sipsolutions.net>
Cc: David S. Miller <davem@davemloft.net>
Cc: user-mode-linux-devel@lists.sourceforge.net
Cc: libertas-dev@lists.infradead.org
Cc: linux-wireless@vger.kernel.org
Cc: netdev@vger.kernel.org
Cc: linux-scsi@vger.kernel.org
Cc: linux-usb@vger.kernel.org
parent dca41306
...@@ -187,7 +187,9 @@ static int hostaudio_open(struct inode *inode, struct file *file) ...@@ -187,7 +187,9 @@ static int hostaudio_open(struct inode *inode, struct file *file)
int ret; int ret;
#ifdef DEBUG #ifdef DEBUG
kparam_block_sysfs_write(dsp);
printk(KERN_DEBUG "hostaudio: open called (host: %s)\n", dsp); printk(KERN_DEBUG "hostaudio: open called (host: %s)\n", dsp);
kparam_unblock_sysfs_write(dsp);
#endif #endif
state = kmalloc(sizeof(struct hostaudio_state), GFP_KERNEL); state = kmalloc(sizeof(struct hostaudio_state), GFP_KERNEL);
...@@ -199,9 +201,11 @@ static int hostaudio_open(struct inode *inode, struct file *file) ...@@ -199,9 +201,11 @@ static int hostaudio_open(struct inode *inode, struct file *file)
if (file->f_mode & FMODE_WRITE) if (file->f_mode & FMODE_WRITE)
w = 1; w = 1;
kparam_block_sysfs_write(dsp);
lock_kernel(); lock_kernel();
ret = os_open_file(dsp, of_set_rw(OPENFLAGS(), r, w), 0); ret = os_open_file(dsp, of_set_rw(OPENFLAGS(), r, w), 0);
unlock_kernel(); unlock_kernel();
kparam_unblock_sysfs_write(dsp);
if (ret < 0) { if (ret < 0) {
kfree(state); kfree(state);
...@@ -258,13 +262,17 @@ static int hostmixer_open_mixdev(struct inode *inode, struct file *file) ...@@ -258,13 +262,17 @@ static int hostmixer_open_mixdev(struct inode *inode, struct file *file)
if (file->f_mode & FMODE_WRITE) if (file->f_mode & FMODE_WRITE)
w = 1; w = 1;
kparam_block_sysfs_write(mixer);
lock_kernel(); lock_kernel();
ret = os_open_file(mixer, of_set_rw(OPENFLAGS(), r, w), 0); ret = os_open_file(mixer, of_set_rw(OPENFLAGS(), r, w), 0);
unlock_kernel(); unlock_kernel();
kparam_unblock_sysfs_write(mixer);
if (ret < 0) { if (ret < 0) {
kparam_block_sysfs_write(dsp);
printk(KERN_ERR "hostaudio_open_mixdev failed to open '%s', " printk(KERN_ERR "hostaudio_open_mixdev failed to open '%s', "
"err = %d\n", dsp, -ret); "err = %d\n", dsp, -ret);
kparam_unblock_sysfs_write(dsp);
kfree(state); kfree(state);
return ret; return ret;
} }
...@@ -320,8 +328,10 @@ MODULE_LICENSE("GPL"); ...@@ -320,8 +328,10 @@ MODULE_LICENSE("GPL");
static int __init hostaudio_init_module(void) static int __init hostaudio_init_module(void)
{ {
__kernel_param_lock();
printk(KERN_INFO "UML Audio Relay (host dsp = %s, host mixer = %s)\n", printk(KERN_INFO "UML Audio Relay (host dsp = %s, host mixer = %s)\n",
dsp, mixer); dsp, mixer);
__kernel_param_unlock();
module_data.dev_audio = register_sound_dsp(&hostaudio_fops, -1); module_data.dev_audio = register_sound_dsp(&hostaudio_fops, -1);
if (module_data.dev_audio < 0) { if (module_data.dev_audio < 0) {
......
...@@ -289,10 +289,13 @@ static int if_usb_probe(struct usb_interface *intf, ...@@ -289,10 +289,13 @@ static int if_usb_probe(struct usb_interface *intf,
} }
/* Upload firmware */ /* Upload firmware */
kparam_block_sysfs_write(fw_name);
if (__if_usb_prog_firmware(cardp, lbs_fw_name, BOOT_CMD_FW_BY_USB)) { if (__if_usb_prog_firmware(cardp, lbs_fw_name, BOOT_CMD_FW_BY_USB)) {
kparam_unblock_sysfs_write(fw_name);
lbs_deb_usbd(&udev->dev, "FW upload failed\n"); lbs_deb_usbd(&udev->dev, "FW upload failed\n");
goto err_prog_firmware; goto err_prog_firmware;
} }
kparam_unblock_sysfs_write(fw_name);
if (!(priv = lbs_add_card(cardp, &udev->dev))) if (!(priv = lbs_add_card(cardp, &udev->dev)))
goto err_prog_firmware; goto err_prog_firmware;
......
...@@ -811,12 +811,15 @@ static int if_usb_prog_firmware(struct if_usb_card *cardp) ...@@ -811,12 +811,15 @@ static int if_usb_prog_firmware(struct if_usb_card *cardp)
lbtf_deb_enter(LBTF_DEB_USB); lbtf_deb_enter(LBTF_DEB_USB);
kparam_block_sysfs_write(fw_name);
ret = request_firmware(&cardp->fw, lbtf_fw_name, &cardp->udev->dev); ret = request_firmware(&cardp->fw, lbtf_fw_name, &cardp->udev->dev);
if (ret < 0) { if (ret < 0) {
pr_err("request_firmware() failed with %#x\n", ret); pr_err("request_firmware() failed with %#x\n", ret);
pr_err("firmware %s not found\n", lbtf_fw_name); pr_err("firmware %s not found\n", lbtf_fw_name);
kparam_unblock_sysfs_write(fw_name);
goto done; goto done;
} }
kparam_unblock_sysfs_write(fw_name);
if (check_fwfile_format(cardp->fw->data, cardp->fw->size)) if (check_fwfile_format(cardp->fw->data, cardp->fw->size))
goto release_fw; goto release_fw;
......
...@@ -788,6 +788,7 @@ bfad_drv_init(struct bfad_s *bfad) ...@@ -788,6 +788,7 @@ bfad_drv_init(struct bfad_s *bfad)
memset(&driver_info, 0, sizeof(driver_info)); memset(&driver_info, 0, sizeof(driver_info));
strncpy(driver_info.version, BFAD_DRIVER_VERSION, strncpy(driver_info.version, BFAD_DRIVER_VERSION,
sizeof(driver_info.version) - 1); sizeof(driver_info.version) - 1);
__kernel_param_lock();
if (host_name) if (host_name)
strncpy(driver_info.host_machine_name, host_name, strncpy(driver_info.host_machine_name, host_name,
sizeof(driver_info.host_machine_name) - 1); sizeof(driver_info.host_machine_name) - 1);
...@@ -797,6 +798,7 @@ bfad_drv_init(struct bfad_s *bfad) ...@@ -797,6 +798,7 @@ bfad_drv_init(struct bfad_s *bfad)
if (os_patch) if (os_patch)
strncpy(driver_info.host_os_patch, os_patch, strncpy(driver_info.host_os_patch, os_patch,
sizeof(driver_info.host_os_patch) - 1); sizeof(driver_info.host_os_patch) - 1);
__kernel_param_unlock();
strncpy(driver_info.os_device_name, bfad->pci_name, strncpy(driver_info.os_device_name, bfad->pci_name,
sizeof(driver_info.os_device_name - 1)); sizeof(driver_info.os_device_name - 1));
......
...@@ -1577,6 +1577,7 @@ static void cmvs_file_name(struct uea_softc *sc, char *const cmv_name, int ver) ...@@ -1577,6 +1577,7 @@ static void cmvs_file_name(struct uea_softc *sc, char *const cmv_name, int ver)
char file_arr[] = "CMVxy.bin"; char file_arr[] = "CMVxy.bin";
char *file; char *file;
kparam_block_sysfs_write(cmv_file);
/* set proper name corresponding modem version and line type */ /* set proper name corresponding modem version and line type */
if (cmv_file[sc->modem_index] == NULL) { if (cmv_file[sc->modem_index] == NULL) {
if (UEA_CHIP_VERSION(sc) == ADI930) if (UEA_CHIP_VERSION(sc) == ADI930)
...@@ -1595,6 +1596,7 @@ static void cmvs_file_name(struct uea_softc *sc, char *const cmv_name, int ver) ...@@ -1595,6 +1596,7 @@ static void cmvs_file_name(struct uea_softc *sc, char *const cmv_name, int ver)
strlcat(cmv_name, file, UEA_FW_NAME_MAX); strlcat(cmv_name, file, UEA_FW_NAME_MAX);
if (ver == 2) if (ver == 2)
strlcat(cmv_name, ".v2", UEA_FW_NAME_MAX); strlcat(cmv_name, ".v2", UEA_FW_NAME_MAX);
kparam_unblock_sysfs_write(cmv_file);
} }
static int request_cmvs_old(struct uea_softc *sc, static int request_cmvs_old(struct uea_softc *sc,
......
...@@ -726,7 +726,9 @@ static int __devinit vt8623_pci_probe(struct pci_dev *dev, const struct pci_devi ...@@ -726,7 +726,9 @@ static int __devinit vt8623_pci_probe(struct pci_dev *dev, const struct pci_devi
/* Prepare startup mode */ /* Prepare startup mode */
kparam_block_sysfs_write(mode_option);
rc = fb_find_mode(&(info->var), info, mode_option, NULL, 0, NULL, 8); rc = fb_find_mode(&(info->var), info, mode_option, NULL, 0, NULL, 8);
kparam_unblock_sysfs_write(mode_option);
if (! ((rc == 1) || (rc == 2))) { if (! ((rc == 1) || (rc == 2))) {
rc = -EINVAL; rc = -EINVAL;
dev_err(info->device, "mode %s not found\n", mode_option); dev_err(info->device, "mode %s not found\n", mode_option);
......
...@@ -103,6 +103,7 @@ ieee80211_rate_control_ops_get(const char *name) ...@@ -103,6 +103,7 @@ ieee80211_rate_control_ops_get(const char *name)
struct rate_control_ops *ops; struct rate_control_ops *ops;
const char *alg_name; const char *alg_name;
kparam_block_sysfs_write(ieee80211_default_rc_algo);
if (!name) if (!name)
alg_name = ieee80211_default_rc_algo; alg_name = ieee80211_default_rc_algo;
else else
...@@ -120,6 +121,7 @@ ieee80211_rate_control_ops_get(const char *name) ...@@ -120,6 +121,7 @@ ieee80211_rate_control_ops_get(const char *name)
/* try built-in one if specific alg requested but not found */ /* try built-in one if specific alg requested but not found */
if (!ops && strlen(CONFIG_MAC80211_RC_DEFAULT)) if (!ops && strlen(CONFIG_MAC80211_RC_DEFAULT))
ops = ieee80211_try_rate_control_ops_get(CONFIG_MAC80211_RC_DEFAULT); ops = ieee80211_try_rate_control_ops_get(CONFIG_MAC80211_RC_DEFAULT);
kparam_unblock_sysfs_write(ieee80211_default_rc_algo);
return ops; return ops;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment