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=MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED,RCVD_IN_MSPIKE_H3,RCVD_IN_MSPIKE_WL autolearn=ham autolearn_force=no version=3.4.4 Received: (qmail 28546 invoked from network); 13 Oct 2021 14:02:09 -0000 Received: from mother.openwall.net (195.42.179.200) by inbox.vuxu.org with ESMTPUTF8; 13 Oct 2021 14:02:09 -0000 Received: (qmail 3131 invoked by uid 550); 13 Oct 2021 14:02:05 -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 3101 invoked from network); 13 Oct 2021 14:02:04 -0000 Date: Wed, 13 Oct 2021 10:01:52 -0400 From: Rich Felker To: "(GalaxyMaster)" Cc: musl@lists.openwall.com Message-ID: <20211013140152.GJ7074@brightrain.aerifal.cx> References: <0100017c773d8050-290fe58a-7804-4399-83f8-0ce8d845f7d2-000000@email.amazonses.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <0100017c773d8050-290fe58a-7804-4399-83f8-0ce8d845f7d2-000000@email.amazonses.com> User-Agent: Mutt/1.5.21 (2010-09-15) Subject: Re: [musl] errno on writing to read-only files On 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 it > should be: > === > galaxy@archlinux:~/musl-tests $ cat fput-to-readonly.c > #include > #include > > int main() { > FILE *f; > int i = 0; > f = fopen("fput-to-readonly.c", "r"); > errno = 0; > i = fputs("should not be written", f); > printf("i = %d (should be negative [EOF = %d])\n", i, EOF); > printf("errno = %d\n", errno); > return 0; > } > galaxy@archlinux:~/musl-tests $ gcc -o fput-to-readonly fput-to-readonly.c > galaxy@archlinux:~/musl-tests $ ./fput-to-readonly > i = -1 (should be negative [EOF = -1]) > errno = 0 > galaxy@archlinux:~/musl-tests $ > === > > 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. > > Glibc returns EBADF (9) in this case: > === > [galaxy@archlinux musl-tests]$ ./fput-to-readonly > i = -1 (should be negative [EOF = -1]) > errno = 9 > [galaxy@archlinux musl-tests]$ > === > > Should not we do the same? It kind of makes sense since the descriptor we are > asked to write to is read-only. I think it would be just one line added to > src/stdio/__towrite.c, something like: > === > --- musl-b76f37fd5625d038141b52184956fb4b7838e9a5.orig/src/stdio/__towrite.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 |= f->mode-1; > if (f->flags & F_NOWR) { > f->flags |= F_ERR; > + errno = EBADF; > return EOF; > } > /* Clear read buffer (easier than summoning nasal demons) */ > === This is a duplicate of: https://www.openwall.com/lists/musl/2020/10/08/1 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. 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). Rich