CC: [email protected]
BCC: [email protected]
CC: [email protected]
TO: "Mickaël Salaün" <[email protected]>
CC: James Morris <[email protected]>
CC: Jann Horn <[email protected]>
CC: Kees Cook <[email protected]>

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/[email protected]/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 <[email protected]>


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 at (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
_______________________________________________
kbuild mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to