0

Here my code is. Firstly, I call pipe and initialize file descriptors. And their numbers are 3 and 4. Secondly, I call dup2 and redirect STDOUT to file descriptor 4, closing both endings of the pipe aka fds[0] and fds1. In the end, I call execve and the program gives output to the console. But there must be no output at all because the program closes file descriptor 1 aka STDOUT and writes everything to file descriptor 4. Unfortunately, this does not happen at all. The second code block is the code with similar functionality but written in C. So what am doing wrong?

    .global main
    main:
            # pipe(fds)
            xor %rax, %rax
            mov $22, %al
            lea fds(%rip), %rdi
            syscall

            xor %rax, %rax # fork
            mov $57, %al
            syscall 

            cmp $0, %rax
            je child_ls

            mov $0, %rdi
            call wait
    finish: 
            mov $60, %rax
            mov $0, %rdi
            syscall
    child_ls:
            # dup2(fds[1], STDOUT_FILEINO)
            xor %rax, %rax
            mov $33, %al
            xor %rdi, %rdi
            lea fds(%rip), %rdi
            mov 4(%rdi), %ebx
            mov %rbx, %rdi
            xor %rsi, %rsi
            inc %rsi
            syscall

            # close(fds[0])
            xor %rax, %rax
            mov $3, %al
            lea fds(%rip), %rdi
            mov (%rdi), %ebx
            mov %rbx, %rdi
            syscall

            # close(fds[1])
            xor %rax, %rax
            mov $3, %al
            lea fds(%rip), %rdi
            mov 4(%rdi), %ebx
            mov %rbx, %rdi
            syscall

            xor %rdx, %rdx
            push %rdx

            lea arg_ls(%rip), %rdi
            push %rdi
            lea cmd_ls(%rip), %rdi
            push %rdi

            mov %rsp, %rsi
            call execve
    cmd_ls:
    .string "/bin/ls"
    arg_ls:
    .string "-l"
    fds:
    .int 0, 0

Here the result of assembly code is. enter image description here

The code with similar functionality but written in C. In C everything works fine and there is no output to the console.

    #include <sys/types.h>
    #include <sys/stat.h>
    #include <fcntl.h>
    #include <sys/wait.h>
    #include <unistd.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <errno.h>
    int main()
    {
        char *command[3] = {"/bin/ls", "-l", 0};
        int fd[2];
        pipe(fd);
        pid_t pid = fork();
        if (pid == 0)
        {
            dup2(fd[1], 1);
            execvp(command[0], command);
        }
        wait(0);
        return 0;
    }

enter image description here

  • 1. don't post pictures of text, and fix the compiler warning in your C. (Or name it `.c` instead of `.cpp`!). 2. Run your asm program under strace to see what args you're passing to system calls and what return value or error code is returned. `strace ./test`. – Peter Cordes Apr 15 '22 at 06:46
  • Your asm program does `dup2(0, 1) = 1` and then `close(0)` twice, according to strace. Earlier, `pipe(0x5624baa291eb) = -1 EFAULT (Bad address)`. (In a PIE executable, that looks like a randomized `.data` or `.bss` address. Oh actually it's a `.text` address, which is read-only.) – Peter Cordes Apr 15 '22 at 06:52

0 Answers0