[PATCH] request_firmware(): avoid race conditions

Avoid race occurs when some process have open file descriptor for class
device attributes and already firmware allocated memory are freed. Don't
allow negative loading timeout.

Signed-off-by: Stanislaw W. Gruszka <stf_xl@wp.pl>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>

authored by Stanislaw W. Gruszka and committed by Linus Torvalds b92eac01 bcc8ca09

+10 -3
+10 -3
drivers/base/firmware_class.c
··· 74 74 firmware_timeout_store(struct class *class, const char *buf, size_t count) 75 75 { 76 76 loading_timeout = simple_strtol(buf, NULL, 10); 77 + if (loading_timeout < 0) 78 + loading_timeout = 0; 77 79 return count; 78 80 } 79 81 ··· 140 138 switch (loading) { 141 139 case 1: 142 140 down(&fw_lock); 141 + if (!fw_priv->fw) { 142 + up(&fw_lock); 143 + break; 144 + } 143 145 vfree(fw_priv->fw->data); 144 146 fw_priv->fw->data = NULL; 145 147 fw_priv->fw->size = 0; ··· 184 178 185 179 down(&fw_lock); 186 180 fw = fw_priv->fw; 187 - if (test_bit(FW_STATUS_DONE, &fw_priv->status)) { 181 + if (!fw || test_bit(FW_STATUS_DONE, &fw_priv->status)) { 188 182 ret_count = -ENODEV; 189 183 goto out; 190 184 } ··· 244 238 245 239 if (!capable(CAP_SYS_RAWIO)) 246 240 return -EPERM; 241 + 247 242 down(&fw_lock); 248 243 fw = fw_priv->fw; 249 - if (test_bit(FW_STATUS_DONE, &fw_priv->status)) { 244 + if (!fw || test_bit(FW_STATUS_DONE, &fw_priv->status)) { 250 245 retval = -ENODEV; 251 246 goto out; 252 247 } ··· 425 418 426 419 fw_priv = class_get_devdata(class_dev); 427 420 428 - if (loading_timeout) { 421 + if (loading_timeout > 0) { 429 422 fw_priv->timeout.expires = jiffies + loading_timeout * HZ; 430 423 add_timer(&fw_priv->timeout); 431 424 }