П О Р Т А Л                            
С Е Т Е В Ы Х                          
П Р О Е К Т О В                        
  
                                                 
Главная

О проекте

Web-мастеру
     HTML & JavaScript
     SSI
     Perl
     PHP
     XML & XSLT
     Unix Shell

MySQL

Безопасность

Хостинг

Другое







Самое читаемое:

Учебник PHP - "Для Чайника".
Просмотров 30484 раз(а).

Иллюстрированный самоучитель по созданию сайтов.
Просмотров 9551 раз(а).

Учебник HTML.
Просмотров 16492 раз(а).

Руководство по PHP5.
Просмотров 8320 раз(а).

Хостинг через призму DNS.
Просмотров 12026 раз(а).

Подборка текстов стандартных документов.
Просмотров 12654 раз(а).

Учебник PHP - Самоучитель
Просмотров 8811 раз(а).

Документация на MySQL (учебник & справочное руководство)
Просмотров 6470 раз(а).

Внешние атаки...
Просмотров 5551 раз(а).

Учебник PHP.
Просмотров 6983 раз(а).

SSI в примерах.
Просмотров 4079 раз(а).






 
 

Решение

Не всегда легко найти замену функции system(). Первый вариант - использовать системные вызовы такие как execl() или execle(). Однако это будет совсем не то, так как внешняя программа будет вызываться не как подпрограмма, а будет заменять текущий процесс. Вам придется создать новый процесс при помощи fork и проанализировать аргументы командной строки. Таким образом программа:

  if (system ("/bin/lpr -Plisting stats.txt") != 0) {
    perror ("Printing");
    return (-1);
  }

превращается:
pid_t pid;
int   status;

if ((pid = fork()) < 0) {
  perror("fork");
  return (-1);
}
if (pid == 0) {
  /* дочерний процесс */
  execl ("/bin/lpr", "lpr", "-Plisting", "stats.txt", NULL);
  perror ("execl");
  exit (-1);
}
/* родительский процесс */
waitpid (pid, & status, 0);
if ((! WIFEXITED (status)) || (WEXITSTATUS (status) != 0)) {
  perror ("Printing");
  return (-1);
}

Очевидно, код стал тяжелее! В некоторых ситуациях он становиться довольно сложным, например, когда вам надо перенаправить стандартный вход приложения, как например:
system ("mail root < stat.txt");

То есть перенаправление обозначенное < делается оболочкой. Вы можете делать то же используя сложную последовательность такую как fork(), open(), dup2(), execl() и т.д. В таком случае, приемлемым решением будет использование функции system(), но с предварительной конфигурацией всего окружения.

Под Linux переменные окружения хранятся в форме указателя на таблицу символов: char ** environ. Эта таблица заканчивается NULL. Строки хранятся в форме "ИМЯ=значение".

Мы начинаем удаление окружения при помощи Gnu расширения:

    int clearenv (void);

или присваивая указателю
    extern char ** environ;

значение NULL. Далее инициализируются важные переменные окружения, используя контролируемые значения, при помощи функций:
    int setenv (const char * name, const char * value, int remove)
    int putenv(const char *string)

перед вызовом функции system(). Например:
    clearenv ();
    setenv ("PATH", "/bin:/usr/bin:/usr/local/bin", 1);
    setenv ("IFS", " \t\n", 1);
    system ("mail root < /tmp/msg.txt");

Если необходимо, вы можете сохранить содержимое некоторых полезных переменных перед очищением окружения (HOME, LANG, TERM, TZ и т.д.). Содержимое, форма представления, размер этих переменных должны быть строго проверены. Это важно, что вы очищаете все окружение перед переопределением нужных переменных. Дыра в suidperl не появилась бы, если должным образом было бы очищено окружение.

По аналогии, защита машины в сети, во-первых, предпологает запрет всякого подключения. Затем, сисадмин активизирует необходимые или полезные сервисы. Тем же методом, при программировании Set-UID приложения окружение должно быть очищено, а затем заполнено нужными переменными.

Проверка формата параметра происходит при помощи сравнения ожидаемого значения с разрешенными форматами. Если сравнение успешно, параметр принимается. Иначе он отвергается. Если вы запускаете тест, используя список неправильных значений формата, возрастает риск передачи неправильного значения, что может привести к краху системы.

Мы должны понимать, не забывая о переменной PATH, что опасность использования system() сохраняется при использовании некоторых производных функций таких как popen() или системных вызовов, например, execlp() или execvp().

Назад | Содержание | Вперед



 



Copyright © 2005-2007 Project.Net.Ru