| ... | @@ -111,10 +111,10 @@ pub const ElfDynLib = struct { | ... | @@ -111,10 +111,10 @@ pub const ElfDynLib = struct { |
| 111 | ElfStringSectionNotFound, | 111 | ElfStringSectionNotFound, |
| 112 | ElfSymSectionNotFound, | 112 | ElfSymSectionNotFound, |
| 113 | ElfHashTableNotFound, | 113 | ElfHashTableNotFound, |
| 114 | }; | 114 | } || os.OpenError || os.MMapError; |
| 115 | | 115 | |
| 116 | /// Trusts the file. Malicious file will be able to execute arbitrary code. | 116 | /// Trusts the file. Malicious file will be able to execute arbitrary code. |
| 117 | pub fn open(path: []const u8) !ElfDynLib { | 117 | pub fn open(path: []const u8) Error!ElfDynLib { |
| 118 | const fd = try os.open(path, .{ .ACCMODE = .RDONLY, .CLOEXEC = true }, 0); | 118 | const fd = try os.open(path, .{ .ACCMODE = .RDONLY, .CLOEXEC = true }, 0); |
| 119 | defer os.close(fd); | 119 | defer os.close(fd); |
| 120 | | 120 | |
| ... | @@ -250,7 +250,7 @@ pub const ElfDynLib = struct { | ... | @@ -250,7 +250,7 @@ pub const ElfDynLib = struct { |
| 250 | } | 250 | } |
| 251 | | 251 | |
| 252 | /// Trusts the file. Malicious file will be able to execute arbitrary code. | 252 | /// Trusts the file. Malicious file will be able to execute arbitrary code. |
| 253 | pub fn openZ(path_c: [*:0]const u8) !ElfDynLib { | 253 | pub fn openZ(path_c: [*:0]const u8) Error!ElfDynLib { |
| 254 | return open(mem.sliceTo(path_c, 0)); | 254 | return open(mem.sliceTo(path_c, 0)); |
| 255 | } | 255 | } |
| 256 | | 256 | |
| ... | @@ -314,34 +314,48 @@ fn checkver(def_arg: *elf.Verdef, vsym_arg: i32, vername: []const u8, strings: [ | ... | @@ -314,34 +314,48 @@ fn checkver(def_arg: *elf.Verdef, vsym_arg: i32, vername: []const u8, strings: [ |
| 314 | return mem.eql(u8, vername, mem.sliceTo(strings + aux.vda_name, 0)); | 314 | return mem.eql(u8, vername, mem.sliceTo(strings + aux.vda_name, 0)); |
| 315 | } | 315 | } |
| 316 | | 316 | |
| | 317 | test "ElfDynLib" { |
| | 318 | if (builtin.os.tag != .linux) { |
| | 319 | return error.SkipZigTest; |
| | 320 | } |
| | 321 | |
| | 322 | _ = ElfDynLib.open("invalid_so.so") catch |err| { |
| | 323 | try testing.expect(err == error.FileNotFound); |
| | 324 | return; |
| | 325 | }; |
| | 326 | } |
| | 327 | |
| 317 | pub const WindowsDynLib = struct { | 328 | pub const WindowsDynLib = struct { |
| 318 | pub const Error = error{FileNotFound}; | 329 | pub const Error = error{ |
| | 330 | FileNotFound, |
| | 331 | InvalidPath, |
| | 332 | } || windows.LoadLibraryError; |
| 319 | | 333 | |
| 320 | dll: windows.HMODULE, | 334 | dll: windows.HMODULE, |
| 321 | | 335 | |
| 322 | pub fn open(path: []const u8) !WindowsDynLib { | 336 | pub fn open(path: []const u8) Error!WindowsDynLib { |
| 323 | return openEx(path, .none); | 337 | return openEx(path, .none); |
| 324 | } | 338 | } |
| 325 | | 339 | |
| 326 | pub fn openEx(path: []const u8, flags: windows.LoadLibraryFlags) !WindowsDynLib { | 340 | pub fn openEx(path: []const u8, flags: windows.LoadLibraryFlags) Error!WindowsDynLib { |
| 327 | const path_w = try windows.sliceToPrefixedFileW(null, path); | 341 | const path_w = windows.sliceToPrefixedFileW(null, path) catch return error.InvalidPath; |
| 328 | return openExW(path_w.span().ptr, flags); | 342 | return openExW(path_w.span().ptr, flags); |
| 329 | } | 343 | } |
| 330 | | 344 | |
| 331 | pub fn openZ(path_c: [*:0]const u8) !WindowsDynLib { | 345 | pub fn openZ(path_c: [*:0]const u8) Error!WindowsDynLib { |
| 332 | return openExZ(path_c, .none); | 346 | return openExZ(path_c, .none); |
| 333 | } | 347 | } |
| 334 | | 348 | |
| 335 | pub fn openExZ(path_c: [*:0]const u8, flags: windows.LoadLibraryFlags) !WindowsDynLib { | 349 | pub fn openExZ(path_c: [*:0]const u8, flags: windows.LoadLibraryFlags) Error!WindowsDynLib { |
| 336 | const path_w = try windows.cStrToPrefixedFileW(null, path_c); | 350 | const path_w = try windows.cStrToPrefixedFileW(null, path_c); |
| 337 | return openExW(path_w.span().ptr, flags); | 351 | return openExW(path_w.span().ptr, flags); |
| 338 | } | 352 | } |
| 339 | | 353 | |
| 340 | pub fn openW(path_w: [*:0]const u16) !WindowsDynLib { | 354 | pub fn openW(path_w: [*:0]const u16) Error!WindowsDynLib { |
| 341 | return openExW(path_w, .none); | 355 | return openExW(path_w, .none); |
| 342 | } | 356 | } |
| 343 | | 357 | |
| 344 | pub fn openExW(path_w: [*:0]const u16, flags: windows.LoadLibraryFlags) !WindowsDynLib { | 358 | pub fn openExW(path_w: [*:0]const u16, flags: windows.LoadLibraryFlags) Error!WindowsDynLib { |
| 345 | var offset: usize = 0; | 359 | var offset: usize = 0; |
| 346 | if (path_w[0] == '\\' and path_w[1] == '?' and path_w[2] == '?' and path_w[3] == '\\') { | 360 | if (path_w[0] == '\\' and path_w[1] == '?' and path_w[2] == '?' and path_w[3] == '\\') { |
| 347 | // + 4 to skip over the \??\ | 361 | // + 4 to skip over the \??\ |
| ... | @@ -372,12 +386,12 @@ pub const DlDynLib = struct { | ... | @@ -372,12 +386,12 @@ pub const DlDynLib = struct { |
| 372 | | 386 | |
| 373 | handle: *anyopaque, | 387 | handle: *anyopaque, |
| 374 | | 388 | |
| 375 | pub fn open(path: []const u8) !DlDynLib { | 389 | pub fn open(path: []const u8) Error!DlDynLib { |
| 376 | const path_c = try os.toPosixPath(path); | 390 | const path_c = try os.toPosixPath(path); |
| 377 | return openZ(&path_c); | 391 | return openZ(&path_c); |
| 378 | } | 392 | } |
| 379 | | 393 | |
| 380 | pub fn openZ(path_c: [*:0]const u8) !DlDynLib { | 394 | pub fn openZ(path_c: [*:0]const u8) Error!DlDynLib { |
| 381 | return DlDynLib{ | 395 | return DlDynLib{ |
| 382 | .handle = system.dlopen(path_c, system.RTLD.LAZY) orelse { | 396 | .handle = system.dlopen(path_c, system.RTLD.LAZY) orelse { |
| 383 | return error.FileNotFound; | 397 | return error.FileNotFound; |