lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date:   Fri, 28 Jul 2023 23:50:31 +0800
From:   Zhangjin Wu <falcon@...ylab.org>
To:     tanyuan@...ylab.org
Cc:     falcon@...ylab.org, linux-kernel@...r.kernel.org,
        linux-kselftest@...r.kernel.org, w@....eu
Subject: [PATCH 1/2] tools/nolibc: add pipe() support

Hi, Yuan

> pipe is crucial for shell.
>

As the syscall manpage[1] shows, pipe() is just one of the exceptions how
may require two return registers in some platforms, e.g.:
arch/mips/kernel/syscall.c

    * For historic reasons the pipe(2) syscall on MIPS has an unusual calling
     * convention.  It returns results in registers $v0 / $v1 which means there
     * is no need for it to do verify the validity of a userspace pointer
     * argument.  Historically that used to be expensive in Linux.  These days
     * the performance advantage is negligible.
     */
    asmlinkage int sysm_pipe(void)
    {
            int fd[2];
            int error = do_pipe_flags(fd, 0);
            if (error)
                    return error;
            current_pt_regs()->regs[3] = fd[1];
            return fd[0];
    }

The other exceptions are getxpid(2), getxuid(2), and getxgid(2) on
Alpha.

Since we are able to use pipe2() for pipe() (introduced from early Linux
2.6.27, glibc 2.9) and use getpid+getppid for getxpid, getuid+geteuid
for getxuid and getgid+getegit for getxgid.

So, it is possible provide such pipe() as a wraper of pipe2() and
getxpid, getxuid and getxgid as wrappers of their corresponding syscall
pairs, then, no need to provide a second return value for all of the
existing architectures, for example:

    #ifndef pipe
    int pipe(int pipefd[2])
    {
        pipe2(pipefd, 0);
    }
    #endif

And for mips:

    // may be in tools/include/nolibc/types.h ?
    struct fd_pair {
           long fd[2];
    };

    // tools/include/nolibc/arch-mips.h
    struct fd_pair pipe(void)
    {
            struct fd_pair fds;
            int pipefds[2];
    
            pipe2(pipefds, 0);
    
            fds.fd[0] = pipefds[0];
            fds.fd[1] = pipefds[1];
    
            return fds;
    }

To use such method, the test case should be changed too, perhaps an
easier method is even only provide pipe2() for all and let users define
their own pipe() if really required, we also need to change the test
case.

Best regards,
Zhangjin
[1]: https://man7.org/linux/man-pages/man2/syscall.2.html

> Signed-off-by: Yuan Tan <tanyuan@...ylab.org>
> ---
>  tools/include/nolibc/sys.h | 17 +++++++++++++++++
>  1 file changed, 17 insertions(+)
> 
> diff --git a/tools/include/nolibc/sys.h b/tools/include/nolibc/sys.h
> index 8bfe7db20b80..09841fc266fe 100644
> --- a/tools/include/nolibc/sys.h
> +++ b/tools/include/nolibc/sys.h
> @@ -752,6 +752,23 @@ int open(const char *path, int flags, ...)
>  }
>  
>  
> +/*
> + * int pipe(int pipefd[2]);
> + */
> +
> +static __attribute__((unused))
> +int sys_pipe(int pipefd[2])
> +{
> +	return my_syscall1(__NR_pipe, pipefd);
> +}
> +
> +static __attribute__((unused))
> +int pipe(int pipefd[2])
> +{
> +	return __sysret(sys_pipe(pipefd));
> +}
> +
> +
>  /*
>   * int prctl(int option, unsigned long arg2, unsigned long arg3,
>   *                       unsigned long arg4, unsigned long arg5);
> -- 
> 2.39.2

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ