LINUX.ORG.RU

История изменений

Исправление MOPKOBKA, (текущая версия) :

На каждый указатель нужно еще две переменные, которые будут хранить диапазон буфера, на который ссылается указатель.

Проверка на ошибку записи будет такой:

Аргумент АдресЗаписи
 
ФлагОшибки = ПроверкаПересечения(
  АдресЗаписи,
  ИсключитьДиапазон(ДиапазонСтека, ДиапазонБуфера)
)

Поэтому если память выделена через alloca() или указывает на массив в стеке, то передав его диапазон в памяти ДиапазонБуфера, мы вырежем этот диапазон из стека, и запись по нему не будет считаться ошибкой.

Для памяти не из стека, ДиапазонБуфера будет 0...0, и следовательно любая запись в стек будет являться ошибкой.

Именно как дополнительные аргументы у функции это лучше не делать, возможно стоит завести какую то область в памяти дополнительную, в стеке, что бы на нее распространялись эти проверки. Назовем эту область памяти SafePtrArea.

При сохранении указателя на стековый буфер в структуру, мы ее расширить не можем, это много чего поломает, но мы можем в SafePtrArea записать информацию о параметрах указателя, и пометить структуру где мы храним указатель отметкой «хранит указатели которые могут указывать на стек». И при чтении указателей из этой структуры, проверять SafePtrArea на наличие в ней этого указателя, и вынимать заодно информацию для передачи дальше по функциям.

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

Исправление MOPKOBKA, :

На каждый указатель нужно еще две переменные, которые будут хранить диапазон буфера, на который ссылается указатель.

Проверка на ошибку записи будет такой:

Аргумент АдресЗаписи
 
ФлагОшибки = ПроверкаПересечения(
  АдресЗаписи,
  ИсключитьДиапазон(ДиапазонСтека, ДиапазонБуфера)
)

Поэтому если память выделена через alloca() или указывает на массив в стеке, то передав его диапазон в памяти ДиапазонБуфера, мы вырежем этот диапазон из стека, и запись по нему не будет считаться ошибкой.

Для памяти не из стека, ДиапазонБуфера будет 0...0, и следовательно любая запись в стек будет являться ошибкой.

Именно как дополнительные аргументы у функции это лучше не делать, возможно стоит завести какую то область в памяти дополнительную, в стеке, что бы на нее распространялись эти проверки. Назовем эту область памяти SafePtrArea.

При сохранении указателя на стековый буфер в структуру, мы уж точно ее расширить не сможем, но мы можем в SafePtrArea записать информацию о параметрах указателя, и пометить структуру где мы храним указатель отметкой «хранит указатели которые могут указывать на стек». И при чтении указателей из этой структуры, проверять SafePtrArea на наличие в ней этого указателя, и вынимать заодно информацию для передачи дальше по функциям.

Исправление MOPKOBKA, :

На каждый указатель нужно еще две переменные, которые будут хранить диапазон буфера, на который ссылается указатель.

Проверка на ошибку записи будет такой:

Аргумент АдресЗаписи
 
ФлагОшибки = ПроверкаПересечения(
  АдресЗаписи,
  ИсключитьДиапазон(ДиапазонСтека, ДиапазонБуфера)
)

Поэтому если память выделена через alloca() или указывает на массив в стеке, то передав его диапазон в памяти

ДиапазонБуфера
, мы вырежем этот диапазон из стека, и запись по нему не будет считаться ошибкой.

Для памяти не из стека, ДиапазонБуфера будет 0...0, и следовательно любая запись в стек будет являться ошибкой.

Именно как дополнительные аргументы у функции это лучше не делать, возможно стоит завести какую то область в памяти дополнительную, в стеке, что бы на нее распространялись эти проверки. Назовем эту область памяти SafePtrArea.

При сохранении указателя на стековый буфер в структуру, мы уж точно ее расширить не сможем, но мы можем в SafePtrArea записать информацию о параметрах указателя, и пометить структуру где мы храним указатель отметкой «хранит указатели которые могут указывать на стек». И при чтении указателей из этой структуры, проверять SafePtrArea на наличие в ней этого указателя, и вынимать заодно информацию для передачи дальше по функциям.

Исходная версия MOPKOBKA, :

На каждый указатель нужно еще две переменные, которые будут хранить диапазон буфера, на который ссылается указатель.

Проверка на ошибку записи будет такой:

Аргумент АдресЗаписи
 
ФлагОшибки = ПроверкаПересечения(
  АдресЗаписи,
  ИсключитьДиапазон(ДиапазонСтека, ДиапазонБуфера)
)

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

Для памяти не из стека, ДиапазонБуфера будет 0...0, и следовательно любая запись в стек будет являться ошибкой.

Именно как дополнительные аргументы у функции это лучше не делать, возможно стоит завести какую то область в памяти дополнительную, в стеке, что бы на нее распространялись эти проверки. Назовем эту область памяти SafePtrArea.

При сохранении указателя на стековый буфер в структуру, мы уж точно ее расширить не сможем, но мы можем в SafePtrArea записать информацию о параметрах указателя, и пометить структуру где мы храним указатель отметкой «хранит указатели которые могут указывать на стек». И при чтении указателей из этой структуры, проверять SafePtrArea на наличие в ней этого указателя, и вынимать заодно информацию для передачи дальше по функциям.