From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on inbox.vuxu.org X-Spam-Level: X-Spam-Status: No, score=-3.3 required=5.0 tests=HTML_MESSAGE, MAILING_LIST_MULTI,MIME_QP_LONG_LINE,RCVD_IN_DNSWL_MED, RCVD_IN_MSPIKE_H3,RCVD_IN_MSPIKE_WL autolearn=ham autolearn_force=no version=3.4.4 Received: (qmail 30510 invoked from network); 16 Oct 2021 06:30:40 -0000 Received: from mother.openwall.net (195.42.179.200) by inbox.vuxu.org with ESMTPUTF8; 16 Oct 2021 06:30:40 -0000 Received: (qmail 24138 invoked by uid 550); 16 Oct 2021 06:30:36 -0000 Mailing-List: contact musl-help@lists.openwall.com; run by ezmlm Precedence: bulk List-Post: List-Help: List-Unsubscribe: List-Subscribe: List-ID: Reply-To: musl@lists.openwall.com Received: (qmail 24105 invoked from network); 16 Oct 2021 06:30:36 -0000 Content-Type: multipart/alternative; boundary=Apple-Mail-1D001D0E-999E-4D69-8654-B7C02271F177 Content-Transfer-Encoding: 7bit From: "A. Wilcox" Mime-Version: 1.0 (1.0) Date: Sat, 16 Oct 2021 01:30:19 -0500 Message-Id: References: <20211013140152.GJ7074@brightrain.aerifal.cx> Cc: "(GalaxyMaster)" In-Reply-To: <20211013140152.GJ7074@brightrain.aerifal.cx> To: musl@lists.openwall.com X-Mailer: iPhone Mail (18G82) Subject: Re: [musl] errno on writing to read-only files --Apple-Mail-1D001D0E-999E-4D69-8654-B7C02271F177 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable On Oct 13, 2021, at 9:02 AM, Rich Felker wrote: >=20 > =EF=BB=BFOn Wed, Oct 13, 2021 at 01:21:31AM +0000, (GalaxyMaster) wrote: >> Hello, >>=20 >> I am observing the following on musl and I am not sure that this is the w= ay it >> should be: >> =3D=3D=3D >> galaxy@archlinux:~/musl-tests $ cat fput-to-readonly.c=20 >> #include >> #include >>=20 >> int main() { >> FILE *f; >> int i =3D 0; >> f =3D fopen("fput-to-readonly.c", "r"); >> errno =3D 0; >> i =3D fputs("should not be written", f); >> printf("i =3D %d (should be negative [EOF =3D %d])\n", i, EOF); >> printf("errno =3D %d\n", errno); >> return 0; >> } >> galaxy@archlinux:~/musl-tests $ gcc -o fput-to-readonly fput-to-readonly.= c=20 >> galaxy@archlinux:~/musl-tests $ ./fput-to-readonly=20 >> i =3D -1 (should be negative [EOF =3D -1]) >> errno =3D 0 >> galaxy@archlinux:~/musl-tests $ >> =3D=3D=3D >>=20 >> Logically, I would expect the errno variable to be set to something since= there >> was clearly an error and the data has not been written to the destination= . >>=20 >> Glibc returns EBADF (9) in this case: >> =3D=3D=3D >> [galaxy@archlinux musl-tests]$ ./fput-to-readonly=20 >> i =3D -1 (should be negative [EOF =3D -1]) >> errno =3D 9 >> [galaxy@archlinux musl-tests]$ >> =3D=3D=3D >>=20 >> Should not we do the same? It kind of makes sense since the descriptor w= e are >> asked to write to is read-only. I think it would be just one line added t= o >> src/stdio/__towrite.c, something like: >> =3D=3D=3D >> --- musl-b76f37fd5625d038141b52184956fb4b7838e9a5.orig/src/stdio/__towrit= e.c 2021-09-24 00:09:22.000000000 +0000 >> +++ musl-b76f37fd5625d038141b52184956fb4b7838e9a5/src/stdio/__towrite.c = 2021-10-13 01:16:04.713069382 +0000 >> @@ -5,6 +5,7 @@ int __towrite(FILE *f) >> f->mode |=3D f->mode-1; >> if (f->flags & F_NOWR) { >> f->flags |=3D F_ERR; >> + errno =3D EBADF; >> return EOF; >> } >> /* Clear read buffer (easier than summoning nasal demons) */ >> =3D=3D=3D >=20 > This is a duplicate of: > https://www.openwall.com/lists/musl/2020/10/08/1 >=20 > As noted then, it's undefined behavior to call stdio functions on a > stream that's not the appropriate type. We do the check quoted above > to avoid blowing up and corrupting buffer state by trying to do the > wrong type of operation, but don't set an errno because there isn't > one specified for this (since it's UB). Arguably it would be better > and more consistent with what we do elsewhere to crash, but for > whatever reason that wasn't done. >=20 > EBADF is specified for when the underlying fd is in the wrong mode, > which is a different condition (and only can happen when you inherited > it as stdin/out/err, used fdopen, or dup2'd over an existing FILE's > fd). >=20 > Rich Hi there, The last (relevant) message in the thread of the duplicate, at https://www.o= penwall.com/lists/musl/2020/10/08/3, mentions a potential fix by setting err= no in __towrite()/__toread(). For clarity, would that be something acceptab= le? I doubt it, but was just curious, since no one replied to that suggestion ei= ther way. Best, -arw -- A. Wilcox (Sent from my iPhone) Mac, iOS, Linux software engineer= --Apple-Mail-1D001D0E-999E-4D69-8654-B7C02271F177 Content-Type: text/html; charset=utf-8 Content-Transfer-Encoding: quoted-printable On Oct 13, 2021, at 9:02 AM, Rich Felker &l= t;dalias@libc.org> wrote:
<= br>
=EF=BB=BFOn Wed, Oct 13, 2021 at 01:21:31AM +0000, (GalaxyMaster) wrote:
Hello,

I= am observing the following on musl and I am not sure that this is the way i= t
should be:
=3D=3D=3D
galaxy@archlinux:~/musl-tests $ cat fput= -to-readonly.c
#incl= ude <stdio.h>
#= include <errno.h>

int main() {
   FILE *f;
   int i =3D= 0;
   f =3D= fopen("fput-to-readonly.c", "r");
   errno =3D 0;
   i =3D fputs("should not be written", f);
   printf("i= =3D %d (should be negative [EOF =3D %d])\n", i, EOF);
   printf("errno =3D %d\n", err= no);
   re= turn 0;
}
<= /blockquote>
galaxy@archlinux:~/musl-tests $ g= cc -o fput-to-readonly fput-to-readonly.c
galaxy@archlinux:~/musl-tests $ ./fput-to-readonly
i =3D -1 (should be neg= ative [EOF =3D -1])
e= rrno =3D 0
galaxy@arc= hlinux:~/musl-tests $
=3D=3D=3D
Logically, I would expect the e= rrno variable to be set to something since there
was clearly an error and the data has not been w= ritten to the destination.
=
Glibc returns E= BADF (9) in this case:
=3D=3D=3D
[galaxy@a= rchlinux musl-tests]$ ./fput-to-readonly
i =3D -1 (should be negative [EOF =3D -1])
errno =3D 9
[galaxy@archlinux musl-tests]$
<= /blockquote>
=3D=3D=3D

Should not we do the same?  It kind of makes sense since t= he descriptor we are
= asked to write to is read-only.  I think it would be just one line adde= d to
src/stdio/__towr= ite.c, something like:
=3D=3D=3D
--- musl-= b76f37fd5625d038141b52184956fb4b7838e9a5.orig/src/stdio/__towrite.c   &= nbsp;2021-09-24 00:09:22.000000000 +0000
+++ musl-b76f37fd5625d038141b52184956fb4b7838e9a5/src/std= io/__towrite.c    2021-10-13 01:16:04.713069382 +0000
@@ -5,6 +5,7 @@ int __towrite(FIL= E *f)
   = f->mode |=3D f->mode-1;
   if (f->flags & F_NOWR) {
       f->flags |= =3D F_ERR;
+   &= nbsp;    errno =3D EBADF;
       return EOF;
   }
   /* Clear read buffer (easier tha= n summoning nasal demons) */
=3D=3D=3D

This is a du= plicate of:
https://www.openwall.com/lists/musl/2020/10/08/1=

As noted then, it's undefined behavior to c= all stdio functions on a
stream that's not the appropriate t= ype. We do the check quoted above
to avoid blowing up and co= rrupting buffer state by trying to do the
wrong type of oper= ation, but don't set an errno because there isn't
one specif= ied for this (since it's UB). Arguably it would be better
an= d more consistent with what we do elsewhere to crash, but for
whatever reason that wasn't done.

EBADF i= s specified for when the underlying fd is in the wrong mode,
which is a different condition (and only can happen when you inherited

it as stdin/out/err, used fdopen, or dup2'd over an existing FIL= E's
fd).

Rich

Hi there,

The last (releva= nt) message in the thread of the duplicate, at https://www.openwall.com/list= s/musl/2020/10/08/3, mentions a potential fix by setting errno in __towrite(= )/__toread().  For clarity, would that be something acceptable?

I doubt it, but was just curious, since no one replied to t= hat suggestion either way.

Best,
-arw

--=
A. Wilcox (Sent from my iPhone)
Mac, iOS, Linux software engineer
=
= --Apple-Mail-1D001D0E-999E-4D69-8654-B7C02271F177--