[CRIU] [PATCH 01/23] criu/filesystems.c: refactor binfmt_misc_restore_bme
Kirill Tkhai
ktkhai at virtuozzo.com
Wed Oct 12 08:52:50 PDT 2016
On 12.10.2016 18:45, Kir Kolyshkin wrote:
> On 10/12/2016 02:14 AM, Kirill Tkhai wrote:
>>
>> On 12.10.2016 04:46, Kir Kolyshkin wrote:
>>> The following error is emitted by clang:
>>>
>>>> CC criu/filesystems.o
>>>> criu/filesystems.c:280:13: error: variable 'ret' is used uninitialized
>>>> whenever 'if' condition is false [-Werror,-Wsometimes-uninitialized]
>>>> } else if (bme->extension) {
>>>> ^~~~~~~~~~~~~~
>>>> criu/filesystems.c:287:6: note: uninitialized use occurs here
>>>> if (ret > 0) {
>>>> ^~~
>>>> criu/filesystems.c:280:9: note: remove the 'if' if its condition is
>>>> always true
>>>> } else if (bme->extension) {
>>>> ^~~~~~~~~~~~~~~~~~~~
>>>> criu/filesystems.c:272:9: note: initialize the variable 'ret' to silence
>>>> this warning
>>>> int ret;
>>>> ^
>>>> = 0
>>>> 1 error generated.
>>> This code was a result of commit 398e7d3.
>>>
>>> If we look closely, this is a false alarm, as "else if (bme->extension)"
>>> is always true as it was checked before. But this is not very clear,
>>> and the issue with clangs still needs to be fixed.
>>>
>>> There are many ways to do so:
>>>
>>> 1. Initialize ret to 0. This is what initial version of this patch did.
>>>
>>> 2. Remove the always-true condition, like this:
>>>
>>> - } else if (bme->extension) {
>>> + } else {
>>>
>>> In my opinion this would hurt readability.
>>>
>>> 3. Change the code flow, improving readability at the same time.
>>>
>>> I believe that #3 is what this patch does. In addition, it fixes
>>> handling of a few corner cases:
>>>
>>> - an overflow in snprintf();
>>> - a case when bme->name is NULL (as it is used for strlen/snprintf,
>>> there is a potential for SIGSEGV);
>>> - a case of ret == 0 (currently there is no code flow that
>>> results in ret being 0, so it's just for the future).
>>>
>>> Cc: Kirill Tkhai <ktkhai at virtuozzo.com>
>>> Signed-off-by: Kir Kolyshkin <kir at openvz.org>
>>> ---
>>> criu/filesystems.c | 30 ++++++++++++++++++++----------
>>> 1 file changed, 20 insertions(+), 10 deletions(-)
>>>
>>> diff --git a/criu/filesystems.c b/criu/filesystems.c
>>> index d66a6c6..cabfbf2 100644
>>> --- a/criu/filesystems.c
>>> +++ b/criu/filesystems.c
>>> @@ -271,25 +271,35 @@ static int binfmt_misc_restore_bme(struct mount_info *mi, BinfmtMiscEntry *bme,
>>> {
>>> int ret;
>>> - /* :name:type:offset:magic/extension:mask:interpreter:flags */
>>> - if ((!bme->magic && !bme->extension) || !bme->interpreter) {
>>> - pr_perror("binfmt_misc: bad dump");
>>> - ret = -1;
>>> - } else if (bme->magic) {
>>> + if (!bme->name || !bme->interpreter)
>>> + goto bad_dump;
>>> +
>>> + /* Either magic or extension should be there */
>>> + if (bme->magic) {
>>> ret = make_bfmtm_magic_str(buf, bme);
>>> - } else if (bme->extension) {
>>> + }
>>> + else if (bme->extension) {
>> Don't we use a specific style for "} else" condition? Currently,
>> the most place are:
>>
>> } else
>>
>> and not
>>
>> }
>> else
>
> Thanks for noting it, as I was paying attention, too. Looked around in the code and found that both forms are used. If the one you want is preferable, I am to resend the fixed version.
As I see, the most places in ./criu directory use kernel style. The only exceptions are in ./criu/arch/ppc64.
My opinion, the only style is better, and I'd prefer the kernel style.
>
>>
>>> /* :name:E::extension::interpreter:flags */
>>> ret = snprintf(buf, BINFMT_MISC_STR, ":%s:E::%s::%s:%s",
>>> bme->name, bme->extension, bme->interpreter,
>>> bme->flags ? : "\0");
>>> + if (ret >= BINFMT_MISC_STR) // output truncated
>>> + ret = -1;
>>> }
>>> + else
>>> + ret = -1;
>>> - if (ret > 0) {
>>> - pr_debug("binfmt_misc_pattern=%s\n", buf);
>>> - ret = write_binfmt_misc_entry(mi->mountpoint, buf, bme);
>>> - }
>>> + if (ret < 0)
>>> + goto bad_dump;
>>> +
>>> + pr_debug("binfmt_misc_pattern=%s\n", buf);
>>> + ret = write_binfmt_misc_entry(mi->mountpoint, buf, bme);
>>> return ret;
>>> +
>>> +bad_dump:
>>> + pr_perror("binfmt_misc: bad dump");
>>> + return -1;
>>> }
>>> static int binfmt_misc_restore(struct mount_info *mi)
>>>
>
More information about the CRIU
mailing list