Module Name: src Committed By: reinoud Date: Thu Dec 16 22:19:09 UTC 2021
Modified Files: src/sys/fs/udf: udf_subr.c Log Message: Fix serious issue with recordable media formatted with Win10. When closing it after modification the VAT was written out corrupted making the disc unreadable anymore on remount. Thanks for ig@ for spotting it in the wild! To generate a diff of this commit: cvs rdiff -u -r1.160 -r1.161 src/sys/fs/udf/udf_subr.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/fs/udf/udf_subr.c diff -u src/sys/fs/udf/udf_subr.c:1.160 src/sys/fs/udf/udf_subr.c:1.161 --- src/sys/fs/udf/udf_subr.c:1.160 Wed Dec 15 22:02:30 2021 +++ src/sys/fs/udf/udf_subr.c Thu Dec 16 22:19:08 2021 @@ -1,4 +1,4 @@ -/* $NetBSD: udf_subr.c,v 1.160 2021/12/15 22:02:30 reinoud Exp $ */ +/* $NetBSD: udf_subr.c,v 1.161 2021/12/16 22:19:08 reinoud Exp $ */ /* * Copyright (c) 2006, 2008 Reinoud Zandijk @@ -29,7 +29,7 @@ #include <sys/cdefs.h> #ifndef lint -__KERNEL_RCSID(0, "$NetBSD: udf_subr.c,v 1.160 2021/12/15 22:02:30 reinoud Exp $"); +__KERNEL_RCSID(0, "$NetBSD: udf_subr.c,v 1.161 2021/12/16 22:19:08 reinoud Exp $"); #endif /* not lint */ @@ -2765,10 +2765,11 @@ udf_update_vat_descriptor(struct udf_mou struct icb_tag *icbtag; struct udf_oldvat_tail *oldvat_tl; struct udf_vat *vat; + struct regid *regid; uint64_t unique_id; uint32_t lb_size; uint8_t *raw_vat; - int filetype, error; + int vat_length, impl_use_len, filetype, error; KASSERT(vat_node); KASSERT(lvinfo); @@ -2813,11 +2814,20 @@ udf_update_vat_descriptor(struct udf_mou sizeof(struct udf_oldvat_tail), ump->vat_entries * 4); } else { /* compose the VAT2 header */ + vat_length = sizeof(struct udf_vat); vat = (struct udf_vat *) raw_vat; - memset(vat, 0, sizeof(struct udf_vat)); - vat->header_len = udf_rw16(152); /* as per spec */ - vat->impl_use_len = udf_rw16(0); + error = udf_vat_read(vat_node, raw_vat, vat_length, 0); + if (error) + goto errout; + + impl_use_len = udf_rw16(vat->impl_use_len); + vat_length += impl_use_len; + + error = udf_vat_read(vat_node, raw_vat, vat_length, 0); + if (error) + goto errout; + memmove(vat->logvol_id, ump->logical_vol->logvol_id, 128); vat->prev_vat = udf_rw32(0xffffffff); vat->num_files = lvinfo->num_files; @@ -2826,9 +2836,20 @@ udf_update_vat_descriptor(struct udf_mou vat->min_udf_writever = lvinfo->min_udf_writever; vat->max_udf_writever = lvinfo->max_udf_writever; - error = udf_vat_write(vat_node, raw_vat, - sizeof(struct udf_vat), 0); + if (impl_use_len >= sizeof(struct regid)) { + /* insert our implementation identification */ + memset(vat->data, 0, impl_use_len); + regid = (struct regid *) vat->data; + udf_set_regid(regid, IMPL_NAME); + udf_add_app_regid(ump, regid); + } else { + if (impl_use_len) + memset(vat->data, 0, impl_use_len); + vat->impl_use_len = 0; + } + error = udf_vat_write(vat_node, raw_vat, vat_length, 0); } +errout: free(raw_vat, M_TEMP); return error; /* success! */ @@ -2997,7 +3018,7 @@ udf_check_for_vat(struct udf_node *vat_n /* definition */ vat = (struct udf_vat *) raw_vat; - vat_offset = vat->header_len; + vat_offset = udf_rw16(vat->header_len); vat_entries = (vat_length - vat_offset)/4; assert(lvinfo);