authorgravatar for jari.vetoniemi@cloudef.pwJari Vetoniemi <jari.vetoniemi@cloudef.pw> 2024-02-15 21:06:29+09:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2024-03-16 23:27:36+02:00
log59e9f529df75ee89ba7c72e6e5a6df8b35556ab9
tree68b832392eca7a7915bb2261fe853592c87c06c5
parentdbb11915bd03992ff9b64cd7f373faa428f0cedf

std: do not use inferred errors in dynamic_library

The error unions for WindowsDynLib and ElfDynLib do not contain all the possible errors. So user code that relies on DynLib.Error will fail to compile.

1 files changed, 27 insertions(+), 13 deletions(-)

lib/std/dynamic_library.zig+27-13
...@@ -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;
115115
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);
120120
...@@ -250,7 +250,7 @@ pub const ElfDynLib = struct {...@@ -250,7 +250,7 @@ pub const ElfDynLib = struct {
250 }250 }
251251
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 }
256256
...@@ -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}
316316
317test "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
317pub const WindowsDynLib = struct {328pub const WindowsDynLib = struct {
318 pub const Error = error{FileNotFound};329 pub const Error = error{
330 FileNotFound,
331 InvalidPath,
332 } || windows.LoadLibraryError;
319333
320 dll: windows.HMODULE,334 dll: windows.HMODULE,
321335
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 }
325339
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 }
330344
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 }
334348
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 }
339353
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 }
343357
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 {
372386
373 handle: *anyopaque,387 handle: *anyopaque,
374388
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 }
379393
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;