mbox series

[00/58] Hide internal functions in libc.so

Message ID 20170901180029.9527-1-hjl.tools@gmail.com
Headers show
Series Hide internal functions in libc.so | expand

Message

H.J. Lu Sept. 1, 2017, 5:59 p.m. UTC
On x86,

# readelf -rW libc_pic.a | grep " __" | grep PLT32  | awk '{ print $5 }' | sort | uniq

shows that many internal functions are called via PLT in libc.so.  This
series of patches hides internal functions to allow direct access within
libc.so and libc.a without using GOT nor PLT.

H.J. Lu (58):
  Mark internal functions with attribute_hidden [BZ #18822]
  Mark 3 *_internal functions with attribute_hidden [BZ #18822]
  Mark __internal_statvfs[64] with attribute_hidden [BZ #18822]
  Mark ____wcsto*_l_internal functions with attribute_hidden [BZ #18822]
  Mark internal argp functions with attribute_hidden [BZ #18822]
  Mark internal unistd functions with attribute_hidden [BZ #18822]
  Mark internal grp/pwd/shadow functions with attribute_hidden [BZ
    #18822]
  Mark __dso_handle as hidden [BZ #18822]
  Mark internal wchar functions with attribute_hidden [BZ #18822]
  Mark internal gmp functions with attribute_hidden [BZ #18822]
  Mark internal nscd functions with attribute_hidden [BZ #18822]
  Mark internal time functions with attribute_hidden [BZ #18822]
  Mark internal statfs functions with attribute_hidden [BZ #18822]
  Mark internal gshadow functions with attribute_hidden [BZ #18822]
  Mark internal stdio functions with attribute_hidden [BZ #18822]
  Mark internal getXXXbyYYY functions with attribute_hidden [BZ #18822]
  Mark internal dirent functions with attribute_hidden [BZ #18822]
  Mark internal utmp functions with attribute_hidden [BZ #18822]
  Mark internal stdlib functions with attribute_hidden [BZ #18822]
  Hide internal regex functions [BZ #18822]
  Hide __readv and __writev [BZ #18822]
  Mark internal rpc functions with attribute_hidden [BZ #18822]
  Mark internal netlink functions with attribute_hidden [BZ #18822]
  Hide __chmod and __mkdir [BZ #18822]
  Hide internal sysinfo functions [BZ #18822]
  Mark internal intl functions with attribute_hidden [BZ #18822]
  Hide internal __ioctl function [BZ #18822]
  Hide internal __malloc_check_init function [BZ #18822]
  Hide internal __mremap function [BZ #18822]
  Hide __posix_spawn_file_actions_realloc/__spawni [BZ #18822]
  Hide internal __strsep function [BZ #18822]
  Hide internal signal functions [BZ #18822]
  Hide internal __sysinfo function [BZ #18822]
  Hide internal __assert_fail_base function [BZ #18822]
  Hide internal __tdestroy function [BZ #18822]
  Hide internal __fopen_maybe_mmap function [BZ #18822]
  Hide internal __bsd_getpt function [BZ #18822]
  Move hidden_proto (__dl_iterate_phdr) to include/link.h [BZ #18822]
  Hide internal __get_sol function [BZ #18822]
  Hide internal __gettextparse function [BZ #18822]
  Hide internal idna functions [BZ #18822]
  Hide internal __ifreq function [BZ #18822]
  Hide internal __hasmntopt function [BZ #18822]
  Hide internal __hash_string function [BZ #18822]
  Hide internal __sched_setparam function [BZ #18822]
  Hide internal __vstrfmon_l function [BZ #18822]
  Hide internal __setrlimit function [BZ #18822]
  Hide internal __tcgetattr function [BZ #18822]
  Hide internal __nis_hash function [BZ #18822]
  Hide internal __setfpucw function [BZ #18822]
  Hide internal __init_misc function [BZ #18822]
  Hide internal __libc_print_version function [BZ #18822]
  Hide internal __moncontrol function [BZ #18822]
  Hide internal __new_exitfn function [BZ #18822]
  Hide internal __new_getrlimit function [BZ #18822]
  Hide internal __glob64 function [BZ #18822]
  Hide internal __sched_setaffinity_new function [BZ #18822]
  Hide internal fadvise64/fallocate64 functions [BZ #18822]

 argp/argp-fmtstream.c                              |  2 +-
 argp/argp-fs-xinl.c                                |  2 +-
 argp/argp-help.c                                   |  4 +-
 argp/argp-parse.c                                  |  2 +-
 argp/argp-xinl.c                                   |  2 +-
 csu/version.c                                      |  2 +-
 dlfcn/modatexit.c                                  |  2 -
 dlfcn/modcxaatexit.c                               |  1 -
 dlfcn/tstatexit.c                                  |  8 ---
 dlfcn/tstcxaatexit.c                               |  8 ---
 elf/dl-iteratephdr.c                               |  1 -
 gmon/gmon.c                                        |  2 +
 iconv/gconv_int.h                                  | 43 +++++++++------
 include/aliases.h                                  |  3 +-
 include/argp-fmtstream.h                           | 19 +++++++
 include/argp.h                                     | 10 ++++
 include/assert.h                                   |  2 +-
 include/dirent.h                                   | 13 ++---
 include/dlfcn.h                                    |  3 +-
 include/fpu_control.h                              |  2 +-
 include/glob.h                                     |  1 +
 include/gmp.h                                      | 33 +++++++++---
 include/grp.h                                      |  6 +--
 include/gshadow.h                                  |  6 ++-
 include/idna.h                                     |  8 +++
 include/ifreq.h                                    | 14 +++++
 include/libc-internal.h                            |  2 +-
 include/link.h                                     |  1 +
 include/malloc.h                                   |  2 +
 include/mntent.h                                   |  1 +
 include/monetary.h                                 |  3 +-
 include/netdb.h                                    | 30 +++++++----
 include/plural-exp.h                               |  8 +++
 include/pwd.h                                      |  6 +--
 include/regex.h                                    |  6 ++-
 include/rpc/netdb.h                                |  4 +-
 include/rpc/rpc.h                                  |  8 +--
 include/sched.h                                    |  1 +
 include/search.h                                   |  1 +
 include/shadow.h                                   |  7 +--
 include/signal.h                                   |  4 ++
 include/stdio.h                                    | 20 +++----
 include/stdlib.h                                   | 63 +++++++++++++---------
 include/string.h                                   |  1 +
 include/sys/ioctl.h                                |  1 +
 include/sys/mman.h                                 |  1 +
 include/sys/resource.h                             |  1 +
 include/sys/stat.h                                 |  2 +
 include/sys/statfs.h                               |  9 ++--
 include/sys/statvfs.h                              |  6 ++-
 include/sys/sysinfo.h                              |  6 ++-
 include/sys/uio.h                                  |  2 +
 include/termios.h                                  |  1 +
 include/time.h                                     | 32 ++++++-----
 include/unistd.h                                   | 60 +++++++++++----------
 include/utmp.h                                     | 28 ++++++----
 include/wchar.h                                    | 61 ++++++++++++++++-----
 inet/getnameinfo.c                                 |  4 +-
 intl/gettextP.h                                    | 17 +++---
 intl/hash-string.h                                 |  3 +-
 intl/plural-exp.c                                  |  2 +-
 intl/plural-exp.h                                  |  5 +-
 io/chmod.c                                         |  1 +
 io/mkdir.c                                         |  1 +
 libio/iolibio.h                                    |  5 +-
 locale/coll-lookup.h                               |  6 ++-
 malloc/mtrace.c                                    |  3 +-
 misc/getsysstats.c                                 |  4 ++
 misc/ioctl.c                                       |  1 +
 misc/mntent_r.c                                    |  1 +
 misc/readv.c                                       |  1 +
 misc/tsearch.c                                     |  1 +
 misc/writev.c                                      |  1 +
 nptl/pthread_atfork.c                              |  7 +--
 nptl/tst-atfork2mod.c                              |  1 -
 nscd/nscd-client.h                                 | 12 +++--
 nscd/nscd_helper.c                                 |  5 ++
 nscd/nscd_proto.h                                  | 34 +++++++-----
 nss/getXXbyYY.c                                    |  3 +-
 posix/regcomp.c                                    |  2 +
 posix/regexec.c                                    |  2 +
 posix/sched_setp.c                                 |  1 +
 posix/spawn_int.h                                  |  5 +-
 posix/wordexp-test.c                               |  4 +-
 resolv/gai_misc.h                                  | 15 ++++--
 resource/setrlimit.c                               |  1 +
 signal/kill.c                                      |  1 +
 signal/sigblock.c                                  |  1 +
 signal/sigprocmask.c                               |  1 +
 stdlib/at_quick_exit.c                             |  7 +--
 stdlib/atexit.c                                    |  8 +--
 stdlib/canonicalize.c                              |  1 +
 stdlib/exit.h                                      |  3 +-
 stdlib/gmp-impl.h                                  | 12 +++--
 stdlib/tst-tls-atexit-lib.c                        |  2 -
 string/strsep.c                                    |  1 +
 sysdeps/generic/aio_misc.h                         |  3 +-
 sysdeps/generic/ifreq.h                            | 12 -----
 sysdeps/generic/ldsodefs.h                         |  8 +--
 sysdeps/i386/machine-gmon.h                        |  2 +-
 sysdeps/ieee754/float128/wcstof128.c               |  3 --
 sysdeps/ieee754/float128/wcstof128_l.c             |  3 --
 sysdeps/mach/getsysstats.c                         |  4 ++
 sysdeps/mach/hurd/chmod.c                          |  1 +
 sysdeps/mach/hurd/ifreq.h                          | 12 -----
 sysdeps/mach/hurd/ioctl.c                          |  1 +
 sysdeps/mach/hurd/kill.c                           |  1 +
 sysdeps/mach/hurd/mkdir.c                          |  1 +
 sysdeps/mach/hurd/readdir64.c                      |  1 +
 sysdeps/mach/hurd/setrlimit.c                      |  1 +
 sysdeps/mach/hurd/sigaltstack.c                    |  1 +
 sysdeps/mach/hurd/sigprocmask.c                    |  1 +
 sysdeps/posix/getaddrinfo.c                        |  5 +-
 sysdeps/posix/readv.c                              |  1 +
 sysdeps/posix/sigblock.c                           |  1 +
 sysdeps/posix/writev.c                             |  1 +
 sysdeps/unix/bsd/tcgetattr.c                       |  1 +
 sysdeps/unix/sysv/linux/aarch64/ioctl.S            |  1 +
 sysdeps/unix/sysv/linux/alpha/sigprocmask.c        |  1 +
 sysdeps/unix/sysv/linux/fstatvfs.c                 |  6 +--
 sysdeps/unix/sysv/linux/fstatvfs64.c               |  7 +--
 sysdeps/unix/sysv/linux/generic/chmod.c            |  2 +
 sysdeps/unix/sysv/linux/generic/mkdir.c            |  2 +
 sysdeps/unix/sysv/linux/getpt.c                    |  2 +-
 sysdeps/unix/sysv/linux/getrlimit64.c              |  3 +-
 sysdeps/unix/sysv/linux/getsourcefilter.c          |  1 +
 sysdeps/unix/sysv/linux/getsourcefilter.h          | 20 +++++++
 sysdeps/unix/sysv/linux/getsysstats.c              |  4 ++
 sysdeps/unix/sysv/linux/i386/glob64.c              |  1 +
 sysdeps/unix/sysv/linux/i386/olddirent.h           |  3 +-
 sysdeps/unix/sysv/linux/i386/readdir64.c           |  1 +
 sysdeps/unix/sysv/linux/ia64/sigprocmask.c         |  1 +
 sysdeps/unix/sysv/linux/include/sys/sysinfo.h      |  2 +-
 sysdeps/unix/sysv/linux/internal_statvfs.c         |  2 +-
 sysdeps/unix/sysv/linux/internal_statvfs.h         | 26 +++++++++
 sysdeps/unix/sysv/linux/m68k/mremap.S              |  1 +
 sysdeps/unix/sysv/linux/mips/mips64/n64/ioctl.S    |  1 +
 sysdeps/unix/sysv/linux/netlinkaccess.h            | 10 ++--
 sysdeps/unix/sysv/linux/pathconf.h                 | 12 +++--
 sysdeps/unix/sysv/linux/posix_fadvise64.c          |  2 +
 sysdeps/unix/sysv/linux/posix_fallocate64.c        |  2 +
 sysdeps/unix/sysv/linux/powerpc/ioctl.c            |  1 +
 sysdeps/unix/sysv/linux/readdir64.c                |  1 +
 sysdeps/unix/sysv/linux/readv.c                    |  2 +
 sysdeps/unix/sysv/linux/s390/s390-64/sigprocmask.c |  1 +
 sysdeps/unix/sysv/linux/sched_setaffinity.c        |  4 ++
 sysdeps/unix/sysv/linux/setrlimit.c                |  1 +
 sysdeps/unix/sysv/linux/setrlimit64.c              |  3 ++
 sysdeps/unix/sysv/linux/setsourcefilter.c          |  5 +-
 sysdeps/unix/sysv/linux/sigprocmask.c              |  1 +
 .../unix/sysv/linux/sparc/sparc64/sigprocmask.c    |  1 +
 sysdeps/unix/sysv/linux/statvfs.c                  |  6 +--
 sysdeps/unix/sysv/linux/statvfs64.c                |  7 +--
 sysdeps/unix/sysv/linux/tcgetattr.c                |  1 +
 sysdeps/unix/sysv/linux/tile/tilegx/ioctl.S        |  1 +
 sysdeps/unix/sysv/linux/wordsize-64/readdir.c      |  1 +
 sysdeps/unix/sysv/linux/writev.c                   |  2 +
 sysdeps/unix/sysv/linux/x86_64/sigprocmask.c       |  1 +
 termios/tcgetattr.c                                |  1 +
 wcsmbs/wcsmbsload.h                                |  9 ++--
 wcsmbs/wcstod.c                                    |  3 --
 wcsmbs/wcstod_l.c                                  |  3 --
 wcsmbs/wcstof.c                                    |  3 --
 wcsmbs/wcstof_l.c                                  |  3 --
 wcsmbs/wcstol_l.c                                  |  3 --
 wcsmbs/wcstold.c                                   |  3 --
 wcsmbs/wcstold_l.c                                 |  3 --
 wcsmbs/wcstoll_l.c                                 |  3 --
 wcsmbs/wcstoul_l.c                                 |  3 --
 wcsmbs/wcstoull_l.c                                |  4 --
 170 files changed, 635 insertions(+), 384 deletions(-)
 create mode 100644 include/argp-fmtstream.h
 create mode 100644 include/idna.h
 create mode 100644 include/ifreq.h
 create mode 100644 include/plural-exp.h
 create mode 100644 sysdeps/unix/sysv/linux/getsourcefilter.h
 create mode 100644 sysdeps/unix/sysv/linux/internal_statvfs.h

Comments

Florian Weimer Sept. 1, 2017, 6:16 p.m. UTC | #1
On 09/01/2017 07:59 PM, H.J. Lu wrote:
> On x86,
> 
> # readelf -rW libc_pic.a | grep " __" | grep PLT32  | awk '{ print $5 }' | sort | uniq
> 
> shows that many internal functions are called via PLT in libc.so.  This
> series of patches hides internal functions to allow direct access within
> libc.so and libc.a without using GOT nor PLT.

I think we need to automate the generation of hidden attributes (or the
hidden aliases).

Any ideas how we can do this?

Thanks,
Florian
H.J. Lu Sept. 1, 2017, 7:41 p.m. UTC | #2
On Fri, Sep 1, 2017 at 11:16 AM, Florian Weimer <fweimer@redhat.com> wrote:
> On 09/01/2017 07:59 PM, H.J. Lu wrote:
>> On x86,
>>
>> # readelf -rW libc_pic.a | grep " __" | grep PLT32  | awk '{ print $5 }' | sort | uniq
>>
>> shows that many internal functions are called via PLT in libc.so.  This
>> series of patches hides internal functions to allow direct access within
>> libc.so and libc.a without using GOT nor PLT.
>
> I think we need to automate the generation of hidden attributes (or the
> hidden aliases).

I'd love to see it.

> Any ideas how we can do this?
>

It won't be easy.
Joseph Myers Sept. 1, 2017, 8:14 p.m. UTC | #3
On Fri, 1 Sep 2017, Florian Weimer wrote:

> On 09/01/2017 07:59 PM, H.J. Lu wrote:
> > On x86,
> > 
> > # readelf -rW libc_pic.a | grep " __" | grep PLT32  | awk '{ print $5 }' | sort | uniq
> > 
> > shows that many internal functions are called via PLT in libc.so.  This
> > series of patches hides internal functions to allow direct access within
> > libc.so and libc.a without using GOT nor PLT.
> 
> I think we need to automate the generation of hidden attributes (or the
> hidden aliases).

I'm not convinced, for the present patch series.  An internal function 
needs to be declared somewhere anyway, with or without an explicit hidden 
attribute, so putting the attribute there when declaring the function 
doesn't really complicate things.  (I do think that if the attributes are 
explicit, there should also be a test that any external symbol in an 
object going into a shared library, that doesn't end up as a (defined or 
undefined) dynamic symbol in that shared library, is hidden, so that 
adding a non-hidden internal function is immediately visible as a test 
failure.)

> Any ideas how we can do this?

Well, an alternative to marking internal functions hidden would be to mark 
exported functions (mostly but not entirely declared in the public 
headers) as exported, and then build with -fvisibility=hidden.  But that's 
still a lot of declarations in source files.  Maybe for each public header 
you could compile an include of it with -D_GNU_SOURCE -aux-info to get a 
list of functions (like conform/GlibcConform.pm does) and automatically 
generate a header with a series of

extern __typeof (foo) foo __attribute__ ((__visibility__ ("default")));

declarations.  (Note -aux-info only covers functions, not variables, and 
the exported names may not always be the ones declared in the header.  The 
Versions files would be another source of information on what should be 
exported.)

Now, currently getting a list of all public headers requires recursing 
into each build subdirectory and doing something like the above would 
require such recursing before any of the rest of the build could start - 
and recursing into each subdirectory is serialized, and comparatively 
slow.  If it were helpful we could e.g. decide to put all public headers 
either in an include-public directory, or in sysdeps directories, so e.g. 
include-public/stdlib.h instead of stdlib/stdlib.h.
Florian Weimer Sept. 18, 2017, 1:58 p.m. UTC | #4
On 09/01/2017 10:14 PM, Joseph Myers wrote:
> On Fri, 1 Sep 2017, Florian Weimer wrote:
> 
>> On 09/01/2017 07:59 PM, H.J. Lu wrote:
>>> On x86,
>>>
>>> # readelf -rW libc_pic.a | grep " __" | grep PLT32  | awk '{ print $5 }' | sort | uniq
>>>
>>> shows that many internal functions are called via PLT in libc.so.  This
>>> series of patches hides internal functions to allow direct access within
>>> libc.so and libc.a without using GOT nor PLT.
>> I think we need to automate the generation of hidden attributes (or the
>> hidden aliases).
> I'm not convinced, for the present patch series.  An internal function
> needs to be declared somewhere anyway, with or without an explicit hidden
> attribute, so putting the attribute there when declaring the function
> doesn't really complicate things.  (I do think that if the attributes are
> explicit, there should also be a test that any external symbol in an
> object going into a shared library, that doesn't end up as a (defined or
> undefined) dynamic symbol in that shared library, is hidden, so that
> adding a non-hidden internal function is immediately visible as a test
> failure.)

I was concerned about cross-architecture variance in this area.

But I presume we can just add a hidden alias and add the export to the 
relevant sysdeps Versions files, so that's not an actual blocker for 
explicit specification of visibility.

So the main issue here is testing that we do not regression in the 
coverage of hidden declarations.

Thanks,
Florian