mailing list of musl libc
 help / color / mirror / code / Atom feed
* [musl] errno not set to EBADF when reading from invalid descriptor
@ 2020-06-25 13:21 Stefan Ciotec
  2020-06-25 15:38 ` Rich Felker
  0 siblings, 1 reply; 5+ messages in thread
From: Stefan Ciotec @ 2020-06-25 13:21 UTC (permalink / raw)
  To: 'musl@lists.openwall.com'; +Cc: Vasile Iliescu

[-- Attachment #1: Type: text/plain, Size: 2345 bytes --]

Hi,

We are using MUSL C-library 1.1.22.
According to the POSIX standard, EOF should be returned and errno should be set to EBADF for the read group of functions (i.e. fgetc(), getc(), getc_unlocked()) when attempting to read from a stream with an invalid file descriptor open for reading.
However, in our tests with MUSL, we discovered that EOF is returned, but errno is not set to EBADF (it's 0 instead), for the following code:

#include <stdio.h>
#include <errno.h>
#include <stdlib.h>

int main() {
   FILE *f = fopen("/tmp/getc_unlocked", "w");
   char c;
   /* Negative smoke testing. */
   flockfile(f);
   c = getc_unlocked(f);
   printf("c:%#x errno:%d\n", c, errno);
   funlockfile(f);
   fclose(f);
   remove("/tmp/getc_unlocked");
   return 0;
}

I tested the same code with Linux glibc and errno is set appropriately to EBADF.

The issue seems to be in the following portion of the MUSL library:
int __toread(FILE *f)
{
   f->mode |= f->mode-1;
   if (f->wpos != f->wbase) f->write(f, 0, 0);
   f->wpos = f->wbase = f->wend = 0;
   if (f->flags & F_NORD) {
      f->flags |= F_ERR;
      return EOF; // Here errno should be set to EBADF before returning
   }
   f->rpos = f->rend = f->buf + f->buf_size;
   return (f->flags & F_EO
}

Best regards,

Stefan Ciotec
Software Engineer
OS Business Unit
Email
Stefan.Ciotec@enea.com
Phone
+40764758162

Enea
319 Splaiul Independentei
OB403A District 6
Bucharest 060044, ROMANIA

[https://www.enea.com/globalassets/images/enea-email-signature.png]<http://www.enea.com/>



This message, including attachments, is CONFIDENTIAL. It may also be privileged or otherwise protected by law. If you received this email by mistake please let us know by reply and then delete it from your system; you should not copy it or disclose its contents to anyone. All messages sent to and from Enea may be monitored to ensure compliance with internal policies and to protect our business. Emails are not secure and cannot be guaranteed to be error free as they can be intercepted, a mended, lost or destroyed, or contain viruses. The sender therefore does not accept liability for any errors or omissions in the contents of this message, which arise as a result of email transmission. Anyone who communicates with us by email accepts these risks.

[-- Attachment #2: Type: text/html, Size: 11559 bytes --]

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [musl] errno not set to EBADF when reading from invalid descriptor
  2020-06-25 13:21 [musl] errno not set to EBADF when reading from invalid descriptor Stefan Ciotec
@ 2020-06-25 15:38 ` Rich Felker
  2020-06-26  5:14   ` Markus Wichmann
  0 siblings, 1 reply; 5+ messages in thread
From: Rich Felker @ 2020-06-25 15:38 UTC (permalink / raw)
  To: Stefan Ciotec; +Cc: 'musl@lists.openwall.com', Vasile Iliescu

On Thu, Jun 25, 2020 at 01:21:05PM +0000, Stefan Ciotec wrote:
> Hi,
> 
> We are using MUSL C-library 1.1.22.
> According to the POSIX standard, EOF should be returned and errno
> should be set to EBADF for the read group of functions (i.e.
> fgetc(), getc(), getc_unlocked()) when attempting to read from a
> stream with an invalid file descriptor open for reading.
> However, in our tests with MUSL, we discovered that EOF is returned,
> but errno is not set to EBADF (it's 0 instead), for the following
> code:

I think you're misreading the standard. Per ISO C, it's undefined
behavior to call a read function on a FILE stream not opened for read
or update. The POSIX "shall fail" text you're looking at applies when
the FILE stream is open for read or update but the underlying fd is
not open for reading; this can happen with fdopen, when inheriting an
unsuitable fd for stdin via exec, or when using dup2 to replace
fileno(f) for some already-opened FILE with a reference to a different
open file that was opened for write only.

Note that the POSIX text is not very well aligned with the C text, but
the DESCRIPTION in POSIX refers to "the input stream pointed to by
stream". This reflects that it's a constraint, and passing an
inappropriate stream pointer is a constraint violation.

Note that there are lots of other reasons you can't safely use stdio
read functions on a stream you don't know is suitable for it.
Switching from writing to reading without a successful flush produces
UB, and switching the other direction without a successful seek does,
even if the FILE stream is open for both.

Rich

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [musl] errno not set to EBADF when reading from invalid descriptor
  2020-06-25 15:38 ` Rich Felker
@ 2020-06-26  5:14   ` Markus Wichmann
  2020-06-26  5:39     ` Damian McGuckin
  2020-06-26 16:06     ` Rich Felker
  0 siblings, 2 replies; 5+ messages in thread
From: Markus Wichmann @ 2020-06-26  5:14 UTC (permalink / raw)
  To: musl

On Thu, Jun 25, 2020 at 11:38:04AM -0400, Rich Felker wrote:
> Note that there are lots of other reasons you can't safely use stdio
> read functions on a stream you don't know is suitable for it.
> Switching from writing to reading without a successful flush produces
> UB, and switching the other direction without a successful seek does,
> even if the FILE stream is open for both.
>
> Rich

So I can't actually use a FILE open for reading and writing that refers
to something non-seekable, like a serial line, to both read and write to
it? I mean, I suppose I could write something and then flush and stay in
read mode forever, but that is not really the nature of my application.
I suppose I'll just open the serial line twice.

Ciao,
Markus

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [musl] errno not set to EBADF when reading from invalid descriptor
  2020-06-26  5:14   ` Markus Wichmann
@ 2020-06-26  5:39     ` Damian McGuckin
  2020-06-26 16:06     ` Rich Felker
  1 sibling, 0 replies; 5+ messages in thread
From: Damian McGuckin @ 2020-06-26  5:39 UTC (permalink / raw)
  To: musl

On Fri, 26 Jun 2020, Markus Wichmann wrote:

> So I can't actually use a FILE open for reading and writing that refers
> to something non-seekable, like a serial line, to both read and write to
> it?

Certainly STDIO allows this, but you need to be very careful. about doing 
it.

Years ago, I would send a string down a serial line opened Read/Write, as 
an atomic write, and then immediately, sit on the line waiting for a reply 
on the same serial line. I was simply trying to retreive the Postscript 
handshake between the system and the printer which was a very small number 
of characters.

Doing it with 2 FILEs is much smarter for the general case.

Regards - Damian

Pacific Engineering Systems International, 277-279 Broadway, Glebe NSW 2037
Ph:+61-2-8571-0847 .. Fx:+61-2-9692-9623 | unsolicited email not wanted here
Views & opinions here are mine and not those of any past or present employer

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [musl] errno not set to EBADF when reading from invalid descriptor
  2020-06-26  5:14   ` Markus Wichmann
  2020-06-26  5:39     ` Damian McGuckin
@ 2020-06-26 16:06     ` Rich Felker
  1 sibling, 0 replies; 5+ messages in thread
From: Rich Felker @ 2020-06-26 16:06 UTC (permalink / raw)
  To: musl

On Fri, Jun 26, 2020 at 07:14:00AM +0200, Markus Wichmann wrote:
> On Thu, Jun 25, 2020 at 11:38:04AM -0400, Rich Felker wrote:
> > Note that there are lots of other reasons you can't safely use stdio
> > read functions on a stream you don't know is suitable for it.
> > Switching from writing to reading without a successful flush produces
> > UB, and switching the other direction without a successful seek does,
> > even if the FILE stream is open for both.
> 
> So I can't actually use a FILE open for reading and writing that refers
> to something non-seekable, like a serial line, to both read and write to
> it? I mean, I suppose I could write something and then flush and stay in
> read mode forever, but that is not really the nature of my application.
> I suppose I'll just open the serial line twice.

Indeed, you basically always need 2 FILEs for bidirectional io. The
only case where you don't is when it's a normal seekable file and
you're willing to follow the arcane rules for switching modes (which
may make sense if it's a trivial case like writing whole file,
rewinding, then only reading from that point forward, which is a
fairly canonical use case for tmpfile()).

Rich

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2020-06-26 16:06 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-06-25 13:21 [musl] errno not set to EBADF when reading from invalid descriptor Stefan Ciotec
2020-06-25 15:38 ` Rich Felker
2020-06-26  5:14   ` Markus Wichmann
2020-06-26  5:39     ` Damian McGuckin
2020-06-26 16:06     ` Rich Felker

Code repositories for project(s) associated with this public inbox

	https://git.vuxu.org/mirror/musl/

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 NNTP newsgroup(s).