Hi Elena,

[auto build test ERROR on next-20170526]
[cannot apply to linus/master linux/master kees/for-next/pstore v4.9-rc8 
v4.9-rc7 v4.9-rc6 v4.12-rc2]
[if your patch is applied to the wrong git tree, please drop us a note to help 
improve the system]

url:    
https://github.com/0day-ci/linux/commits/Kees-Cook/ipc-Convert-kern_ipc_perm-refcount-to-refcount_t/20170528-040601
config: m32r-m32104ut_defconfig (attached as .config)
compiler: m32r-linux-gcc (GCC) 6.2.0
reproduce:
        wget 
https://raw.githubusercontent.com/01org/lkp-tests/master/sbin/make.cross -O 
~/bin/make.cross
        chmod +x ~/bin/make.cross
        # save the attached .config to linux build tree
        make.cross ARCH=m32r 

All errors (new ones prefixed by >>):

   In file included from include/uapi/linux/shm.h:4:0,
                    from include/linux/shm.h:6,
                    from ipc/util.c:44:
   include/linux/ipc.h:25:2: error: unknown type name 'refcount_t'
     refcount_t refcount;
     ^~~~~~~~~~
   ipc/util.c: In function 'ipc_addid':
>> ipc/util.c:235:15: error: passing argument 1 of 'refcount_set' from 
>> incompatible pointer type [-Werror=incompatible-pointer-types]
     refcount_set(&new->refcount, 1);
                  ^
   In file included from include/linux/key.h:26:0,
                    from include/linux/security.h:26,
                    from ipc/util.c:52:
   include/linux/refcount.h:28:20: note: expected 'refcount_t * {aka struct 
refcount_struct *}' but argument is of type 'int *'
    static inline void refcount_set(refcount_t *r, unsigned int n)
                       ^~~~~~~~~~~~
   ipc/util.c: In function 'ipc_rcu_getref':
>> ipc/util.c:400:31: error: passing argument 1 of 'refcount_inc_not_zero' from 
>> incompatible pointer type [-Werror=incompatible-pointer-types]
     return refcount_inc_not_zero(&ptr->refcount);
                                  ^
   In file included from include/linux/key.h:26:0,
                    from include/linux/security.h:26,
                    from ipc/util.c:52:
   include/linux/refcount.h:47:26: note: expected 'refcount_t * {aka struct 
refcount_struct *}' but argument is of type 'int *'
    extern __must_check bool refcount_inc_not_zero(refcount_t *r);
                             ^~~~~~~~~~~~~~~~~~~~~
   ipc/util.c: In function 'ipc_rcu_putref':
>> ipc/util.c:406:29: error: passing argument 1 of 'refcount_dec_and_test' from 
>> incompatible pointer type [-Werror=incompatible-pointer-types]
     if (!refcount_dec_and_test(&ptr->refcount))
                                ^
   In file included from include/linux/key.h:26:0,
                    from include/linux/security.h:26,
                    from ipc/util.c:52:
   include/linux/refcount.h:53:26: note: expected 'refcount_t * {aka struct 
refcount_struct *}' but argument is of type 'int *'
    extern __must_check bool refcount_dec_and_test(refcount_t *r);
                             ^~~~~~~~~~~~~~~~~~~~~
   cc1: some warnings being treated as errors

vim +/refcount_set +235 ipc/util.c

    38   *
    39   *  Note that sems have a special fast path that avoids 
kern_ipc_perm.lock -
    40   *  see sem_lock().
    41   */
    42  
    43  #include <linux/mm.h>
  > 44  #include <linux/shm.h>
    45  #include <linux/init.h>
    46  #include <linux/msg.h>
    47  #include <linux/vmalloc.h>
    48  #include <linux/slab.h>
    49  #include <linux/notifier.h>
    50  #include <linux/capability.h>
    51  #include <linux/highuid.h>
  > 52  #include <linux/security.h>
    53  #include <linux/rcupdate.h>
    54  #include <linux/workqueue.h>
    55  #include <linux/seq_file.h>
    56  #include <linux/proc_fs.h>
    57  #include <linux/audit.h>
    58  #include <linux/nsproxy.h>
    59  #include <linux/rwsem.h>
    60  #include <linux/memory.h>
    61  #include <linux/ipc_namespace.h>
    62  
    63  #include <asm/unistd.h>
    64  
    65  #include "util.h"
    66  
    67  struct ipc_proc_iface {
    68          const char *path;
    69          const char *header;
    70          int ids;
    71          int (*show)(struct seq_file *, void *);
    72  };
    73  
    74  /**
    75   * ipc_init - initialise ipc subsystem
    76   *
    77   * The various sysv ipc resources (semaphores, messages and shared
    78   * memory) are initialised.
    79   *
    80   * A callback routine is registered into the memory hotplug notifier
    81   * chain: since msgmni scales to lowmem this callback routine will be
    82   * called upon successful memory add / remove to recompute msmgni.
    83   */
    84  static int __init ipc_init(void)
    85  {
    86          sem_init();
    87          msg_init();
    88          shm_init();
    89          return 0;
    90  }
    91  device_initcall(ipc_init);
    92  
    93  /**
    94   * ipc_init_ids - initialise ipc identifiers
    95   * @ids: ipc identifier set
    96   *
    97   * Set up the sequence range to use for the ipc identifier range 
(limited
    98   * below IPCMNI) then initialise the ids idr.
    99   */
   100  void ipc_init_ids(struct ipc_ids *ids)
   101  {
   102          ids->in_use = 0;
   103          ids->seq = 0;
   104          ids->next_id = -1;
   105          init_rwsem(&ids->rwsem);
   106          idr_init(&ids->ipcs_idr);
   107  }
   108  
   109  #ifdef CONFIG_PROC_FS
   110  static const struct file_operations sysvipc_proc_fops;
   111  /**
   112   * ipc_init_proc_interface -  create a proc interface for sysipc types 
using a seq_file interface.
   113   * @path: Path in procfs
   114   * @header: Banner to be printed at the beginning of the file.
   115   * @ids: ipc id table to iterate.
   116   * @show: show routine.
   117   */
   118  void __init ipc_init_proc_interface(const char *path, const char 
*header,
   119                  int ids, int (*show)(struct seq_file *, void *))
   120  {
   121          struct proc_dir_entry *pde;
   122          struct ipc_proc_iface *iface;
   123  
   124          iface = kmalloc(sizeof(*iface), GFP_KERNEL);
   125          if (!iface)
   126                  return;
   127          iface->path     = path;
   128          iface->header   = header;
   129          iface->ids      = ids;
   130          iface->show     = show;
   131  
   132          pde = proc_create_data(path,
   133                                 S_IRUGO,        /* world readable */
   134                                 NULL,           /* parent dir */
   135                                 &sysvipc_proc_fops,
   136                                 iface);
   137          if (!pde)
   138                  kfree(iface);
   139  }
   140  #endif
   141  
   142  /**
   143   * ipc_findkey  - find a key in an ipc identifier set
   144   * @ids: ipc identifier set
   145   * @key: key to find
   146   *
   147   * Returns the locked pointer to the ipc structure if found or NULL
   148   * otherwise. If key is found ipc points to the owning ipc structure
   149   *
   150   * Called with ipc_ids.rwsem held.
   151   */
   152  static struct kern_ipc_perm *ipc_findkey(struct ipc_ids *ids, key_t key)
   153  {
   154          struct kern_ipc_perm *ipc;
   155          int next_id;
   156          int total;
   157  
   158          for (total = 0, next_id = 0; total < ids->in_use; next_id++) {
   159                  ipc = idr_find(&ids->ipcs_idr, next_id);
   160  
   161                  if (ipc == NULL)
   162                          continue;
   163  
   164                  if (ipc->key != key) {
   165                          total++;
   166                          continue;
   167                  }
   168  
   169                  rcu_read_lock();
   170                  ipc_lock_object(ipc);
   171                  return ipc;
   172          }
   173  
   174          return NULL;
   175  }
   176  
   177  /**
   178   * ipc_get_maxid - get the last assigned id
   179   * @ids: ipc identifier set
   180   *
   181   * Called with ipc_ids.rwsem held.
   182   */
   183  int ipc_get_maxid(struct ipc_ids *ids)
   184  {
   185          struct kern_ipc_perm *ipc;
   186          int max_id = -1;
   187          int total, id;
   188  
   189          if (ids->in_use == 0)
   190                  return -1;
   191  
   192          if (ids->in_use == IPCMNI)
   193                  return IPCMNI - 1;
   194  
   195          /* Look for the last assigned id */
   196          total = 0;
   197          for (id = 0; id < IPCMNI && total < ids->in_use; id++) {
   198                  ipc = idr_find(&ids->ipcs_idr, id);
   199                  if (ipc != NULL) {
   200                          max_id = id;
   201                          total++;
   202                  }
   203          }
   204          return max_id;
   205  }
   206  
   207  /**
   208   * ipc_addid - add an ipc identifier
   209   * @ids: ipc identifier set
   210   * @new: new ipc permission set
   211   * @size: limit for the number of used ids
   212   *
   213   * Add an entry 'new' to the ipc ids idr. The permissions object is
   214   * initialised and the first free entry is set up and the id assigned
   215   * is returned. The 'new' entry is returned in a locked state on 
success.
   216   * On failure the entry is not locked and a negative err-code is 
returned.
   217   *
   218   * Called with writer ipc_ids.rwsem held.
   219   */
   220  int ipc_addid(struct ipc_ids *ids, struct kern_ipc_perm *new, int size)
   221  {
   222          kuid_t euid;
   223          kgid_t egid;
   224          int id;
   225          int next_id = ids->next_id;
   226  
   227          if (size > IPCMNI)
   228                  size = IPCMNI;
   229  
   230          if (ids->in_use >= size)
   231                  return -ENOSPC;
   232  
   233          idr_preload(GFP_KERNEL);
   234  
 > 235          refcount_set(&new->refcount, 1);
   236          spin_lock_init(&new->lock);
   237          new->deleted = false;
   238          rcu_read_lock();
   239          spin_lock(&new->lock);
   240  
   241          current_euid_egid(&euid, &egid);
   242          new->cuid = new->uid = euid;
   243          new->gid = new->cgid = egid;
   244  
   245          id = idr_alloc(&ids->ipcs_idr, new,
   246                         (next_id < 0) ? 0 : ipcid_to_idx(next_id), 0,
   247                         GFP_NOWAIT);
   248          idr_preload_end();
   249          if (id < 0) {
   250                  spin_unlock(&new->lock);
   251                  rcu_read_unlock();
   252                  return id;
   253          }
   254  
   255          ids->in_use++;
   256  
   257          if (next_id < 0) {
   258                  new->seq = ids->seq++;
   259                  if (ids->seq > IPCID_SEQ_MAX)
   260                          ids->seq = 0;
   261          } else {
   262                  new->seq = ipcid_to_seqx(next_id);
   263                  ids->next_id = -1;
   264          }
   265  
   266          new->id = ipc_buildid(id, new->seq);
   267          return id;
   268  }
   269  
   270  /**
   271   * ipcget_new - create a new ipc object
   272   * @ns: ipc namespace
   273   * @ids: ipc identifier set
   274   * @ops: the actual creation routine to call
   275   * @params: its parameters
   276   *
   277   * This routine is called by sys_msgget, sys_semget() and sys_shmget()
   278   * when the key is IPC_PRIVATE.
   279   */
   280  static int ipcget_new(struct ipc_namespace *ns, struct ipc_ids *ids,
   281                  const struct ipc_ops *ops, struct ipc_params *params)
   282  {
   283          int err;
   284  
   285          down_write(&ids->rwsem);
   286          err = ops->getnew(ns, params);
   287          up_write(&ids->rwsem);
   288          return err;
   289  }
   290  
   291  /**
   292   * ipc_check_perms - check security and permissions for an ipc object
   293   * @ns: ipc namespace
   294   * @ipcp: ipc permission set
   295   * @ops: the actual security routine to call
   296   * @params: its parameters
   297   *
   298   * This routine is called by sys_msgget(), sys_semget() and sys_shmget()
   299   * when the key is not IPC_PRIVATE and that key already exists in the
   300   * ds IDR.
   301   *
   302   * On success, the ipc id is returned.
   303   *
   304   * It is called with ipc_ids.rwsem and ipcp->lock held.
   305   */
   306  static int ipc_check_perms(struct ipc_namespace *ns,
   307                             struct kern_ipc_perm *ipcp,
   308                             const struct ipc_ops *ops,
   309                             struct ipc_params *params)
   310  {
   311          int err;
   312  
   313          if (ipcperms(ns, ipcp, params->flg))
   314                  err = -EACCES;
   315          else {
   316                  err = ops->associate(ipcp, params->flg);
   317                  if (!err)
   318                          err = ipcp->id;
   319          }
   320  
   321          return err;
   322  }
   323  
   324  /**
   325   * ipcget_public - get an ipc object or create a new one
   326   * @ns: ipc namespace
   327   * @ids: ipc identifier set
   328   * @ops: the actual creation routine to call
   329   * @params: its parameters
   330   *
   331   * This routine is called by sys_msgget, sys_semget() and sys_shmget()
   332   * when the key is not IPC_PRIVATE.
   333   * It adds a new entry if the key is not found and does some permission
   334   * / security checkings if the key is found.
   335   *
   336   * On success, the ipc id is returned.
   337   */
   338  static int ipcget_public(struct ipc_namespace *ns, struct ipc_ids *ids,
   339                  const struct ipc_ops *ops, struct ipc_params *params)
   340  {
   341          struct kern_ipc_perm *ipcp;
   342          int flg = params->flg;
   343          int err;
   344  
   345          /*
   346           * Take the lock as a writer since we are potentially going to 
add
   347           * a new entry + read locks are not "upgradable"
   348           */
   349          down_write(&ids->rwsem);
   350          ipcp = ipc_findkey(ids, params->key);
   351          if (ipcp == NULL) {
   352                  /* key not used */
   353                  if (!(flg & IPC_CREAT))
   354                          err = -ENOENT;
   355                  else
   356                          err = ops->getnew(ns, params);
   357          } else {
   358                  /* ipc object has been locked by ipc_findkey() */
   359  
   360                  if (flg & IPC_CREAT && flg & IPC_EXCL)
   361                          err = -EEXIST;
   362                  else {
   363                          err = 0;
   364                          if (ops->more_checks)
   365                                  err = ops->more_checks(ipcp, params);
   366                          if (!err)
   367                                  /*
   368                                   * ipc_check_perms returns the IPC id on
   369                                   * success
   370                                   */
   371                                  err = ipc_check_perms(ns, ipcp, ops, 
params);
   372                  }
   373                  ipc_unlock(ipcp);
   374          }
   375          up_write(&ids->rwsem);
   376  
   377          return err;
   378  }
   379  
   380  
   381  /**
   382   * ipc_rmid - remove an ipc identifier
   383   * @ids: ipc identifier set
   384   * @ipcp: ipc perm structure containing the identifier to remove
   385   *
   386   * ipc_ids.rwsem (as a writer) and the spinlock for this ID are held
   387   * before this function is called, and remain locked on the exit.
   388   */
   389  void ipc_rmid(struct ipc_ids *ids, struct kern_ipc_perm *ipcp)
   390  {
   391          int lid = ipcid_to_idx(ipcp->id);
   392  
   393          idr_remove(&ids->ipcs_idr, lid);
   394          ids->in_use--;
   395          ipcp->deleted = true;
   396  }
   397  
   398  int ipc_rcu_getref(struct kern_ipc_perm *ptr)
   399  {
 > 400          return refcount_inc_not_zero(&ptr->refcount);
   401  }
   402  
   403  void ipc_rcu_putref(struct kern_ipc_perm *ptr,
   404                          void (*func)(struct rcu_head *head))
   405  {
 > 406          if (!refcount_dec_and_test(&ptr->refcount))
   407                  return;
   408  
   409          call_rcu(&ptr->rcu, func);

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation

Attachment: .config.gz
Description: application/gzip

Reply via email to