All of lore.kernel.org
 help / color / mirror / Atom feed
From: kernel test robot <lkp@intel.com>
To: kbuild@lists.01.org
Subject: samples/landlock/sandboxer.c:139:1: warning: leak of 'path_list' [CWE-401]
Date: Wed, 06 Apr 2022 00:19:14 +0800	[thread overview]
Message-ID: <202204060055.MeJXeOn7-lkp@intel.com> (raw)

[-- Attachment #1: Type: text/plain, Size: 20863 bytes --]

CC: kbuild-all(a)lists.01.org
BCC: lkp(a)intel.com
CC: linux-kernel(a)vger.kernel.org
TO: "Mickaël Salaün" <mic@linux.microsoft.com>
CC: James Morris <jamorris@linux.microsoft.com>
CC: Jann Horn <jannh@google.com>
CC: Kees Cook <keescook@chromium.org>

tree:   https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git master
head:   3123109284176b1532874591f7c81f3837bbdc17
commit: ba84b0bf5a164f0f523656c1e37568c30f3f3303 samples/landlock: Add a sandbox manager example
date:   12 months ago
:::::: branch date: 2 days ago
:::::: commit date: 12 months ago
config: i386-randconfig-c001-20220404 (https://download.01.org/0day-ci/archive/20220406/202204060055.MeJXeOn7-lkp(a)intel.com/config)
compiler: gcc-11 (Debian 11.2.0-19) 11.2.0
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=ba84b0bf5a164f0f523656c1e37568c30f3f3303
        git remote add linus https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
        git fetch --no-tags linus master
        git checkout ba84b0bf5a164f0f523656c1e37568c30f3f3303
        # save the config file to linux build tree
         ARCH=i386 KBUILD_USERCFLAGS='-fanalyzer -Wno-error' 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>


gcc-analyzer warnings: (new ones prefixed by >>)
   samples/landlock/sandboxer.c: In function 'populate_ruleset':
>> samples/landlock/sandboxer.c:139:1: warning: leak of 'path_list' [CWE-401] [-Wanalyzer-malloc-leak]
     139 | }
         | ^
     'main': events 1-6
       |
       |  158 | int main(const int argc, char *const argv[], char *const *const envp)
       |      |     ^~~~
       |      |     |
       |      |     (1) entry to 'main'
       |......
       |  168 |         if (argc < 2) {
       |      |            ~
       |      |            |
       |      |            (2) following 'false' branch (when 'argc > 1')...
       |......
       |  186 |         ruleset_fd = landlock_create_ruleset(&ruleset_attr, sizeof(ruleset_attr), 0);
       |      |                      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
       |      |                      |
       |      |                      (3) ...to here
       |  187 |         if (ruleset_fd < 0) {
       |      |            ~
       |      |            |
       |      |            (4) following 'false' branch (when 'ruleset_fd >= 0')...
       |......
       |  208 |         if (populate_ruleset(ENV_FS_RO_NAME, ruleset_fd,
       |      |             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
       |      |             |
       |      |             (5) ...to here
       |      |             (6) calling 'populate_ruleset' from 'main'
       |  209 |                                 ACCESS_FS_ROUGHLY_READ)) {
       |      |                                 ~~~~~~~~~~~~~~~~~~~~~~~
       |
       +--> 'populate_ruleset': events 7-10
              |
              |   78 | static int populate_ruleset(
              |      |            ^~~~~~~~~~~~~~~~
              |      |            |
              |      |            (7) entry to 'populate_ruleset'
              |......
              |   90 |         if (!env_path_name) {
              |      |            ~
              |      |            |
              |      |            (8) following 'false' branch (when 'env_path_name' is non-NULL)...
              |......
              |   95 |         env_path_name = strdup(env_path_name);
              |      |                         ~~~~~~~~~~~~~~~~~~~~~
              |      |                         |
              |      |                         (9) ...to here
              |   96 |         unsetenv(env_var);
              |   97 |         num_paths = parse_path(env_path_name, &path_list);
              |      |                     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
              |      |                     |
              |      |                     (10) calling 'parse_path' from 'populate_ruleset'
              |
              +--> 'parse_path': events 11-14
                     |
                     |   55 | static int parse_path(char *env_path, const char ***const path_list)
                     |      |            ^~~~~~~~~~
                     |      |            |
                     |      |            (11) entry to 'parse_path'
                     |......
                     |   59 |         if (env_path) {
                     |      |            ~
                     |      |            |
                     |      |            (12) following 'true' branch...
                     |   60 |                 num_paths++;
                     |      |                 ~~~~~~~~~~~
                     |      |                          |
                     |      |                          (13) ...to here
                     |......
                     |   66 |         *path_list = malloc(num_paths * sizeof(**path_list));
                     |      |                      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                     |      |                      |
                     |      |                      (14) allocated here
                     |
              <------+
              |
            'populate_ruleset': events 15-19
              |
              |   97 |         num_paths = parse_path(env_path_name, &path_list);
              |      |                     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
              |      |                     |
              |      |                     (15) returning to 'populate_ruleset' from 'parse_path'
              |   98 |         if (num_paths == 1 && path_list[0][0] == '\0') {
              |      |            ~                  ~~~~~~~~~~~~
              |      |            |                           |
              |      |            |                           (17) ...to here
              |      |            |                           (18) assuming 'path_list' is non-NULL
              |      |            (16) following 'true' branch (when 'num_paths == 1')...
              |......
              |  139 | }
              |      | ~                    
              |      | |
              |      | (19) 'path_list' leaks here; was allocated@(14)
              |
>> samples/landlock/sandboxer.c:139:1: warning: leak of 'path_list' [CWE-401] [-Wanalyzer-malloc-leak]
     139 | }
         | ^
     'main': events 1-6
       |
       |  158 | int main(const int argc, char *const argv[], char *const *const envp)
       |      |     ^~~~
       |      |     |
       |      |     (1) entry to 'main'
       |......
       |  168 |         if (argc < 2) {
       |      |            ~
       |      |            |
       |      |            (2) following 'false' branch (when 'argc > 1')...
       |......
       |  186 |         ruleset_fd = landlock_create_ruleset(&ruleset_attr, sizeof(ruleset_attr), 0);
       |      |                      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
       |      |                      |
       |      |                      (3) ...to here
       |  187 |         if (ruleset_fd < 0) {
       |      |            ~
       |      |            |
       |      |            (4) following 'false' branch (when 'ruleset_fd >= 0')...
       |......
       |  208 |         if (populate_ruleset(ENV_FS_RO_NAME, ruleset_fd,
       |      |             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
       |      |             |
       |      |             (5) ...to here
       |      |             (6) calling 'populate_ruleset' from 'main'
       |  209 |                                 ACCESS_FS_ROUGHLY_READ)) {
       |      |                                 ~~~~~~~~~~~~~~~~~~~~~~~
       |
       +--> 'populate_ruleset': events 7-10
              |
              |   78 | static int populate_ruleset(
              |      |            ^~~~~~~~~~~~~~~~
              |      |            |
              |      |            (7) entry to 'populate_ruleset'
              |......
              |   90 |         if (!env_path_name) {
              |      |            ~
              |      |            |
              |      |            (8) following 'false' branch (when 'env_path_name' is non-NULL)...
              |......
              |   95 |         env_path_name = strdup(env_path_name);
              |      |                         ~~~~~~~~~~~~~~~~~~~~~
              |      |                         |
              |      |                         (9) ...to here
              |   96 |         unsetenv(env_var);
              |   97 |         num_paths = parse_path(env_path_name, &path_list);
              |      |                     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
              |      |                     |
              |      |                     (10) calling 'parse_path' from 'populate_ruleset'
              |
              +--> 'parse_path': events 11-16
                     |
                     |   55 | static int parse_path(char *env_path, const char ***const path_list)
                     |      |            ^~~~~~~~~~
                     |      |            |
                     |      |            (11) entry to 'parse_path'
                     |......
                     |   59 |         if (env_path) {
                     |      |            ~
                     |      |            |
                     |      |            (12) following 'false' branch...
                     |......
                     |   66 |         *path_list = malloc(num_paths * sizeof(**path_list));
                     |      |                      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                     |      |                      |
                     |      |                      (13) ...to here
                     |      |                      (14) allocated here
                     |   67 |         for (i = 0; i < num_paths; i++)
                     |      |                     ~~~~~~~~~~~~~
                     |      |                       |
                     |      |                       (15) following 'false' branch (when 'i >= num_paths')...
                     |......
                     |   70 |         return num_paths;
                     |      |                ~~~~~~~~~
                     |      |                |
                     |      |                (16) ...to here
                     |
              <------+
              |
            'populate_ruleset': events 17-22
              |
              |   97 |         num_paths = parse_path(env_path_name, &path_list);
              |      |                     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
              |      |                     |
              |      |                     (17) returning to 'populate_ruleset' from 'parse_path'
              |   98 |         if (num_paths == 1 && path_list[0][0] == '\0') {
              |      |            ~         
              |      |            |
              |      |            (18) following 'false' branch (when 'num_paths != 1')...
              |......
              |  107 |         for (i = 0; i < num_paths; i++) {
              |      |              ~~~~~  ~~~~~~~~~~~~~
              |      |                |      |
              |      |                |      (20) following 'false' branch (when 'i >= num_paths')...
              |      |                (19) ...to here
              |......
              |  134 |         ret = 0;
              |      |         ~~~~~~~      
              |      |             |
              |      |             (21) ...to here
              |......
              |  139 | }
              |      | ~                    
              |      | |
              |      | (22) 'path_list' leaks here; was allocated at (14)
              |
>> samples/landlock/sandboxer.c:98:40: warning: dereference of possibly-NULL 'path_list' [CWE-690] [-Wanalyzer-possible-null-dereference]
      98 |         if (num_paths == 1 && path_list[0][0] == '\0') {
         |                               ~~~~~~~~~^~~
     'populate_ruleset': events 1-4
       |
       |   78 | static int populate_ruleset(
       |      |            ^~~~~~~~~~~~~~~~
       |      |            |
       |      |            (1) entry to 'populate_ruleset'
       |......
       |   90 |         if (!env_path_name) {
       |      |            ~
       |      |            |
       |      |            (2) following 'false' branch (when 'env_path_name' is non-NULL)...
       |......
       |   95 |         env_path_name = strdup(env_path_name);
       |      |                         ~~~~~~~~~~~~~~~~~~~~~
       |      |                         |
       |      |                         (3) ...to here
       |   96 |         unsetenv(env_var);
       |   97 |         num_paths = parse_path(env_path_name, &path_list);
       |      |                     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
       |      |                     |
       |      |                     (4) calling 'parse_path' from 'populate_ruleset'
       |
       +--> 'parse_path': events 5-8
              |
              |   55 | static int parse_path(char *env_path, const char ***const path_list)
              |      |            ^~~~~~~~~~
              |      |            |
              |      |            (5) entry to 'parse_path'
              |......
              |   59 |         if (env_path) {
              |      |            ~
              |      |            |
              |      |            (6) following 'true' branch...
              |   60 |                 num_paths++;
              |      |                 ~~~~~~~~~~~
              |      |                          |
              |      |                          (7) ...to here
              |......
              |   66 |         *path_list = malloc(num_paths * sizeof(**path_list));
              |      |                      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
              |      |                      |
              |      |                      (8) this call could return NULL
              |
       <------+
       |
     'populate_ruleset': events 9-12
       |
       |   97 |         num_paths = parse_path(env_path_name, &path_list);
       |      |                     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
       |      |                     |
       |      |                     (9) returning to 'populate_ruleset' from 'parse_path'
       |   98 |         if (num_paths == 1 && path_list[0][0] == '\0') {
       |      |            ~                  ~~~~~~~~~~~~
       |      |            |                           |
       |      |            |                           (11) ...to here
       |      |            |                           (12) 'path_list' could be NULL: unchecked value from (8)
       |      |            (10) following 'true' branch (when 'num_paths == 1')...
       |

vim +/path_list +139 samples/landlock/sandboxer.c

ba84b0bf5a164f0 Mickaël Salaün 2021-04-22   72  
ba84b0bf5a164f0 Mickaël Salaün 2021-04-22   73  #define ACCESS_FILE ( \
ba84b0bf5a164f0 Mickaël Salaün 2021-04-22   74  	LANDLOCK_ACCESS_FS_EXECUTE | \
ba84b0bf5a164f0 Mickaël Salaün 2021-04-22   75  	LANDLOCK_ACCESS_FS_WRITE_FILE | \
ba84b0bf5a164f0 Mickaël Salaün 2021-04-22   76  	LANDLOCK_ACCESS_FS_READ_FILE)
ba84b0bf5a164f0 Mickaël Salaün 2021-04-22   77  
ba84b0bf5a164f0 Mickaël Salaün 2021-04-22   78  static int populate_ruleset(
ba84b0bf5a164f0 Mickaël Salaün 2021-04-22   79  		const char *const env_var, const int ruleset_fd,
ba84b0bf5a164f0 Mickaël Salaün 2021-04-22   80  		const __u64 allowed_access)
ba84b0bf5a164f0 Mickaël Salaün 2021-04-22   81  {
ba84b0bf5a164f0 Mickaël Salaün 2021-04-22   82  	int num_paths, i, ret = 1;
ba84b0bf5a164f0 Mickaël Salaün 2021-04-22   83  	char *env_path_name;
ba84b0bf5a164f0 Mickaël Salaün 2021-04-22   84  	const char **path_list = NULL;
ba84b0bf5a164f0 Mickaël Salaün 2021-04-22   85  	struct landlock_path_beneath_attr path_beneath = {
ba84b0bf5a164f0 Mickaël Salaün 2021-04-22   86  		.parent_fd = -1,
ba84b0bf5a164f0 Mickaël Salaün 2021-04-22   87  	};
ba84b0bf5a164f0 Mickaël Salaün 2021-04-22   88  
ba84b0bf5a164f0 Mickaël Salaün 2021-04-22   89  	env_path_name = getenv(env_var);
ba84b0bf5a164f0 Mickaël Salaün 2021-04-22   90  	if (!env_path_name) {
ba84b0bf5a164f0 Mickaël Salaün 2021-04-22   91  		/* Prevents users to forget a setting. */
ba84b0bf5a164f0 Mickaël Salaün 2021-04-22   92  		fprintf(stderr, "Missing environment variable %s\n", env_var);
ba84b0bf5a164f0 Mickaël Salaün 2021-04-22   93  		return 1;
ba84b0bf5a164f0 Mickaël Salaün 2021-04-22   94  	}
ba84b0bf5a164f0 Mickaël Salaün 2021-04-22   95  	env_path_name = strdup(env_path_name);
ba84b0bf5a164f0 Mickaël Salaün 2021-04-22   96  	unsetenv(env_var);
ba84b0bf5a164f0 Mickaël Salaün 2021-04-22   97  	num_paths = parse_path(env_path_name, &path_list);
ba84b0bf5a164f0 Mickaël Salaün 2021-04-22  @98  	if (num_paths == 1 && path_list[0][0] == '\0') {
ba84b0bf5a164f0 Mickaël Salaün 2021-04-22   99  		/*
ba84b0bf5a164f0 Mickaël Salaün 2021-04-22  100  		 * Allows to not use all possible restrictions (e.g. use
ba84b0bf5a164f0 Mickaël Salaün 2021-04-22  101  		 * LL_FS_RO without LL_FS_RW).
ba84b0bf5a164f0 Mickaël Salaün 2021-04-22  102  		 */
ba84b0bf5a164f0 Mickaël Salaün 2021-04-22  103  		ret = 0;
ba84b0bf5a164f0 Mickaël Salaün 2021-04-22  104  		goto out_free_name;
ba84b0bf5a164f0 Mickaël Salaün 2021-04-22  105  	}
ba84b0bf5a164f0 Mickaël Salaün 2021-04-22  106  
ba84b0bf5a164f0 Mickaël Salaün 2021-04-22  107  	for (i = 0; i < num_paths; i++) {
ba84b0bf5a164f0 Mickaël Salaün 2021-04-22  108  		struct stat statbuf;
ba84b0bf5a164f0 Mickaël Salaün 2021-04-22  109  
ba84b0bf5a164f0 Mickaël Salaün 2021-04-22  110  		path_beneath.parent_fd = open(path_list[i], O_PATH |
ba84b0bf5a164f0 Mickaël Salaün 2021-04-22  111  				O_CLOEXEC);
ba84b0bf5a164f0 Mickaël Salaün 2021-04-22  112  		if (path_beneath.parent_fd < 0) {
ba84b0bf5a164f0 Mickaël Salaün 2021-04-22  113  			fprintf(stderr, "Failed to open \"%s\": %s\n",
ba84b0bf5a164f0 Mickaël Salaün 2021-04-22  114  					path_list[i],
ba84b0bf5a164f0 Mickaël Salaün 2021-04-22  115  					strerror(errno));
ba84b0bf5a164f0 Mickaël Salaün 2021-04-22  116  			goto out_free_name;
ba84b0bf5a164f0 Mickaël Salaün 2021-04-22  117  		}
ba84b0bf5a164f0 Mickaël Salaün 2021-04-22  118  		if (fstat(path_beneath.parent_fd, &statbuf)) {
ba84b0bf5a164f0 Mickaël Salaün 2021-04-22  119  			close(path_beneath.parent_fd);
ba84b0bf5a164f0 Mickaël Salaün 2021-04-22  120  			goto out_free_name;
ba84b0bf5a164f0 Mickaël Salaün 2021-04-22  121  		}
ba84b0bf5a164f0 Mickaël Salaün 2021-04-22  122  		path_beneath.allowed_access = allowed_access;
ba84b0bf5a164f0 Mickaël Salaün 2021-04-22  123  		if (!S_ISDIR(statbuf.st_mode))
ba84b0bf5a164f0 Mickaël Salaün 2021-04-22  124  			path_beneath.allowed_access &= ACCESS_FILE;
ba84b0bf5a164f0 Mickaël Salaün 2021-04-22  125  		if (landlock_add_rule(ruleset_fd, LANDLOCK_RULE_PATH_BENEATH,
ba84b0bf5a164f0 Mickaël Salaün 2021-04-22  126  					&path_beneath, 0)) {
ba84b0bf5a164f0 Mickaël Salaün 2021-04-22  127  			fprintf(stderr, "Failed to update the ruleset with \"%s\": %s\n",
ba84b0bf5a164f0 Mickaël Salaün 2021-04-22  128  					path_list[i], strerror(errno));
ba84b0bf5a164f0 Mickaël Salaün 2021-04-22  129  			close(path_beneath.parent_fd);
ba84b0bf5a164f0 Mickaël Salaün 2021-04-22  130  			goto out_free_name;
ba84b0bf5a164f0 Mickaël Salaün 2021-04-22  131  		}
ba84b0bf5a164f0 Mickaël Salaün 2021-04-22  132  		close(path_beneath.parent_fd);
ba84b0bf5a164f0 Mickaël Salaün 2021-04-22  133  	}
ba84b0bf5a164f0 Mickaël Salaün 2021-04-22  134  	ret = 0;
ba84b0bf5a164f0 Mickaël Salaün 2021-04-22  135  
ba84b0bf5a164f0 Mickaël Salaün 2021-04-22  136  out_free_name:
ba84b0bf5a164f0 Mickaël Salaün 2021-04-22  137  	free(env_path_name);
ba84b0bf5a164f0 Mickaël Salaün 2021-04-22  138  	return ret;
ba84b0bf5a164f0 Mickaël Salaün 2021-04-22 @139  }
ba84b0bf5a164f0 Mickaël Salaün 2021-04-22  140  

-- 
0-DAY CI Kernel Test Service
https://01.org/lkp

             reply	other threads:[~2022-04-05 16:19 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-04-05 16:19 kernel test robot [this message]
  -- strict thread matches above, loose matches on Subject: below --
2022-04-04 12:22 samples/landlock/sandboxer.c:139:1: warning: leak of 'path_list' [CWE-401] kernel test robot

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=202204060055.MeJXeOn7-lkp@intel.com \
    --to=lkp@intel.com \
    --cc=kbuild@lists.01.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.