Hi, > if this still should be trackled,
It's still in kernel 5.10, at least. > please report it upstream I agree that this bug is not Debain's business. But i'd need a kernel list member who would be ready to review a patch. Warning: From here on it's just whining of a userlander about kernel cruelty. There is no maintainer for isofs. Nearest is linux-scsi because of the semi-proximity between cdrom and isofs. Having had a real test machine last year, i tried to submit patches for both subsystems [1] [2], but did not get any reaction. After this experience i did not submit my patch for the name length issues. It is based on 5.10: ---------------------------------------------------------------------- From 3d484405f0ad8d10ef490281da157bfdd7450cb6 Mon Sep 17 00:00:00 2001 From: Thomas Schmitt <scdbac...@gmx.net> Date: Tue, 22 Sep 2020 12:34:50 +0200 Subject: [PATCH 1/1] isofs: truncate oversized Rock Ridge names to 255 bytes Enlarge the limit for name bytes from 253 to 255. Do not discard all bytes of the NM field where the overflow occurs, but rather append them to the accumulated name before truncating it to exactly 255 bytes. Map trailing incomplete UTF-8 bytes to '_'. Signed-off-by: Thomas Schmitt <scdbac...@gmx.net> --- fs/isofs/rock.c | 73 ++++++++++++++++++++++++++++++++++++++++++++++--- fs/isofs/rock.h | 2 ++ 2 files changed, 71 insertions(+), 4 deletions(-) diff --git a/fs/isofs/rock.c b/fs/isofs/rock.c index 94ef92fe806c..e1db8776b67e 100644 --- a/fs/isofs/rock.c +++ b/fs/isofs/rock.c @@ -192,6 +192,63 @@ static int rock_check_overflow(struct rock_state *rs, int sig) return 0; } +/* + * Find backward from idx the start byte of a possible UTF-8 character. + * https://en.wikipedia.org/wiki/UTF-8#Description + * Return -1 if no incomplete UTF-8 sequence is found at the name end. + */ +static int rock_find_utf8_start(char *name, int idx) +{ + unsigned char *uname, uch; + int i; + + uname = (unsigned char *)name; + /* Up to 4-byte codes */ + for (i = 0; i < 4 && idx - i >= 0; i++) { + uch = uname[idx - i]; + if ((uch & 0xe0) == 0xc0) { + /* UTF-8 start byte for 2-byte codes */ + if (i >= 1) + return -1; /* tail is complete */ + else + return (idx - i); /* tail not complete */ + } else if ((uch & 0xf0) == 0xe0) { + /* UTF-8 start byte for 3-byte codes */ + if (i >= 2) + return -1; + else + return (idx - i); + } else if ((uch & 0xf8) == 0xf0) { + /* UTF-8 start byte for 4-byte codes */ + if (i >= 3) + return -1; + else + return (idx - i); + } else if ((uch & 0xc0) != 0x80) { + /* not an UTF-8 tail byte, so no UTF-8 */ + return -1; + } + } + /* That would be an oversized UTF-8 code or no UTF-8 at all */ + return -1; +} + +/* + * Replace trailing incomplete UTF-8 sequence by '_' characters. + */ +static void rock_erase_incomplete_utf8(char *name, int len) +{ + int i; + + if (len <= 0) + return; + i = rock_find_utf8_start(name, len - 1); + if (i < 0) + return; + for (; i < len; i++) + name[i] = '_'; +} + /* * return length of name field; 0: not found, -1: to be ignored */ @@ -271,16 +328,24 @@ int get_rock_ridge_filename(struct iso_directory_record *de, break; } len = rr->len - 5; - if (retnamlen + len >= 254) { - truncate = 1; - break; - } p = memchr(rr->u.NM.name, '\0', len); if (unlikely(p)) len = p - rr->u.NM.name; + if (retnamlen + len > RR_NAME_LEN) { + truncate = 1; + /* Take as many characters as possible */ + len = RR_NAME_LEN - retnamlen; + if (len <= 0) { + rock_erase_incomplete_utf8(retname, + retnamlen); + break; + } + } memcpy(retname + retnamlen, rr->u.NM.name, len); retnamlen += len; retname[retnamlen] = '\0'; + if (truncate == 1) + rock_erase_incomplete_utf8(retname, retnamlen); break; case SIG('R', 'E'): kfree(rs.buffer); diff --git a/fs/isofs/rock.h b/fs/isofs/rock.h index 1558cf22ef8a..0938fc11ced4 100644 --- a/fs/isofs/rock.h +++ b/fs/isofs/rock.h @@ -121,3 +121,5 @@ struct rock_ridge { #define RR_PL 32 /* Parent link */ #define RR_RE 64 /* Relocation directory */ #define RR_TF 128 /* Timestamps */ + +#define RR_NAME_LEN 255 /* Maximum length in bytes of a file name */ -- 2.20.1 ---------------------------------------------------------------------- There is also a lenghty "[PATCH 0/1]" cover letter with hands-on example how to reproduce the bug and how to test the remedy. Have a nice day :) Thomas ---------------------------------------------------------------------- [1] "Fix automatic CD tray loading for data reading via sr" https://lore.kernel.org/linux-scsi/20201006094026.1730-1-scdbac...@gmx.net [2] "isofs: fix Oops with zisofs and large PAGE_SIZE" https://lore.kernel.org/linux-scsi/20201120140633.1673-1-scdbac...@gmx.net