Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions Sources/ContainerizationEXT4/EXT4+Xattrs.swift
Original file line number Diff line number Diff line change
Expand Up @@ -257,19 +257,22 @@ extension EXT4 {
var i = start
var attribs: [ExtendedAttribute] = []
// 16 is the size of 1 XAttrEntry
while i + 16 < buffer.count {
while i + 16 <= buffer.count {
let attributeStart = i
let rawXattrEntry = Array(buffer[i..<i + 16])
let xattrEntry = try EXT4.XAttrEntry(using: rawXattrEntry)
i += 16
var endIndex = i + Int(xattrEntry.nameLength)
guard endIndex < buffer.count else {
guard endIndex <= buffer.count else {
continue
}
let rawName = buffer[i..<endIndex]
let name = String(bytes: rawName, encoding: .ascii)!
let valueStart = Int(xattrEntry.valueOffset) + offset
let valueEnd = Int(xattrEntry.valueOffset) + Int(xattrEntry.valueSize) + offset
guard valueEnd <= buffer.count else {
break
}
let value = [UInt8](buffer[valueStart..<valueEnd])
let xattr = ExtendedAttribute(idx: xattrEntry.nameIndex, compressedName: name, value: value)
attribs.append(xattr)
Expand Down
28 changes: 28 additions & 0 deletions Tests/ContainerizationEXT4Tests/TestEXT4ExtendedAttributes.swift
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,34 @@ struct TestEXT4ExtendedAttribute {
}
}

@Test func lastXattrNotDroppedAtBufferBoundary() throws {
let buffer: [UInt8] = [
0, // nameLength
8, // nameIndex
0, 0, // valueOffset
0, 0, 0, 0, // valueInum
0, 0, 0, 0, // valueSize
0, 0, 0, 0, // hash
]
let attrs = try EXT4.FileXattrsState.read(buffer: buffer, start: 0, offset: 0)
try #require(attrs.count == 1)
#expect(attrs[0].fullName == "system.richacl")
}

@Test func xattrOutOfBoundsValueDoesNotCrash() throws {
let buffer: [UInt8] = [
1, // nameLength
1, // nameIndex
17, 0, // valueOffset
0, 0, 0, 0, // valueInum
4, 0, 0, 0, // valueSize
0, 0, 0, 0, // hash
UInt8(ascii: "a"), 0, 0, 0, // name
]
let attrs = try EXT4.FileXattrsState.read(buffer: buffer, start: 0, offset: 0)
#expect(attrs.isEmpty)
}

@Test func encodeDecodeAttributes() {
let xattrs: [String: Data] = [
"foo.bar": Data([1, 2, 3]),
Expand Down
Loading