I'd like to run a service as a non-privileged user, but it needs to bind to a system port number (i.e. less than 1024), so I give it setcap 'cap_net_bind_service=+ep' <path for service>, all good.

Problem is, on startup, the service reads environment vars and for some reason it can't do that when it has cap_net_bind_service. So, with two copies of the executable, one with cap_net_bind_service, one without, only the one without can read environment vars.

It's as though there's a default set of capabilities that allows reading env vars, but the exe loses that capability when I give it cap_net_bind_service. Is that right, or is something else going on? What additional capability might I need to give to the service so that it can read env vars? There's nothing in capability.h that jumps out as being "allow env var reading"?

1 Answer 1


I got to the bottom of it. In brief, the binary is using secure_getenv to access environment variables. This returns null, instead of accessing the variables, when the binary is run in "secure execution" mode (AT_SECURE=1). Having any capability set, causes it to run in this mode.

Confirm that the binary is using secure_getenv using readelf:

readelf -a <path for service> | grep getenv
00000040ac28  004b00000007 R_X86_64_JUMP_SLO 0000000000000000 secure_getenv@GLIBC_2.17 + 0
00000040ad90  007a00000007 R_X86_64_JUMP_SLO 0000000000000000 getenv@GLIBC_2.2.5 + 0
    75: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND secure_getenv@GLIBC_2.17 (6)
   122: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND getenv@GLIBC_2.2.5 (2)

Confirm that it's running in secure execution mode with environment variables (how ironic!) LD_DEBUG=all and/or LD_SHOW_AUXV (see man ld.so).

If it isn't then LD_SHOW_AUXV produces output with AT_SECURE set to 0. There is no output from LD_SHOW_AUXV when it is running in secure execution mode.

Normally, there is/isn't output from LD_DEBUG too when it is/isn't running in secure execution mode. However, if /etc/suid-debug is present (empty file, create with touch), then LD_DEBUG will produce output when running in secure execution mode.

See man getauxval for more information about AT_SECURE and secure execution mode.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.