lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date:   Thu, 11 Mar 2021 12:28:39 +0100
From:   Michal Simek <michal.simek@...inx.com>
To:     Colin Ian King <colin.king@...onical.com>,
        Michal Simek <michal.simek@...inx.com>
CC:     Linus Walleij <linus.walleij@...aro.org>,
        "linux-gpio@...r.kernel.org" <linux-gpio@...r.kernel.org>,
        "linux-kernel@...r.kernel.org" <linux-kernel@...r.kernel.org>
Subject: Re: pinctrl: core: Handling pinmux and pinconf separately



On 3/11/21 12:24 PM, Colin Ian King wrote:
> On 11/03/2021 11:16, Michal Simek wrote:
>>
>>
>> On 3/11/21 11:57 AM, Colin Ian King wrote:
>>> Hi,
>>>
>>> Static analysis on linux-next with Coverity has found a potential issue
>>> in drivers/pinctrl/core.c with the following commit:
>>>
>>> commit 0952b7ec1614abf232e921aac0cc2bca8e60e162
>>> Author: Michal Simek <michal.simek@...inx.com>
>>> Date:   Wed Mar 10 09:16:54 2021 +0100
>>>
>>>     pinctrl: core: Handling pinmux and pinconf separately
>>>
>>> The analysis is as follows:
>>>
>>> 1234 /**
>>> 1235  * pinctrl_commit_state() - select/activate/program a pinctrl state
>>> to HW
>>> 1236  * @p: the pinctrl handle for the device that requests configuration
>>> 1237  * @state: the state handle to select/activate/program
>>> 1238  */
>>> 1239 static int pinctrl_commit_state(struct pinctrl *p, struct
>>> pinctrl_state *state)
>>> 1240 {
>>> 1241        struct pinctrl_setting *setting, *setting2;
>>> 1242        struct pinctrl_state *old_state = p->state;
>>>
>>>     1. var_decl: Declaring variable ret without initializer.
>>>
>>> 1243        int ret;
>>> 1244
>>>
>>>     2. Condition p->state, taking true branch.
>>>
>>> 1245        if (p->state) {
>>> 1246                /*
>>> 1247                 * For each pinmux setting in the old state, forget
>>> SW's record
>>> 1248                 * of mux owner for that pingroup. Any pingroups
>>> which are
>>> 1249                 * still owned by the new state will be re-acquired
>>> by the call
>>> 1250                 * to pinmux_enable_setting() in the loop below.
>>> 1251                 */
>>>
>>>     3. Condition 0 /* !!(!__builtin_types_compatible_p() &&
>>> !__builtin_types_compatible_p()) */, taking false branch.
>>>     4. Condition !(&setting->node == &p->state->settings), taking true
>>> branch.
>>>     7. Condition 0 /* !!(!__builtin_types_compatible_p() &&
>>> !__builtin_types_compatible_p()) */, taking false branch.
>>>     8. Condition !(&setting->node == &p->state->settings), taking true
>>> branch.
>>>     11. Condition 0 /* !!(!__builtin_types_compatible_p() &&
>>> !__builtin_types_compatible_p()) */, taking false branch.
>>>     12. Condition !(&setting->node == &p->state->settings), taking false
>>> branch.
>>>
>>> 1252                list_for_each_entry(setting, &p->state->settings,
>>> node) {
>>>
>>>     5. Condition setting->type != PIN_MAP_TYPE_MUX_GROUP, taking true
>>> branch.
>>>     9. Condition setting->type != PIN_MAP_TYPE_MUX_GROUP, taking true
>>> branch.
>>> 1253                        if (setting->type != PIN_MAP_TYPE_MUX_GROUP)
>>>     6. Continuing loop.
>>>     10. Continuing loop.
>>>
>>> 1254                                continue;
>>> 1255                        pinmux_disable_setting(setting);
>>> 1256                }
>>> 1257        }
>>> 1258
>>> 1259        p->state = NULL;
>>> 1260
>>> 1261        /* Apply all the settings for the new state - pinmux first */
>>>
>>>     13. Condition 0 /* !!(!__builtin_types_compatible_p() &&
>>> !__builtin_types_compatible_p()) */, taking false branch.
>>>     14. Condition !(&setting->node == &state->settings), taking true branch.
>>> 1262        list_for_each_entry(setting, &state->settings, node) {
>>>     15. Switch case value PIN_MAP_TYPE_CONFIGS_PIN.
>>>
>>> 1263                switch (setting->type) {
>>> 1264                case PIN_MAP_TYPE_MUX_GROUP:
>>> 1265                        ret = pinmux_enable_setting(setting);
>>> 1266                        break;
>>> 1267                case PIN_MAP_TYPE_CONFIGS_PIN:
>>> 1268                case PIN_MAP_TYPE_CONFIGS_GROUP:
>>>
>>>     16. Breaking from switch.
>>>
>>> 1269                        break;
>>> 1270                default:
>>> 1271                        ret = -EINVAL;
>>> 1272                        break;
>>> 1273                }
>>> 1274
>>>
>>>     Uninitialized scalar variable (UNINIT)
>>>     17. uninit_use: Using uninitialized value ret.
>>>
>>> 1275                if (ret < 0)
>>> 1276                        goto unapply_new_state;
>>>
>>> For the PIN_MAP_TYPE_CONFIGS_PIN and PIN_MAP_TYPE_CONFIGS_GROUP
>>> setting->type cases the loop can break out with ret not being set. Since
>>> ret has not been initialized it the ret < 0 check is checking against an
>>> uninitialized value.
>>>
>>> I was not sure if the PIN_MAP_TYPE_CONFIGS_PIN and
>>> PIN_MAP_TYPE_CONFIGS_GROUP cases should be setting ret and if so, what
>>> the value of ret should be set to (is it an error condition or not?). Or
>>> should ret be initialized to 0 or a default error value at the start of
>>> the function.
>>>
>>> Hence I'm reporting this issue.
>>
>> What about this? Is this passing static analysis?
> 
> It will take me 2 hours to re-run the analysis, but from eyeballing the
> code I think the assignments will fix this.

would be good if you can rerun it and get back to us on this.
I will wait if something else will pop up and then will send v2 with
this that Linus can apply this one instead.

Thanks,
Michal



Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ