From: kbuild test robot <lkp@intel.com>
To: Kees Cook <keescook@chromium.org>
Cc: kbuild-all@01.org, linux-kernel@vger.kernel.org,
Andrew Morton <akpm@linux-foundation.org>,
David Windsor <dwindsor@gmail.com>,
Kees Cook <keescook@chromium.org>,
Hans Liljestrand <ishkamiel@gmail.com>,
Elena Reshetova <elena.reshetova@intel.com>,
Davidlohr Bueso <dave@stgolabs.net>,
Manfred Spraul <manfred@colorfullife.com>,
Mauro Carvalho Chehab <mchehab@kernel.org>,
Bjorn Helgaas <bhelgaas@google.com>,
Michal Hocko <mhocko@suse.com>
Subject: Re: [PATCH] ipc: Convert kern_ipc_perm.refcount to refcount_t
Date: Sun, 28 May 2017 05:57:01 +0800 [thread overview]
Message-ID: <201705280516.bAHdBQAm%fengguang.wu@intel.com> (raw)
In-Reply-To: <20170527195947.GA28160@beast>
[-- Attachment #1: Type: text/plain, Size: 14292 bytes --]
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 #2: .config.gz --]
[-- Type: application/gzip, Size: 11266 bytes --]
prev parent reply other threads:[~2017-05-27 21:57 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-05-27 19:59 [PATCH] ipc: Convert kern_ipc_perm.refcount to refcount_t Kees Cook
2017-05-27 20:19 ` kbuild test robot
2017-05-27 21:57 ` kbuild test robot [this message]
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=201705280516.bAHdBQAm%fengguang.wu@intel.com \
--to=lkp@intel.com \
--cc=akpm@linux-foundation.org \
--cc=bhelgaas@google.com \
--cc=dave@stgolabs.net \
--cc=dwindsor@gmail.com \
--cc=elena.reshetova@intel.com \
--cc=ishkamiel@gmail.com \
--cc=kbuild-all@01.org \
--cc=keescook@chromium.org \
--cc=linux-kernel@vger.kernel.org \
--cc=manfred@colorfullife.com \
--cc=mchehab@kernel.org \
--cc=mhocko@suse.com \
/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.