AIX 5.3 против Solaris 5.10 - реализация C strcat - PullRequest
0 голосов
/ 23 сентября 2010

Кто-нибудь знает, почему это могло произойти?

У меня есть программа на C в AIX 5.3, меня попросили запустить ее на машине SPARC Solaris 10, но когда я это сделал, я заметил переполнение буфера при одном из многих безрассудных действий strcat. Моя цель не в том, чтобы очистить код, а в том, чтобы дать конкретный и обоснованный ответ о том, почему это переполнение происходит в Solaris, а не в AIX, являющейся точно такой же плохо закодированной программой.

Я немного читал о том, может ли это быть вызвано:

  1. различия в порядках байтов между AIX и Solaris.

  2. Выполнение функции strcat (AIX копирует справа налево, а Solaris слева направо), но я не смог найти никакой документации по этому вопросу.

  3. Просто и повезло, что эта проблема не возникает в AIX.

Любой свет, который вы могли бы пролить на это, высоко ценится.

РЕДАКТИРОВАТЬ: можно ли этого избежать с помощью флага noexec_user_stack на солярисе?

РЕДАКТИРОВАТЬ 2: Кто-нибудь есть какая-либо информация о том, как обе операционные системы фактическое копирование байтов? в ситуации, подобной варианту 2 выше?

РЕДАКТИРОВАТЬ 3: Вот кусок кода:

/*global*/<br> char bufferA[101];<br> /*inside function*/<br> bufferA[0]='\0';<br> strcpy(bufferA,"1");<br> if (atoi(something)==0) {<br> strcat(bufferA,pieces_of_data);<br> count ++ ;<br> }

, очевидно, есть и больше, но это единственная часть, где используется bufferA, и есть две переменные, объявленные глобальными после bufferA, которые повреждаются, когда последняя часть последней строки добавляется в bufferA.

Как я уже говорил, если я изменю декларацию с 101 на 201, коррупция не произойдет.

РЕДАКТИРОВАТЬ 4: кто-нибудь знает что-нибудь о параметрах компилятора -misalign и -misalign2 в Solaris? может ли быть какой-либо свет с этими параметрами? На самом деле, лучший вопрос был бы: есть ли разница между AIX powerPC и Solaris SPARC в отношении выравнивания? Хотя, возможно, это вопрос к ошибке сервера, но, если вы что-то знаете, поделитесь, пожалуйста.

Ответы [ 5 ]

2 голосов
/ 23 сентября 2010

Это была (неудача?) Удача или, возможно, артефакт немного отличающихся систем управления памятью, когда в AIX было выделено больше места, чем в Solaris.

Частично это зависит от того, насколько вопиющими являются переполнения. Если они составляют пару байтов за пределами и , если AIX обычно выделяет, скажем, 32-байтовые минимальные блоки, где Solaris выделяет 16-байтовые минимальные блоки, то в AIX больше места для ошибок без ущерба, чем в Solaris , Тем не менее, если вы ошиблись в неправильном контексте, у AIX также должна быть проблема - вы можете считать себя несчастливым, если не заметили проблему в AIX, поскольку, как вы говорите, она, безусловно, возникает там так же, как и она. в Solaris, если исходный код, который вы компилируете, совпадает.

Дальнейшие исследования показывают:

  • Для 32-разрядных компиляций AIX 5.3 выделяет кратное 16 байтов на выделение, как в Solaris.
  • Для 64-битных компиляций AIX 5.3 выделяет кратное 32 байта для каждого выделения; это тоже самое что и солярис.

Однако, если вы переключились между 32-разрядной и 64-разрядной сборками между AIX и Solaris, это может быть источником вашей проблемы.

Каким бы ни был ответ, теперь вы знаете об этом, исправьте это для обеих платформ с одним набором изменений. Вы относитесь к каждой такой уязвимости с благодарностью; в любое время изменение исходной платформы может выявить проблему, что приведет к серьезным проблемам с недовольными клиентами.

(О, я думаю, что и SPARC, и PPC - машины с прямым порядком байтов; это Intel с прямым порядком байтов и они отличаются от остального мира.)


Тестовый код - с преднамеренной, преднамеренной утечкой

#include <stdlib.h>
#include <stdio.h>
int main(void)
{
    int sz ;
    char *buffer;
    for (sz = 1; sz < 1025; sz *= 2)
    {
        buffer = malloc(sz);
        printf("0x%08lX\n", (unsigned long)buffer);
    }   
    return 0;
} 
1 голос
/ 23 сентября 2010

Если это происходит на одной платформе, это происходит на другой. Вам просто повезло, что макет памяти на одной платформе вызвал ошибку к проявлению.

Это неопределенное поведение .

Если у вас есть дымящаяся насыпь неохраняемых strcpy / cats , засоряющих ваш код исправить код. Не вините платформу. Виноват автор.

Вальгринд твой друг.

0 голосов
/ 28 сентября 2010

Вот как вы можете использовать отладчик Solaris Studio для поиска ошибок доступа / использования памяти:

1: Download studio
  http://www.oracle.com/technetwork/server-storage/solarisstudio/overview/index.html
2: Install it
  Uncompress/Extract the downloaded file somewhere in your disk
  Run the installer
3: Recompile your program with debugging on
  $ PATH=$PATH:/opt/<studio-installation-directory>/bin
  $ cc -g program.c
4: Launch your program under debugger control
  $ dbx program
5: Enable run time checking
  (dbx) check -all
  access checking - ON
  memuse checking - ON
6: Run your program
  (dbx) run
7: Watch all the error messages
  ...
0 голосов
/ 23 сентября 2010

Это, вероятно, проявление ошибки, зависящее от процессора. Заполнение и выравнивание данных обычно определяются характеристиками целевого процессора. Дополнительные байты заполнения могут скрывать ошибку на одной цели, в то время как на другой цели меньше байтов заполнения.

Это также может быть связано с тем, что фактические данные, передаваемые strcat, отличаются. Например, если часть создаваемой строки должна состоять из имени ОС, процессора или пути к системному файлу.

Возможно также, что строки были распределены с размером, основанным либо на константе заголовка, либо на sizeof, который отличается для разных целей, поэтому ваш фактический буфер меньше.

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

0 голосов
/ 23 сентября 2010

Я не уверен, считается ли это ответом или нет, но быстрое и грязное исправление может заключаться в поиске и замене всех экземпляров malloc в коде на workaround_malloc и реализациипоследний как вызов malloc(size+100) ..: -)

...