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
.config.gz
Description: application/gzip