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]
Message-ID: <4e23cc1c-2fe0-413e-9fe1-a9428c0861b9@t-8ch.de>
Date:   Sun, 9 Jul 2023 20:49:10 +0200
From:   Thomas Weißschuh <thomas@...ch.de>
To:     Zhangjin Wu <falcon@...ylab.org>
Cc:     w@....eu, arnd@...db.de, linux-kernel@...r.kernel.org,
        linux-kselftest@...r.kernel.org
Subject: Re: [PATCH v2 04/12] tools/nolibc: crt.h: add _start_c

On 2023-07-08 23:29:58+0800, Zhangjin Wu wrote:
> As the environ and _auxv support added for nolibc, the assembly _start
> function becomes more and more complex and therefore makes the porting
> of nolibc to new architectures harder and harder.
> 
> To simplify portability, this c version of _start_c() is added to do
> most of the assembly start operations in C, which reduces the complexity
> a lot and will eventually simplify the porting of nolibc to the new
> architectures.
> 
> The new _start_c() only requires a stack pointer argument, it will find
> argv, envp and _auxv for us, and then call main(), finally, it exit()
> with main's return status. With this new _start_c(), the future new
> architectures only require to add very few assembly instructions.

I like it!

A quick test indicates that the initialization of the stackprotectors
could also be moved into the C function.

It also seems like a good opportunity to add some tests for
argv/environment variable passing.

And as general note to the full series I think that splitting the arch
files is not necessary and confusing.

> Signed-off-by: Zhangjin Wu <falcon@...ylab.org>
> ---
>  tools/include/nolibc/crt.h | 44 ++++++++++++++++++++++++++++++++++++++
>  1 file changed, 44 insertions(+)
> 
> diff --git a/tools/include/nolibc/crt.h b/tools/include/nolibc/crt.h
> index 221b7c5346ca..b269294e9664 100644
> --- a/tools/include/nolibc/crt.h
> +++ b/tools/include/nolibc/crt.h
> @@ -13,4 +13,48 @@
>  char **environ __attribute__((weak));

The old code seems to avoid putting "environ" into the global symbol
namespace. Could this declaration be moved into the function like in
getenv()?

>  const unsigned long *_auxv __attribute__((weak));
>  
> +int main(int argc, char *argv[], char **envp);

This will lead to conflicting declarations if the users use a different
signature. I'm not (yet?) sure how to work around this.

Also how is the case handled where main() returns "void"?
I'm not sure how this is currently handled or if the compiler takes core
of returning 0 in this case.

> +static void exit(int);
> +
> +void _start_c(long *sp)
> +{
> +	int argc, i;
> +	char **argv;
> +	char **envp;
> +
> +	/*
> +	 * sp  :  argc          <-- argument count, required by main()
> +	 * argv:  argv[0]       <-- argument vector, required by main()
> +	 *        argv[1]
> +	 *        ...
> +	 *        argv[argc-1]
> +	 *        null
> +	 * envp:  envp[0]       <-- environment variables, required by main() and getenv()
> +	 *        envp[1]
> +	 *        ...
> +	 *        null
> +	 * _auxv: auxv[0]       <-- auxiliary vector, required by getauxval()
> +	 *        auxv[1]
> +	 *        ...
> +	 *        null
> +	 */
> +
> +	/* assign argc and argv */
> +	argc = sp[0];
> +	argv = (void *)(sp + 1);
> +
> +	/* find envp */
> +	envp = argv + argc + 1;
> +	environ = envp;
> +
> +	/* find auxv */
> +	i = 0;
> +	while (envp[i])
> +		i++;
> +	_auxv = (void *)(envp + i + 1);
> +
> +	/* go to application */
> +	exit(main(argc, argv, envp));
> +}
> +
>  #endif /* _NOLIBC_CRT_H */
> -- 
> 2.25.1
> 

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ