<?xml version="1.0" encoding="UTF-8" ?>

<bugzilla version="5.2"
          urlbase="https://bugzilla.altlinux.org/"
          
          maintainer="jenya@basealt.ru"
>

    <bug>
          <bug_id>49446</bug_id>
          
          <creation_ts>2024-02-19 09:18:46 +0300</creation_ts>
          <short_desc>Программа не завершается и находится в бесконечном цикле</short_desc>
          <delta_ts>2024-02-24 21:23:57 +0300</delta_ts>
          <reporter_accessible>1</reporter_accessible>
          <cclist_accessible>1</cclist_accessible>
          <classification_id>4</classification_id>
          <classification>Development</classification>
          <product>Sisyphus</product>
          <component>osec</component>
          <version>unstable</version>
          <rep_platform>x86_64</rep_platform>
          <op_sys>Linux</op_sys>
          <bug_status>CLOSED</bug_status>
          <resolution>FIXED</resolution>
          
          
          <bug_file_loc></bug_file_loc>
          <status_whiteboard></status_whiteboard>
          <keywords></keywords>
          <priority>P5</priority>
          <bug_severity>normal</bug_severity>
          <target_milestone>---</target_milestone>
          
          
          <everconfirmed>1</everconfirmed>
          <reporter name="Корытов Иван">boot.efi</reporter>
          <assigned_to name="Alexey Gladkov">legion</assigned_to>
          <cc>legion</cc>
    
    <cc>obidinog</cc>
          
          <qa_contact>qa-sisyphus</qa_contact>

      

      

      

          <comment_sort_order>oldest_to_newest</comment_sort_order>  
          <long_desc isprivate="0" >
    <commentid>241778</commentid>
    <comment_count>0</comment_count>
    <who name="Корытов Иван">boot.efi</who>
    <bug_when>2024-02-19 09:18:46 +0300</bug_when>
    <thetext>При повреждении базы данных, программа пытается закрыть файл базы данных, который уже был ранее закрыт и входит в бесконечный цикл.

Команда, которая использовалась для запуска:
/usr/bin/osec -X /etc/osec/exclude.conf -D /var/lib/osec -f /etc/osec/dirs.conf

Версия: 1.3.1-alt2

Шаги для воспроизведения:
1. Установить osec и запустить, чтобы создать базы данных файлов
2. Намеренно повредить одну из баз данных
   dd if=/dev/zero of=/var/lib/osec/osec.cdb.%2Flib count=10K
3. Запустить программу повторно

Ожидаемый результат: программа завершается успешно или с предупреждениями
Полученный результат: программа не завершается и бесконечно выводит сообщение об ошибке

&gt;  osec: file not look like osec database: /var/lib/osec/osec.cdb.%2Flib
&gt;  osec: close: (null): Bad file descriptor
&gt;  osec: close: /var/lib/osec/osec.cdb.%2Flib :Bad file descriptor
&gt;  osec: close: /var/lib/osec/osec.cdb.%2Flib :Bad file descriptor
&gt;  ...
&gt;  osec: close: /var/lib/osec/osec.cdb.%2Flib :Bad file descriptor

Почему изначально были повреждены базы данных - неизвестно. Один из файлов состоял полностью из нулей, другой - частично.

Описание проблемы в файле src/osec.c:

Программа проверяет, что открываемый файл является базой данных и из-за неверных данных переходит на метку end.

&gt;	if (!compat_db_version(old_fd)) {
&gt;		osec_error(&quot;file not look like osec database: %s&quot;, old_dbname);
&gt;		goto end;
&gt;	}

На метке end она успешно закрывает файл с путем из переменной old_dbname и дескриптором old_fd:

&gt;	if (old_fd != -1 &amp;&amp; close(old_fd) == -1) {
&gt;		osec_error(&quot;close: %s :%m&quot;, old_dbname);
&gt;		goto end;
&gt;	}

Затем, программа пытается закрыть файл с путем из переменной new_dbname и дескриптором new_fd:

&gt;	if (close(new_fd) == -1) {
&gt;		osec_error(&quot;close: %s: %m&quot;, new_dbname);
&gt;		goto end;
&gt;	}

Закрытие файла завершается с ошибкой, т.к. и дескриптор, и путь &quot;new&quot; заданы пустыми в начале функции:

&gt;	new_fd = old_fd = -1;
&gt;	new_dbname = NULL;

После вывода сообщения программа переходит к метке end. Так как файл &quot;old&quot; уже успешно закрыт, а переменная old_fd не очищена, то функция close завершается с оибкой и выводится сообщение уже с путем old_dbname. И программа вновь переходит к метке end, не очищая переменные с дескрипторами, что приводит к бесконечному циклу (переходу к метке).

Функция close не очищает передаваемый дескриптор при возникновении ошибки, т.к. он передается по значению, а не по ссылке.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>241853</commentid>
    <comment_count>1</comment_count>
    <who name="obidinog@basealt.ru">obidinog</who>
    <bug_when>2024-02-20 12:49:17 +0300</bug_when>
    <thetext>Стенд:
kworkstation-10.2.1-x86-64 Обновленный до Sisyphus
Пакет:
osec 1.3.1-alt3

Ошибка воспроизводится по вышеуказанным шагам</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>242006</commentid>
    <comment_count>2</comment_count>
    <who name="Alexey Gladkov">legion</who>
    <bug_when>2024-02-23 17:47:19 +0300</bug_when>
    <thetext>Да, какой-то странный код. `goto end` у close вообще лишний.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>242051</commentid>
    <comment_count>3</comment_count>
    <who name="Repository Robot">repository-robot</who>
    <bug_when>2024-02-24 21:23:57 +0300</bug_when>
    <thetext>osec-1.3.2-alt1 -&gt; sisyphus:

 Sat Feb 24 2024 Alexey Gladkov &lt;legion@altlinux.ru&gt; 1.3.2-alt1
 - New version (1.3.2).
 - Fix infinite loop (ALT#49446).</thetext>
  </long_desc>
      
      

    </bug>

</bugzilla>