Bug 188611 - Function extcon_sync() returns an improper value when the call to get_zeroed_page() fails.
Summary: Function extcon_sync() returns an improper value when the call to get_zeroed_...
Status: RESOLVED CODE_FIX
Alias: None
Product: Drivers
Classification: Unclassified
Component: Other (show other bugs)
Hardware: All Linux
: P1 normal
Assignee: drivers_other
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2016-11-25 10:41 UTC by bianpan
Modified: 2017-05-11 09:29 UTC (History)
0 users

See Also:
Kernel Version: linux-4.9-rc6
Subsystem:
Regression: No
Bisected commit-id:


Attachments
The patch fixes the bug (1.12 KB, patch)
2017-05-11 09:29 UTC, bianpan
Details | Diff

Description bianpan 2016-11-25 10:41:32 UTC
When there is no enough memory, function get_zeroed_page() will return a NULL pointer. In function extcon_sync() defined in file drivers/extcon/extcon.c, it returns 0 when the call to get_zeroed_page() (at line 448) returns a NULL pointer. 0 means success, which seems incorrect. Use "return -ENOMEM;" instead of "return 0" at line 456? Codes related to this bug are summarised as follows.

extcon_sync @@ drivers/extcon/extcon.c
 423 int extcon_sync(struct extcon_dev *edev, unsigned int id)
 424 {
         ...
 435     if (!edev)
 436         return -EINVAL;
 437 
 438     index = find_cable_index_by_id(edev, id);
 439     if (index < 0)
 440         return index;
 441 
 442     spin_lock_irqsave(&edev->lock, flags);
 443 
 444     state = !!(edev->state & BIT(index));
 445     raw_notifier_call_chain(&edev->nh[index], state, edev);
 446 
 447     /* This could be in interrupt handler */
 448     prop_buf = (char *)get_zeroed_page(GFP_ATOMIC);
 449     if (!prop_buf) {
 450         /* Unlock early before uevent */
 451         spin_unlock_irqrestore(&edev->lock, flags);
 452 
 453         dev_err(&edev->dev, "out of memory in extcon_set_state\n");
 454         kobject_uevent(&edev->dev.kobj, KOBJ_CHANGE);
 455 
 456         return 0;       // return -ENOMEM?
 457     }
         ...
 476     /* Unlock early before uevent */
 477     spin_unlock_irqrestore(&edev->lock, flags);
 478     kobject_uevent_env(&edev->dev.kobj, KOBJ_CHANGE, envp);
 479     free_page((unsigned long)prop_buf);
 480 
 481     return 0;
 482 }

Thanks very much!
Comment 1 bianpan 2017-05-11 09:29:19 UTC
Created attachment 256381 [details]
The patch fixes the bug

The patch has been merged into the lastest kernel version. So I will close it.

Note You need to log in before you can comment on or make changes to this bug.