avva: (moose)
[personal profile] avva
Прикольно - оказывается, инструкция idiv, деление со знаком, на x86 кидает исключение не только при делении на ноль, но и когда результат не помещается в регистр. А этого очень легко добиться, написав в C например INT_MIN / -1. Как мы помним, INT_MIN по модулю на единицу больше, чем INT_MAX; например, в 32-битных числах INT_MIN равно -2147483648, а INT_MAX равно 2147483647. Поэтому когда INT_MIN делят на -1, положительный результат не вмещается в 32 бита.

Само по себе это не катастрофа - ну кидает исключение, ну и подумаешь. Дело в том, однако, что про деление на ноль все знают и помнят, и проверяют перед попыткой делить. А против INT_MIN/-1 никто практически не защищается. Поэтому можно, например:

- крэшнуть компилятор (правда, игрушечный), PostgreSQL (не игрушечную) или антивирус;
- подвесить Windows 8;
- убить bash

Date: 2013-01-30 07:48 am (UTC)
spamsink: (Default)
From: [personal profile] spamsink
Даже с /Ox?

Date: 2013-01-30 08:08 am (UTC)
From: [identity profile] ircicq.livejournal.com
от опций /O не зависит работоспособность корректных программ.

если делим Int64/Int32, то IDIV напрямую никогда не используется, хотя именно эту операцию он реализует.

Если делим Int32/Int32, IDIV используется и генерится исключение в случае переполнения результата.

Не видно, что и каким образом здесь возможно улучшить на уровне работы CPU.

Date: 2013-01-30 08:24 am (UTC)
spamsink: (Default)
From: [personal profile] spamsink
Никакие операции с целыми числами, кроме обсуждаемой, не генерируют исключение в случае переполнения результата, поэтому я и утверждаю, что и деление MIN_INT на -1 на уровне пользовательской программы не должно. Как это будет конкретно реализовано - патчем ли микропрограммы, перепрыгиванием ли через команду, вызвавшую прерывание, в обработчике в ядре - дело десятое.

Date: 2013-01-30 08:37 am (UTC)
From: [identity profile] ircicq.livejournal.com
Ну скажем так: ADD, SUB, MUL не генерируют Overflow потому, что есть полезное применение усеченного результата, например в арифметике длинных чисел.

Полезного применения INT_MIN/-1 не видно, и потому логичнее сигнализировать об ошибке
Edited Date: 2013-01-30 08:37 am (UTC)

Date: 2013-01-30 08:48 am (UTC)
From: [identity profile] archaicos.livejournal.com
Можно попросить компилятор генерировать инструкцию INTO после инструкций сложения и вычитания целых со знаком - будет исключение на каждом переполнении (в gcc была опция для этого). Наверное и с умножением будет работать. Аналогичное может быть и при впихивании невпихуемого в целое со знаком (стандарт C разрешает тут кинуть сигнал). Т.е. результат зависит от процессора, системы и компилятора.

Date: 2013-01-30 03:49 pm (UTC)
spamsink: (Default)
From: [personal profile] spamsink
Речь, опять же, не о том, что можно генерировать, а о том, что есть проблема: масса программ, принимающих данные от пользователей, не проверяет на сочетание MIN_INT/-1, и потому подвержена атаке. Я предлагаю, что можно сделать для защиты от этой атаки.

Date: 2013-01-30 04:04 pm (UTC)
From: [identity profile] archaicos.livejournal.com
Увы, мало что можно сделать постфактум, не имея контроля над этой массой и ещё большей массой её пользователей. Игнорирование этого исключения не всегда однозначно снизит риск. Продолжение работы с неправильными данными может риск и повысить - зависит от самой программы и от того, как она взаимодействует со своим окружением.

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

Надеюсь, ты не думаешь, что writing secure code - это просто, и что о security думают все программисты, чей код потенциально под ударом?

Date: 2013-01-30 04:18 pm (UTC)
spamsink: (Default)
From: [personal profile] spamsink
Повысить уж точно не может. Ну станет можно написать MIN_INT/-1, получая (без исключения) тот же MIN_INT, что и получаемый нынче без исключения результат деления MIN_INT на 1, что за беда?

Я думаю, что писать безопасный код - сложно, поэтому нужно защищаться не только кодом, но и системными средствами.

Date: 2013-01-30 04:24 pm (UTC)
From: [identity profile] archaicos.livejournal.com
> Повысить уж точно не может.

Если точно, докажи.

Иногда упавший сервис можно перезапустить, откатив при этом выполняющиеся транзакции. Неправильное число иногда может привести к тому, что например, стырят данные или деньги. Или пациента облучат до лучевой болезни.
Edited Date: 2013-01-30 04:25 pm (UTC)

Date: 2013-01-30 04:44 pm (UTC)
spamsink: (Default)
From: [personal profile] spamsink
Это может произойти и сейчас; ничего нового возвращение MIN_INT еще в одном случае не привносит.

Date: 2013-01-30 03:17 pm (UTC)
From: [identity profile] huzhepidarasa.livejournal.com
«Никакие операции с целыми числами, кроме обсуждаемой, не генерируют исключение»

этого никто не гарантирует. implementation defined.

операции над unsigned с гарантией не генерируют исключений, но idiv именно что signed.

January 2026

S M T W T F S
    1 2 3
4 5678910
11121314151617
18192021222324
25262728293031

Most Popular Tags

Page Summary

Style Credit

Expand Cut Tags

No cut tags
Page generated Jan. 6th, 2026 07:08 am
Powered by Dreamwidth Studios