Несоответствие в использовании системного вызова контейнера и жестких дисков [Linux]

#assembly #containers #64-bit #intel

#сборка #контейнеры #64-разрядный #intel

Вопрос:

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

Я написал некоторую сборку для Linux , которая отправит DNS — запрос и получит ответ . Версия x86 работает везде, но когда я сделал версию x64 для этого, и она работает везде, кроме как в контейнерах.

Я решил углубиться в подробности и заметил, что если я изменю тип запроса на TCP, он также будет делать то, что мне нужно, просто отлично.

Я отладил и вижу, что все настроено в стеке правильно, но ни один запрос на самом деле никогда не отправляется. Должен ли код быть написан по-другому, несмотря на то, что он работает на машинах baremetal? Или существует ли ограничение, которое обычно применяется для предотвращения отправки вызовов UDP.

Редактировать: я работаю над Linux x64 ubuntu. Я могу показать дамп TCP, когда он работает, но проблема в том, что когда он не работает, трафик вообще отсутствует; Пакеты не отправляются.

Редактирование 2:

Вот регистры в контейнере, которые содержат возврат после отправки .

 rax            0xffffffffffffffa1   -95
rbx            0x0  0
rcx            0xffffffffffffffff   -1
rdx            0x20 32
rsi            0x7fffffffe2b8   140737488347832
rdi            0x7  7
rbp            0x0  0x0
rsp            0x7fffffffe2b0   0x7fffffffe2b0
r8             0x7fffffffe2b0   140737488347824
r9             0x10 16
r10            0xd  13
r11            0x346    838
r12            0x5555555544f0   93824992232688
r13            0x7fffffffe3b0   140737488348080
r14            0x0  0
r15            0x0  0
rip            0x555555554668   0x555555554668 <main 104>
eflags         0x246    [ PF ZF IF ]
cs             0x33 51
ss             0x2b 43
ds             0x0  0
es             0x0  0
fs             0x0  0
gs             0x0  0
  

На физической машине после отправки системного вызова.

 (gdb) info registers
rax            0x20 32
rbx            0x0  0
rcx            0x555555554668   93824992233064
rdx            0x20 32
rsi            0x7fffffffdda8   140737488346536
rdi            0x3  3
rbp            0x5555555546e0   0x5555555546e0 <__libc_csu_init>
rsp            0x7fffffffdda0   0x7fffffffdda0
r8             0x7fffffffdda0   140737488346528
r9             0x10 16
r10            0x2  2
r11            0x246    582
r12            0x5555555544f0   93824992232688
r13            0x7fffffffdea0   140737488346784
r14            0x0  0
r15            0x0  0
rip            0x555555554668   0x555555554668 <main 104>
eflags         0x246    [ PF ZF IF ]
cs             0x33 51
ss             0x2b 43
ds             0x0  0
es             0x0  0
fs             0x0  0
gs             0x0  0
  

>

 section     .text
global      main   ;must be declared for linker (ld)



;The Message We want to send.
;AA AA 01 00 00 01 00 00 00 00 00 00 0A 72 6f 6f 74 6b 69 74 64 65 76 03 63 6f 6d 00 00 01 00 01


   ;DNS HEADER;
   ; AA AA - ID
   ; 01 00 - Query parameters
   ; 00 01 - Number of questions
   ; 00 00 - Number of answers
   ; 00 00 - Number of authority records
   ; 00 00 - Number of additional records
   ; DNS QUESTION --
   ; 07 - 'example' has length 7, ;so change this to be the length of domain ; keep in mind there are not '.' in the question.
   ; 65 - e
   ; 78 - x
   ; 61 - a
   ; 6D - m
   ; 70 - p
   ; 6C - l
   ; 65 - e

   ; 03 - subdomain '.com'  length 03  ; change this to be the length of type.

   ; 63 - c
   ; 6F - o
   ; 6D - m

   ; 00    - zero byte to end the QNAME 
   ; 00 01 - QTYPE 
   ; 00 01 - QCLASS

   ; DNS ANSWER!
   ; aa aa
   ; 81 80
   ; 00 01
   ; 00 01
   ; 00 00
   ; 00 00
   ; 07 65
   ; 78 61
   ; 6d 70
   ; 6c 65
   ; 03 63
   ; 6f 6d
   ; 00 00
   ; 01 00
   ; 01 c0
   ; 0c 00
   ; 01 00
   ; 01 00
   ; 00 12
   ; 8d 00
   ; 04 

   ; IP ADDRESS IN HEX -- 93.184.216.34
   ; 5d
   ; b8 
   ; d8
   ; 22



main:

        mov rax, 41                                ;Create Socket
        mov rdi, 2                                 ;AF_INET
        mov rsi, 2                                 ;Sock_DGRAM
        mov rdx, 0                                 ;flags
        syscall                                    ;CALL SYSCALL CREATE SOCKET ; Looks good!

        mov rdi, rax                            ; sockfd
; ####################### DNS REQUEST

mov rax, 0x0000000100010000
push rax 
mov rax, 0x6d6f6303656c706d
push rax 
mov rax, 0x6178650700000000
push rax 
mov rax, 0x000001000001AAAA
push rax 

; ############################### 

        mov rsi ,rsp
        mov rdx, 32 ; len of bytes    ; Google IP  port 53  INET Family       
        mov rax, 0x0101010135000002   ; 8.8.8.8.8 - 0x35 - 00 00 02 
        push rax
        mov rax, 44                             ; Send Syscall

        mov r8, rsp
        mov r9, 16
        syscall  ; This never Actually sends in containers for some reason.


; Now need to read the response!

        xor rax, rax   ; read syscall == 0x00
        push 100        ; Set out bytes to response to be higher!
        pop rdx         ; rdx = input size
        sub rsp, rdx
        mov rsi, rsp    ; rsi => buffer
        syscall

        add rsp, rax ; This will give us the top of the stack where the answer is stored.
        sub rsp, 0x4 ;
        mov rax, [rsp]
        mov ebx, eax 
        mov rax, rbx
  

Комментарии:

1. Вы забыли упомянуть, какой контейнер и какая операционная система. Также предоставьте strace и журнал wireshark.

2. Я могу получить некоторую трассировку дампа gdb, если это поможет.

3. @Jester возможно, это мне очень помогло бы. Вы знаете, что такое код ошибки -95? Я смотрю на коды ошибок, но численно указаны только -1 и -2. Другие указаны по имени.

4. Системные вызовы Linux возвращают errno как отрицательное число при ошибках. Итак, это «Операция EOPNOTSUPP 95 / * не поддерживается на конечной точке транспорта */».

5. Кроме того, если вы использовали strace в своей программе, как сказал Jester, вам будет показан код ошибки по имени. И что используемый вами IP-адрес 1.1.1.1, а не 8.8.8.8.