public inbox for libc-alpha@sourceware.org
 help / color / mirror / Atom feed
From: Askar Safin <safinaskar@zohomail.com>
To: "dalias" <dalias@libc.org>,
	"Adhemerval Zanella Netto" <adhemerval.zanella@linaro.org>
Cc: "libc-alpha" <libc-alpha@sourceware.org>, "carlos" <carlos@redhat.com>
Subject: Re: [PATCH, RFC] Add public function syscall_no_errno
Date: Wed, 07 Feb 2024 04:59:54 +0400	[thread overview]
Message-ID: <18d81141715.113eab5157547.6554800058266941170@zohomail.com> (raw)
In-Reply-To: <20240201201638.GG22081@brightrain.aerifal.cx>

Hi, Rich and Adhemerval!

 ---- On Fri, 02 Feb 2024 00:16:26 +0400  dalias  wrote --- 
 > OK, but this falls under "poking around behind libc's back".

Function "syscall" exists in glibc. So it is assumed to be useful.
Thus it is okay to have "syscall_no_errno", too. "syscall" in
its current form has a problem: you cannot correctly call
SYS_getuid32. Thus there is need for "syscall_no_errno".

So I will write next version of my patch. I hope in several days,
when I have time.
"syscall_no_errno" will be simple wrapper for "INTERNAL_SYSCALL_NCS_CALL".

 > Well that's not something syscall() gives you and it's not something
 > syscall_no_errno() would reliably give you either unless it was
 > specifically documented to be callable from such a context. If that's
 > what you want, maybe that's what should be discussed.

I did some research. I have read all places where glibc calls "clone".
And I see that in all these places if CLONE_VM specified, then
CLONE_SETTLS or CLONE_VFORK is specified.

In fact, there is 2 places only, where glibc calls clone (in Linux x86_64).

One is implementation of pthread_create. We pass CLONE_VM and
CLONE_SETTLS. Thus (as well as I understand) TLS is set up
in child right from the beginning.
There is no time gap, when TLS is not initialized yet.

Second place is implementation of posix_spawn. We pass CLONE_VM
and CLONE_VFORK. CLONE_VFORK means that parent is suspended,
and thus it is okay to access its TLS.

Thus glibc absolutely always (even internally!) maintains invariant
"TLS is safe to access". I. e. glibc itself does not need a way to perform
syscalls when TLS is not set up.

Thus if I want syscall_no_errno to provide such guarantee, this will
be absolutely unique guarantee, which is not needed even by
glibc authors themselves. So I think this will be very hard to provide it,
and benefits will be small.

Yes, small time gap when TLS is not initialized, still exists. Before "main".
But in this case we have one thread only, so everything is simple.

For all these reasons I think that guarantee "you may call syscall_no_errno
even after clone(CLONE_VM) without CLONE_VFORK and
without CLONE_SETTLS" should not be provided.

(Correct me if I wrong.)

So I go back to my original proposal: add function, which will be able to
call directly syscalls, such as SYS_getuid32.

Adhemerval Zanella Netto:
> There is another potential issue where you have multiple syscall
> with slight different kABI

In fact my original use case is so: I want to parse true kernel ABI
from files /sys/kernel/debug/tracing/events/syscalls/sys_enter_*/format
and then generate a library based on the ABI.

Such library will provide syscall wrappers with correct types. These
wrappers will call functions "syscall" and "syscall_no_errno".

(In fact, this will be Rust library, not C one, but I don't think
this is important for our discussion. You may say: "Then why
you want to add syscall_no_errno to upstream glibc?"
Well, because I want it to be available to everyone. To Rust
programmers, to C programmers and to everyone else.
Without the need to write assembly.)

So, I will read proper kernel ABI from /sys/kernel/..., so
I will get ABI right.

> at least for glibc, where the user
> exported argument does not really match the kernel (stat/fstat/etc.).

I will use Linux headers, so all will be okay.
(Well, correction: I will use Rust's crate "linux-raw-sys",
which is based on Linux headers.)

You may say: "Well, I still think you should find Rust library,
which does what you want, and stop bothering upstream glibc".
I will answer: I don't trust Rust libs! Yes, there exist multiple
Rust crates, which provide something similar to syscall_no_errno.

They are implemented using hand-coded assembly.
Why should I trust that they got this assembly correct?

On the other hand, glibc already has high quality
INTERNAL_SYSCALL_NCS_CALL, which I trust. It is
more likely to be correct, than all these buggy Rust crates.

We just need to export it. So I propose to export simple
wrapper for INTERNAL_SYSCALL_NCS_CALL called
"syscall_no_errno". And everybody will use it. C devs,
Rust devs, etc. Big benefits for everybody. For low
cost on glibc side.

Also, I have a question. It seems that function "syscall"
uses TLS and nothing else. This means that it is okay to
call it in a child, created using "clone", assuming that one
of these holds:
- We didn't specify CLONE_VM
- We specified CLONE_VM and CLONE_VFORK (thus parent
is suspended and it is okay to use its TLS)

So may I also write a patch for documentation, which will
document this guarantee? It surely already holds, because
glibc uses it in implementation of posix_spawn. I just
want to document it, and this will mean that now it
will hold in the future.

Moreover, such guarantee holds if we call clone using this code
without specifiying new stack:

if (syscall(SYS_clone, ...) == 0){ /* we are in child */ }

  parent reply	other threads:[~2024-02-07  1:00 UTC|newest]

Thread overview: 23+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-01-28 16:39 Askar Safin
2024-02-01 17:53 ` Adhemerval Zanella Netto
2024-02-01 18:18   ` Rich Felker
2024-02-01 19:32   ` Askar Safin
2024-02-01 20:16     ` dalias
2024-02-01 20:57       ` Adhemerval Zanella Netto
2024-02-08 15:02         ` [PATCH v2] " Askar Safin
2024-02-08 17:48           ` Szabolcs Nagy
2024-02-12 14:24           ` Florian Weimer
2024-02-12 14:44             ` Rich Felker
2024-02-12 16:16               ` Askar Safin
2024-02-12 17:25                 ` Zack Weinberg
2024-02-12 17:43                   ` Andreas Schwab
2024-02-12 18:22                     ` Zack Weinberg
2024-02-13  9:10                       ` Andreas Schwab
2024-02-13 11:57                         ` Adhemerval Zanella Netto
2024-02-12 17:55                   ` Adhemerval Zanella Netto
2024-02-12 18:34                   ` Askar Safin
2024-02-07  0:59       ` Askar Safin [this message]
2024-02-07 20:59         ` [PATCH, RFC] " dalias
2024-02-08 17:08           ` Askar Safin
2024-02-07  1:57 ` Mike Frysinger
2024-02-07 12:55   ` Askar Safin

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=18d81141715.113eab5157547.6554800058266941170@zohomail.com \
    --to=safinaskar@zohomail.com \
    --cc=adhemerval.zanella@linaro.org \
    --cc=carlos@redhat.com \
    --cc=dalias@libc.org \
    --cc=libc-alpha@sourceware.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).