@@ -44,6 +44,53 @@ fn sigaddset(set: *sigset_t, sig: c_int) void {
4444 set .val [s / 32 ] |= @as (u32 , 1 ) << @intCast (s % 32 );
4545}
4646
47+ fn validateTargetArch (pid : i32 ) error {ArchMismatch }! void {
48+ var path_buf : [32 ]u8 = undefined ;
49+ const exe_path = std .fmt .bufPrint (& path_buf , "/proc/{d}/exe" , .{pid }) catch return ;
50+
51+ const fd = std .posix .openat (std .posix .AT .FDCWD , exe_path , .{ .ACCMODE = .RDONLY }, 0 ) catch return ;
52+ defer _ = std .c .close (fd );
53+
54+ var header : [20 ]u8 = undefined ;
55+ var n : usize = 0 ;
56+ while (n < header .len ) {
57+ const r = std .posix .read (fd , header [n .. ]) catch return ;
58+ if (r == 0 ) return ;
59+ n += r ;
60+ }
61+
62+ if (! std .mem .eql (u8 , header [0.. 4], "\x7f ELF" )) return ;
63+
64+ const endian : std.builtin.Endian = switch (header [5 ]) {
65+ 1 = > .little ,
66+ 2 = > .big ,
67+ else = > return ,
68+ };
69+ const e_machine = std .mem .readInt (u16 , header [18.. 20], endian );
70+ const native_machine : u16 = switch (builtin .cpu .arch ) {
71+ .x86_64 = > 62 ,
72+ .aarch64 = > 183 ,
73+ else = > return ,
74+ };
75+
76+ if (e_machine != native_machine ) {
77+ const target_name : []const u8 = switch (e_machine ) {
78+ 62 = > "x86_64" ,
79+ 183 = > "aarch64" ,
80+ 3 = > "x86" ,
81+ 40 = > "arm" ,
82+ else = > "unknown" ,
83+ };
84+ const self_name = comptime switch (builtin .cpu .arch ) {
85+ .x86_64 = > "x86_64" ,
86+ .aarch64 = > "aarch64" ,
87+ else = > unreachable ,
88+ };
89+ std .debug .print ("Target is {s} but injector is {s}\n " , .{ target_name , self_name });
90+ return error .ArchMismatch ;
91+ }
92+ }
93+
4794pub fn inject (
4895 io : std.Io ,
4996 allocator : std.mem.Allocator ,
@@ -58,6 +105,8 @@ pub fn inject(
58105 break :blk val [0 ] == '1' ;
59106 };
60107
108+ try validateTargetArch (tgid );
109+
61110 var mask = sigset_t {};
62111 sigaddset (& mask , SIGUSR1 );
63112 sigaddset (& mask , SIGUSR2 );
0 commit comments