diff --git a/executor/common_linux.h b/executor/common_linux.h index dd48b570c1e..64e3f8fb58c 100644 --- a/executor/common_linux.h +++ b/executor/common_linux.h @@ -3044,7 +3044,15 @@ static long syz_mount_image( } else if (strncmp(fs, "ext", 3) == 0) { // For ext2/3/4 we have to have errors=continue because the image // can contain errors=panic flag and can legally crash kernel. - if (strstr(opts, "errors=panic") || strstr(opts, "errors=remount-ro") == 0) + bool has_remount_ro = false; + char* remount_ro_start = strstr(opts, "errors=remount-ro"); + if (remount_ro_start != NULL) { + // syzkaller can sometimes break the options format, so we have to make sure this option can really be parsed. + char after = *(remount_ro_start + strlen("errors=remount-ro")); + char before = remount_ro_start == opts ? '\0' : *(remount_ro_start - 1); + has_remount_ro = ((before == '\0' || before == ',') && (after == '\0' || after == ',')); + } + if (strstr(opts, "errors=panic") || !has_remount_ro) strcat(opts, ",errors=continue"); } else if (strcmp(fs, "xfs") == 0) { // For xfs we need nouuid because xfs has a global uuids table diff --git a/pkg/csource/generated.go b/pkg/csource/generated.go index 8c8fa8d2263..955d7c97199 100644 --- a/pkg/csource/generated.go +++ b/pkg/csource/generated.go @@ -6799,7 +6799,14 @@ static long syz_mount_image( if (strcmp(fs, "iso9660") == 0) { flags |= MS_RDONLY; } else if (strncmp(fs, "ext", 3) == 0) { - if (strstr(opts, "errors=panic") || strstr(opts, "errors=remount-ro") == 0) + bool has_remount_ro = false; + char* remount_ro_start = strstr(opts, "errors=remount-ro"); + if (remount_ro_start != NULL) { + char after = *(remount_ro_start + strlen("errors=remount-ro")); + char before = remount_ro_start == opts ? '\0' : *(remount_ro_start - 1); + has_remount_ro = ((before == '\0' || before == ',') && (after == '\0' || after == ',')); + } + if (strstr(opts, "errors=panic") || !has_remount_ro) strcat(opts, ",errors=continue"); } else if (strcmp(fs, "xfs") == 0) { strcat(opts, ",nouuid");