+ /* Check if the security descriptor will be affected by one of the bugs.
+ * If not, do nothing and return.
+ *
+ * Note: HAVE_NTFS_MNT_RDONLY is defined if libntfs-3g is
+ * version 2013.1.13 or later. */
+ if (!(
+ #if !defined(HAVE_NTFS_MNT_RDONLY)
+ (sacl_offset != 0 && sacl_offset == size - sizeof(wimlib_ACL)) ||
+ #endif
+ (dacl_offset != 0 && dacl_offset == size - sizeof(wimlib_ACL))))
+ return NULL;
+
+ owner_offset = le32_to_cpu(desc->owner_offset);
+ group_offset = le32_to_cpu(desc->group_offset);
+ owner = (const wimlib_SID*)((const u8*)desc + owner_offset);
+ group = (const wimlib_SID*)((const u8*)desc + group_offset);
+
+ /* We'll try to move the owner or group SID to the end of the security
+ * descriptor to avoid the bug. This is only possible if at least one
+ * is valid. */
+ owner_valid = (owner_offset != 0) &&
+ (owner_offset % 4 == 0) &&
+ (owner_offset <= size - sizeof(SID)) &&
+ (owner_offset + sid_size(owner) <= size) &&
+ (owner_offset >= sizeof(wimlib_SECURITY_DESCRIPTOR_RELATIVE));
+ group_valid = (group_offset != 0) &&
+ (group_offset % 4 == 0) &&
+ (group_offset <= size - sizeof(SID)) &&
+ (group_offset + sid_size(group) <= size) &&
+ (group_offset >= sizeof(wimlib_SECURITY_DESCRIPTOR_RELATIVE));
+ if (owner_valid) {
+ sid = owner;
+ } else if (group_valid) {
+ sid = group;
+ } else {
+ return NULL;
+ }
+
+ desc_new = MALLOC(size + sid_size(sid));
+ if (!desc_new)
+ return NULL;
+
+ memcpy(desc_new, desc, size);
+ if (owner_valid)
+ desc_new->owner_offset = cpu_to_le32(size);
+ else if (group_valid)
+ desc_new->group_offset = cpu_to_le32(size);
+ memcpy((u8*)desc_new + size, sid, sid_size(sid));
+ *size_p = size + sid_size(sid);
+ return desc_new;
+}