エクスポートされた変数に対してgetenvを呼び出すと、root以外のユーザーがnilを返すのはなぜですか?

エクスポートされた変数に対してgetenvを呼び出すと、root以外のユーザーがnilを返すのはなぜですか?

Cコードは次のとおりです。

#include <stdio.h>
#include <stdlib.h>

int main () {
   printf("PATH : %s\n", getenv("PATH"));
   printf("HOME : %s\n", getenv("HOME"));
   printf("ROOT : %s\n", getenv("ROOT"));
   printf("TMPDIR : %s\n", getenv("TMPDIR"));
   return(0);
}

完了後:

gcc env.c -o printenv
setcap 'cap_dac_override+eip' printenv
sudo -S su -s $(which bash) steve
export TMDIR=hello
./printenv

私は次のような結果を得ます。

PATH : /sbin:/bin:/usr/sbin:/usr/bin
HOME : /home/steve
ROOT : (null)
TMPDIR : (null)

「printenv」に設定されたCAPを削除すると、出力は次のようになります。

PATH : /sbin:/bin:/usr/sbin:/usr/bin
HOME : /home/steve
ROOT : (null)
TMPDIR : hello

どうやって?

いくつかの検索の最後に、以下を発見しました。http://ポーラホーム.com/service/man/?qf=secure_getenv&tf=2&of=RedHat&sf=

これは、関数の設定時にgetenvがsecure_getenvになり、すべてのgetenv()lib呼び出しがnilを返すためである可能性があると述べていますが、この場合、環境変数をどのようにPATH印刷しますか?HOME

答え1

まあ、何回の調査の終わりにその理由を見つけました。 「TMPDIR」はldの特殊変数の1つです。したがって、セキュリティ上の理由からCAPが設定され、実行ユーザーがrootでない場合は無視されます。詳細については、ldのマニュアルページを参照してください。だから:https://man7.org/linux/man-pages/man8/ld.so.8.html

ENVIRONMENT         top
       Various environment variables influence the operation of the
       dynamic linker.

   Secure-execution mode
       For security reasons, if the dynamic linker determines that a
       binary should be run in secure-execution mode, the effects of
       some environment variables are voided or modified, and
       furthermore those environment variables are stripped from the
       environment, so that the program does not even see the
       definitions.  Some of these environment variables affect the
       operation of the dynamic linker itself, and are described below.
       Other environment variables treated in this way include:
       GCONV_PATH, GETCONF_DIR, HOSTALIASES, LOCALDOMAIN, LOCPATH,
       MALLOC_TRACE, NIS_PATH, NLSPATH, RESOLV_HOST_CONF, RES_OPTIONS,
       TMPDIR, and TZDIR.

       A binary is executed in secure-execution mode if the AT_SECURE
       entry in the auxiliary vector (see getauxval(3)) has a nonzero
       value.  This entry may have a nonzero value for various reasons,
       including:

       *  The process's real and effective user IDs differ, or the real
          and effective group IDs differ.  This typically occurs as a
          result of executing a set-user-ID or set-group-ID program.

       *  A process with a non-root user ID executed a binary that
          conferred capabilities to the process.

       *  A nonzero value may have been set by a Linux Security Module.

関連情報