avr-ld buffer overflow

Дійсно прикра помилка в avr-ld (binutils-avr 2.25) — та, що спонукала мене до перевірки використання Raspberry Pi як комп’ютера для роботи, — виявилася доволі цікавою.

Почала вивалюватися вона у мене доволі давно, але я помилково вважав, що вона притаманна 64-бітній версії Ubuntu 16.04, бо на роботі в 32-бітній все працювало. Думав, що це якісь проблеми невраховування розмірів чи співвідношення розмірів змінних на зразок «подаруночка від FTDI». Чесно кажучи, у повідомлення не особливо і вчитувався — «та хай, це по роботі, то на роботі й зберу» і вдома більше не запускав аж до того, як нещодавно перезібрати знадобилося негайно, бо це зупиняло термінову роботу. Тоді ж ото зібрав на Raspberry й написав про все це.

Ну й на ключову фразу *** buffer overflow detected *** Іван у коментарях пояснив, як із цим можна боротися.
Докладніше читайте в його щоденнику «А щоб було», а коротко ситуація така: потрібно або прибрати генерацію map-файлу, або перемкнути мову середовища на англійську. На роботі ж у 32-бітній версії Ubuntu все працювало, бо там колись давно чи то через розповзання діалогів у якійсь GUI-програмі, чи то через карлючки в ній, та мову системи було перемкнуто на англійську і це забулося.

Ця інформація вкупі з нарешті уважно прочитаним логом помилки

*** buffer overflow detected ***: /usr/lib/gcc/avr/4.9.2/../../../avr/bin/ld terminated
======= Backtrace: =========
/lib/x86_64-linux-gnu/libc.so.6(+0x777e5)[0x7f1a3e9f17e5]
/lib/x86_64-linux-gnu/libc.so.6(__fortify_fail+0x5c)[0x7f1a3ea9315c]
/lib/x86_64-linux-gnu/libc.so.6(+0x117160)[0x7f1a3ea91160]
/lib/x86_64-linux-gnu/libc.so.6(+0x1166c9)[0x7f1a3ea906c9]
/lib/x86_64-linux-gnu/libc.so.6(_IO_default_xsputn+0x80)[0x7f1a3e9f56b0]
/lib/x86_64-linux-gnu/libc.so.6(_IO_vfprintf+0xd1)[0x7f1a3e9c7241]
/lib/x86_64-linux-gnu/libc.so.6(__vsprintf_chk+0x84)[0x7f1a3ea90754]
/lib/x86_64-linux-gnu/libc.so.6(__sprintf_chk+0x7d)[0x7f1a3ea906ad]
/usr/lib/gcc/avr/4.9.2/../../../avr/bin/ld[0x416c47]
/usr/lib/gcc/avr/4.9.2/../../../avr/bin/ld[0x488174]

дозволяє зробити висновок, що розмір буфера для sprintf (не snprintf! тоді б хоч не хряпалося так) у модулі генерування карти лінкера було вибрано в режимі «має вистачити всім»™, але під «всіма», схоже, мали на увазі лише ASCII-світ. Щойно у вас з’являться двобайтові UTF-8-символи, буфера вже не вистачає. Що цікаво, avr-as з того ж binutils-avr 2.25, а також make — ще жодного разу не падали, чудово видаючи повідомлення українською мовою.

Оскільки відмовлятися від map-файлу я не хочу, «відремонтувати» роботу avr-ld можу двома способами.
Або в універсальному gcc-avr.mak, який ходить з проекту в проект і підключається по include в проектні Makefile, перемкнути мову середовища для всього інструментарію (раптом ще десь вилізе, то щоб і не знати), замінивши у фрагменті

46
47
48
49
50
51
52
# Set default toolchain prefix if it does not defind in environment or project makefile
TOOL ?= avr-

# Set tool names
CC      := $(TOOL)gcc
AS      := $(TOOL)gcc -x assembler-with-cpp
BIN     := $(TOOL)objcopy

другий рядок на

47
TOOL ?= LANG=en avr-

або ж змінити мову лише для лінкування, додавши те ж саме LANG=en безпосередньо перед відповідною командою:

211
212
213
$(TRGELF) : $(OBJ)
        echo ====  Link to $(notdir $@) ;\
        LANG=en $(CC) $^ $(LIB) $(LDFLAGS) -o $@

Стосується ця помилка лише Ubuntu (болгари обговорювали теж Ubuntu, в інших системах могли не вмикати локалізацію) й чи присутня вона в binutils-avr 2.26, я не знаю, можливості перевірити ще не було.

Leave a Reply

[flagcounter image]