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=-0.8 required=5.0 tests=DKIM_ADSP_CUSTOM_MED, DKIM_INVALID,DKIM_SIGNED,FREEMAIL_FROM,MAILING_LIST_MULTI, RCVD_IN_MSPIKE_H2 autolearn=ham autolearn_force=no version=3.4.4 Received: (qmail 12495 invoked from network); 29 Mar 2023 15:18:17 -0000 Received: from second.openwall.net (193.110.157.125) by inbox.vuxu.org with ESMTPUTF8; 29 Mar 2023 15:18:17 -0000 Received: (qmail 20170 invoked by uid 550); 29 Mar 2023 15:18:14 -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 20129 invoked from network); 29 Mar 2023 15:18:13 -0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; t=1680103081; x=1682695081; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:from:to:cc:subject:date:message-id:reply-to; bh=jffvkShAp/qMy6x/9eZCje7I5NDHtmx6zSRD8bBaWg8=; b=oGOlagbcrxmqDlyZuCK99PYiKxf6xdQ7sybJLmcQut+Fj8CGNJepBlK4S6KUoQ8qDN HbywjrsWwQ9zoA1/0HwFRgtklrFpEuWK+THP/oaturSjr1TLpv6MdTh7uPicfTXsIQwX QBrsE8uvfwVUbG35snccXABuEdyOwlmjSF9B8WAFxUlvjFsJHITKPJ4b4LEBTanBxIrX bm1h1NL4rMIVET1+4y/ti//KfRm9d/t8R5nUQpy4sMm+2aiAQ8Ek0jVc5KaV1c67ZGxs 1FrQxddCZ6hJH+Qs+5HvCKODgvGLBzQZHEI3xaZgUzCYesrFT72GsbeauuMSNSHulXGM 4O2A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1680103081; x=1682695081; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=jffvkShAp/qMy6x/9eZCje7I5NDHtmx6zSRD8bBaWg8=; b=wUNDqbJKUli98MMdOrpZn58MvYh6xhaKn6W6YbWjF2SVN6rl9dHBsfUIbp5hxvkeb+ 1GS2yEGBk9Yf61RtgfbJYD0/Exiq9xSVlreObyvR9X41BGSjRa8b7GaQeKr9k38J893I 7tsyqGwDPUs27Dk+64qnvNwzs+mAEWjUvaIuNJfXQIZUthwAocm0xf0+0bC0PFIElZiI sCba86PHToeJ4nGVQ7wtY34YoCYTiKh0+jnx+upGWWzU4UdZlVssDhov0KTNDmuEoL4W 7cqjIg6m8MYw1OGzuMoldrrcUy+mn3s7I5nu7ULf7zOTpzQY1T3jrZumFd0pDwlCak9Z WVKA== X-Gm-Message-State: AAQBX9ekJ9ny/V2i4vTpqMs7L9hRjlqMBGmvJrSGnZlDOQO4ccUG7zM2 /RgRI6gAnkGroRTFgxP7WE3C+ftKAGfTrQ== X-Google-Smtp-Source: AKy350ZgSWcRspzuKqfBqjBHBcddHgMkcBW0amZJyX7gvVxo3BhDGCAOPVhcL3ZUZBUBwcqr/CltBg== X-Received: by 2002:a05:6a00:e13:b0:627:ff64:85cc with SMTP id bq19-20020a056a000e1300b00627ff6485ccmr17199043pfb.0.1680103080805; Wed, 29 Mar 2023 08:18:00 -0700 (PDT) From: Matthias Goergens To: musl@lists.openwall.com Cc: Matthias Goergens Date: Wed, 29 Mar 2023 23:17:51 +0800 Message-Id: <20230329151751.392944-1-matthias.goergens@gmail.com> X-Mailer: git-send-email 2.40.0 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Subject: [musl] [PATCH] mntent: deal with escaped whitespace in mtab and fstab >From glibc's documentation: > Since fields in the mtab and fstab files are separated by whitespace, > octal escapes are used to represent the characters space (\040), > tab (\011), newline (\012), and backslash (\\) in those files when they > occur in one of the four strings in a mntent structure. The > routines addmntent() and getmntent() will convert from string > representation to escaped representation and back. When converting > from escaped representation, the sequence \134 is also converted to a > backslash. This fixes the issue reported in https://www.openwall.com/lists/musl/2021/12/14/1 Please pardon the previous broken patch that I tried to send directly via gmail. This is my first time contributing to musl. Please point out any ways to improve. I probably got a few things wrong? Thanks! Addendum: this is a new version. The first one did not copy the final null-byte. --- src/misc/mntent.c | 75 ++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 68 insertions(+), 7 deletions(-) diff --git a/src/misc/mntent.c b/src/misc/mntent.c index d404fbe3..49f4e386 100644 --- a/src/misc/mntent.c +++ b/src/misc/mntent.c @@ -1,3 +1,4 @@ +#include #include #include #include @@ -20,6 +21,37 @@ int endmntent(FILE *f) return 1; } +static inline int decode1(char** in_buf, char** out_buf, const char* from, const char to) { + if(strncmp(from, *in_buf, strlen(from)) == 0) { + *(*out_buf)++ = to; + *in_buf += strlen(from); + return 1; + } + return 0; +} + +static inline char* decode(char* buf) { + assert(buf != NULL); + char* read_cursor = buf; + char* write_cursor = buf; + while(*read_cursor) { + // space + decode1(&read_cursor, &write_cursor, "\\040", '\040') + // tab + || decode1(&read_cursor, &write_cursor, "\\011", '\011') + // newline + || decode1(&read_cursor, &write_cursor, "\\012", '\012') + // backslash + || decode1(&read_cursor, &write_cursor, "\\134", '\134') + || decode1(&read_cursor, &write_cursor, "\\\\", '\\') + // default: copy char as is. + || (*write_cursor++ = *read_cursor++); + } + *write_cursor = *read_cursor; + + return buf; +} + struct mntent *getmntent_r(FILE *f, struct mntent *mnt, char *linebuf, int buflen) { int n[8], use_internal = (linebuf == SENTINEL); @@ -55,10 +87,10 @@ struct mntent *getmntent_r(FILE *f, struct mntent *mnt, char *linebuf, int bufle linebuf[n[5]] = 0; linebuf[n[7]] = 0; - mnt->mnt_fsname = linebuf+n[0]; - mnt->mnt_dir = linebuf+n[2]; - mnt->mnt_type = linebuf+n[4]; - mnt->mnt_opts = linebuf+n[6]; + mnt->mnt_fsname = decode(linebuf+n[0]); + mnt->mnt_dir = decode(linebuf+n[2]); + mnt->mnt_type = decode(linebuf+n[4]); + mnt->mnt_opts = decode(linebuf+n[6]); return mnt; } @@ -69,12 +101,41 @@ struct mntent *getmntent(FILE *f) return getmntent_r(f, &mnt, SENTINEL, 0); } +static inline int write_string(FILE *f, const char* str) +{ + char c; + int error_occured = 0; + while(str && !error_occured && (c = *str++) != 0) { + if(c == '\040') // space + error_occured = fprintf(f, "%s", "\\040") < 0; + else if (c == '\011') // tab + error_occured = fprintf(f, "%s", "\\011") < 0; + else if (c == '\012') // newline + error_occured = fprintf(f, "%s", "\\012") < 0; + else if (c == '\\') + error_occured = fprintf(f, "%s", "\\\\") < 0; + else + error_occured = fprintf(f, "%c", c) < 0; + } + return error_occured; +} + int addmntent(FILE *f, const struct mntent *mnt) { if (fseek(f, 0, SEEK_END)) return 1; - return fprintf(f, "%s\t%s\t%s\t%s\t%d\t%d\n", - mnt->mnt_fsname, mnt->mnt_dir, mnt->mnt_type, mnt->mnt_opts, - mnt->mnt_freq, mnt->mnt_passno) < 0; + flockfile(f); + int result = + write_string(f, mnt->mnt_fsname) + || (fprintf(f, "\t") < 0) + || write_string(f, mnt->mnt_dir) + || (fprintf(f, "\t") < 0) + || write_string(f, mnt->mnt_type) + || (fprintf(f, "\t") < 0) + || write_string(f, mnt->mnt_opts) + || (fprintf(f, "\t%d\t%d\n", + mnt->mnt_freq, mnt->mnt_passno) < 0); + funlockfile(f); + return result; } char *hasmntopt(const struct mntent *mnt, const char *opt) -- 2.40.0