31
31
#include <sys/sysmacros.h>
32
32
#include <sys/types.h>
33
33
#include <sys/stat.h>
34
+ #include <sys/statfs.h>
34
35
#include <limits.h>
35
36
#include <unistd.h>
36
37
#include "injector_internal.h"
45
46
#define Elf_Sym Elf32_Sym
46
47
#endif
47
48
49
+ // #define INJECTOR_DEBUG_ELF_C 1
50
+
51
+ #ifdef INJECTOR_DEBUG_ELF_C
52
+ #undef DEBUG
53
+ #define DEBUG (...) fprintf(stderr, __VA_ARGS__)
54
+ #else
55
+ #undef DEBUG
56
+ #define DEBUG (...) do {} while(0)
57
+ #endif
58
+
48
59
typedef struct {
49
60
int dlfunc_type ; /* -1, DLFUNC_POSIX or DLFUNC_INTERNAL */
50
61
FILE * fp ;
@@ -288,6 +299,7 @@ static int search_and_open_libc(FILE **fp_out, pid_t pid, size_t *addr, libc_typ
288
299
injector__set_errmsg ("failed to open %s. (error: %s)" , buf , strerror (errno ));
289
300
return INJERR_OTHER ;
290
301
}
302
+ DEBUG ("Open %s\n" , buf );
291
303
/* /libc.so.6 or /libc-2.{DIGITS}.so or /ld-musl-{arch}.so.1 */
292
304
if (regcomp (& reg , "/libc(\\.so\\.6|-2\\.[0-9]+\\.so)|/ld-musl-.+?\\.so\\.1" , REG_EXTENDED ) != 0 ) {
293
305
injector__set_errmsg ("regcomp failed!" );
@@ -297,6 +309,7 @@ static int search_and_open_libc(FILE **fp_out, pid_t pid, size_t *addr, libc_typ
297
309
unsigned long saddr , eaddr ;
298
310
unsigned long long offset , inode ;
299
311
unsigned int dev_major , dev_minor ;
312
+ DEBUG (" %s" , buf );
300
313
if (sscanf (buf , "%lx-%lx %*s %llx %x:%x %llu" , & saddr , & eaddr , & offset , & dev_major , & dev_minor , & inode ) != 6 ) {
301
314
continue ;
302
315
}
@@ -325,7 +338,9 @@ static int search_and_open_libc(FILE **fp_out, pid_t pid, size_t *addr, libc_typ
325
338
}
326
339
regfree (& reg );
327
340
* p = '\0' ;
328
- return open_libc (fp_out , strchr (buf , '/' ), pid , makedev (dev_major , dev_minor ), inode );
341
+ p = strchr (buf , '/' );
342
+ DEBUG (" libc in /proc/PID/maps: '%s'\n" , p );
343
+ return open_libc (fp_out , p , pid , makedev (dev_major , dev_minor ), inode );
329
344
}
330
345
fclose (fp );
331
346
injector__set_errmsg ("Could not find libc" );
@@ -387,19 +402,58 @@ static int open_libc(FILE **fp_out, const char *path, pid_t pid, dev_t dev, ino_
387
402
return 0 ;
388
403
}
389
404
405
+ static inline int is_on_overlay_fs (int fd )
406
+ {
407
+ struct statfs sbuf ;
408
+ if (fstatfs (fd , & sbuf ) != 0 ) {
409
+ DEBUG (" fstatfs() error %s\n" , strerror (errno ));
410
+ return -1 ;
411
+ }
412
+ #ifndef OVERLAYFS_SUPER_MAGIC
413
+ #define OVERLAYFS_SUPER_MAGIC 0x794c7630
414
+ #endif
415
+ return (sbuf .f_type == OVERLAYFS_SUPER_MAGIC ) ? 1 : 0 ;
416
+ }
417
+
390
418
static FILE * fopen_with_ino (const char * path , dev_t dev , ino_t ino )
391
419
{
420
+ DEBUG (" checking: '%s' ..." , path );
392
421
struct stat sbuf ;
393
422
FILE * fp = fopen (path , "r" );
394
423
395
424
if (fp == NULL ) {
425
+ DEBUG (" fopen() error %s\n" , strerror (errno ));
396
426
return NULL ;
397
427
}
398
- if (fstat (fileno (fp ), & sbuf ) != 0 || sbuf .st_dev != dev || sbuf .st_ino != ino ) {
399
- fclose (fp );
400
- return NULL ;
428
+
429
+ if (fstat (fileno (fp ), & sbuf ) != 0 ) {
430
+ DEBUG (" fstat() error %s\n" , strerror (errno ));
431
+ goto cleanup ;
432
+ }
433
+ if (sbuf .st_ino != ino ) {
434
+ DEBUG (" unexpected inode number: expected %llu but %llu\n" ,
435
+ (unsigned long long )ino , (unsigned long long )sbuf .st_ino );
436
+ goto cleanup ;
401
437
}
438
+ if (sbuf .st_dev != dev ) {
439
+ int rv = is_on_overlay_fs (fileno (fp ));
440
+ if (rv < 0 ) {
441
+ goto cleanup ;
442
+ }
443
+ if (rv != 1 ) {
444
+ DEBUG (" unexpected device number: expected %llu but %llu\n" ,
445
+ (unsigned long long )dev , (unsigned long long )sbuf .st_dev );
446
+ goto cleanup ;
447
+ }
448
+ DEBUG (" ignore device number mismatch (expected %llu but %llu) on overlay file system ... " ,
449
+ (unsigned long long )dev , (unsigned long long )sbuf .st_dev );
450
+ }
451
+
452
+ DEBUG (" OK\n" );
402
453
return fp ;
454
+ cleanup :
455
+ fclose (fp );
456
+ return NULL ;
403
457
}
404
458
405
459
static int read_elf_ehdr (FILE * fp , Elf_Ehdr * ehdr )
0 commit comments