(root)/
glib-2.79.0/
glib/
tests/
getpwuid-preload.c
       1  /* GLIB - Library of useful routines for C programming
       2   *
       3   * Copyright (C) 2020 Red Hat, Inc.
       4   *
       5   * Author: Jakub Jelen <jjelen@redhat.com>
       6   *
       7   * SPDX-License-Identifier: LGPL-2.1-or-later
       8   *
       9   * This library is free software; you can redistribute it and/or
      10   * modify it under the terms of the GNU Lesser General Public
      11   * License as published by the Free Software Foundation; either
      12   * version 2.1 of the License, or (at your option) any later version.
      13   *
      14   * This library is distributed in the hope that it will be useful,
      15   * but WITHOUT ANY WARRANTY; without even the implied warranty of
      16   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      17   * Lesser General Public License for more details.
      18   *
      19   * You should have received a copy of the GNU Lesser General
      20   * Public License along with this library; if not, see <http://www.gnu.org/licenses/>.
      21   */
      22  
      23  #include <dlfcn.h>
      24  #include <pwd.h>
      25  #include <sys/types.h>
      26  #include <unistd.h>
      27  
      28  #ifndef __APPLE__
      29  
      30  #define GET_REAL(func) \
      31    (real_##func = dlsym (RTLD_NEXT, #func))
      32  
      33  #define DEFINE_WRAPPER(return_type, func, argument_list) \
      34    static return_type (* real_##func) argument_list;      \
      35    return_type func argument_list
      36  
      37  #else
      38  
      39  #define GET_REAL(func) \
      40    func
      41  
      42  /* https://opensource.apple.com/source/dyld/dyld-852.2/include/mach-o/dyld-interposing.h */
      43  #define DYLD_INTERPOSE(_replacement,_replacee) \
      44     __attribute__((used)) static struct{ const void* replacement; const void* replacee; } _interpose_##_replacee \
      45              __attribute__ ((section ("__DATA,__interpose"))) = { (const void*)(unsigned long)&_replacement, (const void*)(unsigned long)&_replacee };
      46  
      47  #define DEFINE_WRAPPER(return_type, func, argument_list) \
      48    static return_type wrap_##func argument_list;          \
      49    DYLD_INTERPOSE(wrap_##func, func)                      \
      50    static return_type wrap_##func argument_list
      51  
      52  #endif /* __APPLE__ */
      53  
      54  /* This is used in gutils.c used to make sure utility functions
      55   * handling user information do not crash on bad data (for example
      56   * caused by getpwuid returning some NULL elements.
      57   */
      58  
      59  #undef getpwuid
      60  
      61  static struct passwd my_pw;
      62  
      63  DEFINE_WRAPPER (struct passwd *, getpwuid, (uid_t uid))
      64  {
      65    struct passwd *pw = GET_REAL (getpwuid) (uid);
      66    my_pw = *pw;
      67    my_pw.pw_name = NULL;
      68    return &my_pw;
      69  }
      70  
      71  DEFINE_WRAPPER (int, getpwnam_r, (const char     *name,
      72                                    struct passwd  *pwd,
      73                                    char            buf[],
      74                                    size_t          buflen,
      75                                    struct passwd **result))
      76  {
      77    int code = GET_REAL (getpwnam_r) (name, pwd, buf, buflen, result);
      78    pwd->pw_name = NULL;
      79    return code;
      80  }
      81  
      82  DEFINE_WRAPPER (int, getpwuid_r, (uid_t           uid,
      83                                    struct passwd  *restrict pwd,
      84                                    char            buf[],
      85                                    size_t          buflen,
      86                                    struct passwd **result))
      87  {
      88    int code = GET_REAL (getpwuid_r) (uid, pwd, buf, buflen, result);
      89    pwd->pw_name = NULL;
      90    return code;
      91  }