Skip to content

Commit

Permalink
param: simple locking for sysfs-writable charp parameters
Browse files Browse the repository at this point in the history
Since the writing to sysfs can free the old one, we need to block that
when we access the charp variables.

Signed-off-by: Rusty Russell <[email protected]>
Reviewed-by: Takashi Iwai <[email protected]>
Tested-by: Phil Carmody <[email protected]>
Cc: Jeff Dike <[email protected]>
Cc: Dan Williams <[email protected]>
Cc: John W. Linville <[email protected]>
Cc: Jing Huang <[email protected]>
Cc: James E.J. Bottomley <[email protected]>
Cc: Greg Kroah-Hartman <[email protected]>
Cc: Johannes Berg <[email protected]>
Cc: David S. Miller <[email protected]>
Cc: [email protected]
Cc: [email protected]
Cc: [email protected]
Cc: [email protected]
Cc: [email protected]
Cc: [email protected]
  • Loading branch information
rustyrussell committed Aug 11, 2010
1 parent dca4130 commit d6d1b65
Show file tree
Hide file tree
Showing 7 changed files with 24 additions and 0 deletions.
10 changes: 10 additions & 0 deletions arch/um/drivers/hostaudio_kern.c
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,9 @@ static int hostaudio_open(struct inode *inode, struct file *file)
int ret;

#ifdef DEBUG
kparam_block_sysfs_write(dsp);
printk(KERN_DEBUG "hostaudio: open called (host: %s)\n", dsp);
kparam_unblock_sysfs_write(dsp);
#endif

state = kmalloc(sizeof(struct hostaudio_state), GFP_KERNEL);
Expand All @@ -199,9 +201,11 @@ static int hostaudio_open(struct inode *inode, struct file *file)
if (file->f_mode & FMODE_WRITE)
w = 1;

kparam_block_sysfs_write(dsp);
lock_kernel();
ret = os_open_file(dsp, of_set_rw(OPENFLAGS(), r, w), 0);
unlock_kernel();
kparam_unblock_sysfs_write(dsp);

if (ret < 0) {
kfree(state);
Expand Down Expand Up @@ -258,13 +262,17 @@ static int hostmixer_open_mixdev(struct inode *inode, struct file *file)
if (file->f_mode & FMODE_WRITE)
w = 1;

kparam_block_sysfs_write(mixer);
lock_kernel();
ret = os_open_file(mixer, of_set_rw(OPENFLAGS(), r, w), 0);
unlock_kernel();
kparam_unblock_sysfs_write(mixer);

if (ret < 0) {
kparam_block_sysfs_write(dsp);
printk(KERN_ERR "hostaudio_open_mixdev failed to open '%s', "
"err = %d\n", dsp, -ret);
kparam_unblock_sysfs_write(dsp);
kfree(state);
return ret;
}
Expand Down Expand Up @@ -320,8 +328,10 @@ MODULE_LICENSE("GPL");

static int __init hostaudio_init_module(void)
{
__kernel_param_lock();
printk(KERN_INFO "UML Audio Relay (host dsp = %s, host mixer = %s)\n",
dsp, mixer);
__kernel_param_unlock();

module_data.dev_audio = register_sound_dsp(&hostaudio_fops, -1);
if (module_data.dev_audio < 0) {
Expand Down
3 changes: 3 additions & 0 deletions drivers/net/wireless/libertas/if_usb.c
Original file line number Diff line number Diff line change
Expand Up @@ -289,10 +289,13 @@ static int if_usb_probe(struct usb_interface *intf,
}

/* Upload firmware */
kparam_block_sysfs_write(fw_name);
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");
goto err_prog_firmware;
}
kparam_unblock_sysfs_write(fw_name);

if (!(priv = lbs_add_card(cardp, &udev->dev)))
goto err_prog_firmware;
Expand Down
3 changes: 3 additions & 0 deletions drivers/net/wireless/libertas_tf/if_usb.c
Original file line number Diff line number Diff line change
Expand Up @@ -811,12 +811,15 @@ static int if_usb_prog_firmware(struct if_usb_card *cardp)

lbtf_deb_enter(LBTF_DEB_USB);

kparam_block_sysfs_write(fw_name);
ret = request_firmware(&cardp->fw, lbtf_fw_name, &cardp->udev->dev);
if (ret < 0) {
pr_err("request_firmware() failed with %#x\n", ret);
pr_err("firmware %s not found\n", lbtf_fw_name);
kparam_unblock_sysfs_write(fw_name);
goto done;
}
kparam_unblock_sysfs_write(fw_name);

if (check_fwfile_format(cardp->fw->data, cardp->fw->size))
goto release_fw;
Expand Down
2 changes: 2 additions & 0 deletions drivers/scsi/bfa/bfad.c
Original file line number Diff line number Diff line change
Expand Up @@ -788,6 +788,7 @@ bfad_drv_init(struct bfad_s *bfad)
memset(&driver_info, 0, sizeof(driver_info));
strncpy(driver_info.version, BFAD_DRIVER_VERSION,
sizeof(driver_info.version) - 1);
__kernel_param_lock();
if (host_name)
strncpy(driver_info.host_machine_name, host_name,
sizeof(driver_info.host_machine_name) - 1);
Expand All @@ -797,6 +798,7 @@ bfad_drv_init(struct bfad_s *bfad)
if (os_patch)
strncpy(driver_info.host_os_patch, os_patch,
sizeof(driver_info.host_os_patch) - 1);
__kernel_param_unlock();

strncpy(driver_info.os_device_name, bfad->pci_name,
sizeof(driver_info.os_device_name - 1));
Expand Down
2 changes: 2 additions & 0 deletions drivers/usb/atm/ueagle-atm.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;

kparam_block_sysfs_write(cmv_file);
/* set proper name corresponding modem version and line type */
if (cmv_file[sc->modem_index] == NULL) {
if (UEA_CHIP_VERSION(sc) == ADI930)
Expand All @@ -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);
if (ver == 2)
strlcat(cmv_name, ".v2", UEA_FW_NAME_MAX);
kparam_unblock_sysfs_write(cmv_file);
}

static int request_cmvs_old(struct uea_softc *sc,
Expand Down
2 changes: 2 additions & 0 deletions drivers/video/vt8623fb.c
Original file line number Diff line number Diff line change
Expand Up @@ -726,7 +726,9 @@ static int __devinit vt8623_pci_probe(struct pci_dev *dev, const struct pci_devi

/* Prepare startup mode */

kparam_block_sysfs_write(mode_option);
rc = fb_find_mode(&(info->var), info, mode_option, NULL, 0, NULL, 8);
kparam_unblock_sysfs_write(mode_option);
if (! ((rc == 1) || (rc == 2))) {
rc = -EINVAL;
dev_err(info->device, "mode %s not found\n", mode_option);
Expand Down
2 changes: 2 additions & 0 deletions net/mac80211/rate.c
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ ieee80211_rate_control_ops_get(const char *name)
struct rate_control_ops *ops;
const char *alg_name;

kparam_block_sysfs_write(ieee80211_default_rc_algo);
if (!name)
alg_name = ieee80211_default_rc_algo;
else
Expand All @@ -120,6 +121,7 @@ ieee80211_rate_control_ops_get(const char *name)
/* try built-in one if specific alg requested but not found */
if (!ops && strlen(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;
}
Expand Down

0 comments on commit d6d1b65

Please sign in to comment.