lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [day] [month] [year] [list]
Message-ID: <202205270016.p6f8TmQi-lkp@intel.com>
Date:   Fri, 27 May 2022 00:17:00 +0800
From:   kernel test robot <lkp@...el.com>
To:     Jens Axboe <axboe@...nel.dk>
Cc:     kbuild-all@...ts.01.org, linux-kernel@...r.kernel.org
Subject: [axboe-block:for-5.20/io_uring 54/55] io_uring/poll.c:168:38:
 sparse: sparse: incorrect type in assignment (different base types)

tree:   https://git.kernel.org/pub/scm/linux/kernel/git/axboe/linux-block.git for-5.20/io_uring
head:   030e5a1b325edbe3b173db29156613f9eddd44e6
commit: 55bc1c3e59e8972f62d95a771a8e2f35e5c8989d [54/55] io_uring: move poll handling into its own file
config: openrisc-randconfig-s032-20220524 (https://download.01.org/0day-ci/archive/20220527/202205270016.p6f8TmQi-lkp@intel.com/config)
compiler: or1k-linux-gcc (GCC) 11.3.0
reproduce:
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # apt-get install sparse
        # sparse version: v0.6.4-14-g5a0004b5-dirty
        # https://git.kernel.org/pub/scm/linux/kernel/git/axboe/linux-block.git/commit/?id=55bc1c3e59e8972f62d95a771a8e2f35e5c8989d
        git remote add axboe-block https://git.kernel.org/pub/scm/linux/kernel/git/axboe/linux-block.git
        git fetch --no-tags axboe-block for-5.20/io_uring
        git checkout 55bc1c3e59e8972f62d95a771a8e2f35e5c8989d
        # save the config file
        mkdir build_dir && cp config build_dir/.config
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-11.3.0 make.cross C=1 CF='-fdiagnostic-prefix -D__CHECK_ENDIAN__' O=build_dir ARCH=openrisc SHELL=/bin/bash

If you fix the issue, kindly add following tag where applicable
Reported-by: kernel test robot <lkp@...el.com>


sparse warnings: (new ones prefixed by >>)
>> io_uring/poll.c:168:38: sparse: sparse: incorrect type in assignment (different base types) @@     expected signed int [usertype] res @@     got restricted __poll_t @@
   io_uring/poll.c:168:38: sparse:     expected signed int [usertype] res
   io_uring/poll.c:168:38: sparse:     got restricted __poll_t
>> io_uring/poll.c:179:56: sparse: sparse: restricted __poll_t degrades to integer
>> io_uring/poll.c:178:66: sparse: sparse: incorrect type in argument 1 (different base types) @@     expected restricted __poll_t [usertype] val @@     got unsigned int @@
   io_uring/poll.c:178:66: sparse:     expected restricted __poll_t [usertype] val
   io_uring/poll.c:178:66: sparse:     got unsigned int
>> io_uring/poll.c:178:52: sparse: sparse: incorrect type in initializer (different base types) @@     expected restricted __poll_t [usertype] mask @@     got unsigned short @@
   io_uring/poll.c:178:52: sparse:     expected restricted __poll_t [usertype] mask
   io_uring/poll.c:178:52: sparse:     got unsigned short
>> io_uring/poll.c:184:50: sparse: sparse: incorrect type in argument 3 (different base types) @@     expected signed int [usertype] res @@     got restricted __poll_t [usertype] mask @@
   io_uring/poll.c:184:50: sparse:     expected signed int [usertype] res
   io_uring/poll.c:184:50: sparse:     got restricted __poll_t [usertype] mask
   io_uring/poll.c:219:63: sparse: sparse: restricted __poll_t degrades to integer
   io_uring/poll.c:219:57: sparse: sparse: incorrect type in argument 1 (different base types) @@     expected restricted __poll_t [usertype] val @@     got unsigned int @@
   io_uring/poll.c:219:57: sparse:     expected restricted __poll_t [usertype] val
   io_uring/poll.c:219:57: sparse:     got unsigned int
>> io_uring/poll.c:337:40: sparse: sparse: incorrect type in argument 2 (different base types) @@     expected int mask @@     got restricted __poll_t [usertype] mask @@
   io_uring/poll.c:337:40: sparse:     expected int mask
   io_uring/poll.c:337:40: sparse:     got restricted __poll_t [usertype] mask
>> io_uring/poll.c:430:24: sparse: sparse: incorrect type in return expression (different base types) @@     expected int @@     got restricted __poll_t [assigned] [usertype] mask @@
   io_uring/poll.c:430:24: sparse:     expected int
   io_uring/poll.c:430:24: sparse:     got restricted __poll_t [assigned] [usertype] mask
>> io_uring/poll.c:447:40: sparse: sparse: incorrect type in argument 2 (different base types) @@     expected int mask @@     got restricted __poll_t [assigned] [usertype] mask @@
   io_uring/poll.c:447:40: sparse:     expected int mask
   io_uring/poll.c:447:40: sparse:     got restricted __poll_t [assigned] [usertype] mask
>> io_uring/poll.c:476:33: sparse: sparse: incorrect type in initializer (different base types) @@     expected restricted __poll_t [usertype] mask @@     got int @@
   io_uring/poll.c:476:33: sparse:     expected restricted __poll_t [usertype] mask
   io_uring/poll.c:476:33: sparse:     got int
   io_uring/poll.c:523:33: sparse: sparse: incorrect type in argument 5 (different base types) @@     expected int mask @@     got restricted __poll_t [assigned] [usertype] mask @@
   io_uring/poll.c:523:33: sparse:     expected int mask
   io_uring/poll.c:523:33: sparse:     got restricted __poll_t [assigned] [usertype] mask
>> io_uring/poll.c:523:50: sparse: sparse: incorrect type in argument 6 (different base types) @@     expected int events @@     got restricted __poll_t [usertype] events @@
   io_uring/poll.c:523:50: sparse:     expected int events
   io_uring/poll.c:523:50: sparse:     got restricted __poll_t [usertype] events
>> io_uring/poll.c:637:24: sparse: sparse: invalid assignment: |=
>> io_uring/poll.c:637:24: sparse:    left side has type unsigned int
>> io_uring/poll.c:637:24: sparse:    right side has type restricted __poll_t
   io_uring/poll.c:638:65: sparse: sparse: restricted __poll_t degrades to integer
   io_uring/poll.c:638:29: sparse: sparse: restricted __poll_t degrades to integer
>> io_uring/poll.c:638:38: sparse: sparse: incorrect type in return expression (different base types) @@     expected restricted __poll_t @@     got unsigned int @@
   io_uring/poll.c:638:38: sparse:     expected restricted __poll_t
   io_uring/poll.c:638:38: sparse:     got unsigned int
   io_uring/poll.c:733:38: sparse: sparse: invalid assignment: &=
>> io_uring/poll.c:733:38: sparse:    left side has type restricted __poll_t
>> io_uring/poll.c:733:38: sparse:    right side has type int
   io_uring/poll.c:734:52: sparse: sparse: restricted __poll_t degrades to integer
   io_uring/poll.c:734:38: sparse: sparse: invalid assignment: |=
   io_uring/poll.c:734:38: sparse:    left side has type restricted __poll_t
>> io_uring/poll.c:734:38: sparse:    right side has type unsigned int
   io_uring/poll.c: note: in included file:
   io_uring/io_uring_types.h:90:37: sparse: sparse: array of flexible structures

vim +168 io_uring/poll.c

   135	
   136	/*
   137	 * All poll tw should go through this. Checks for poll events, manages
   138	 * references, does rewait, etc.
   139	 *
   140	 * Returns a negative error on failure. >0 when no action require, which is
   141	 * either spurious wakeup or multishot CQE is served. 0 when it's done with
   142	 * the request, then the mask is stored in req->cqe.res.
   143	 */
   144	static int io_poll_check_events(struct io_kiocb *req, bool *locked)
   145	{
   146		struct io_ring_ctx *ctx = req->ctx;
   147		int v, ret;
   148	
   149		/* req->task == current here, checking PF_EXITING is safe */
   150		if (unlikely(req->task->flags & PF_EXITING))
   151			return -ECANCELED;
   152	
   153		do {
   154			v = atomic_read(&req->poll_refs);
   155	
   156			/* tw handler should be the owner, and so have some references */
   157			if (WARN_ON_ONCE(!(v & IO_POLL_REF_MASK)))
   158				return 0;
   159			if (v & IO_POLL_CANCEL_FLAG)
   160				return -ECANCELED;
   161	
   162			if (!req->cqe.res) {
   163				struct poll_table_struct pt = { ._key = req->apoll_events };
   164				unsigned flags = locked ? 0 : IO_URING_F_UNLOCKED;
   165	
   166				if (unlikely(!io_assign_file(req, flags)))
   167					return -EBADF;
 > 168				req->cqe.res = vfs_poll(req->file, &pt) & req->apoll_events;
   169			}
   170	
   171			if ((unlikely(!req->cqe.res)))
   172				continue;
   173			if (req->apoll_events & EPOLLONESHOT)
   174				return 0;
   175	
   176			/* multishot, just fill a CQE and proceed */
   177			if (!(req->flags & REQ_F_APOLL_MULTISHOT)) {
 > 178				__poll_t mask = mangle_poll(req->cqe.res &
 > 179							    req->apoll_events);
   180				bool filled;
   181	
   182				spin_lock(&ctx->completion_lock);
   183				filled = io_fill_cqe_aux(ctx, req->cqe.user_data,
 > 184							 mask, IORING_CQE_F_MORE);
   185				io_commit_cqring(ctx);
   186				spin_unlock(&ctx->completion_lock);
   187				if (filled) {
   188					io_cqring_ev_posted(ctx);
   189					continue;
   190				}
   191				return -ECANCELED;
   192			}
   193	
   194			ret = io_poll_issue(req, locked);
   195			if (ret)
   196				return ret;
   197	
   198			/*
   199			 * Release all references, retry if someone tried to restart
   200			 * task_work while we were executing it.
   201			 */
   202		} while (atomic_sub_return(v & IO_POLL_REF_MASK, &req->poll_refs));
   203	
   204		return 1;
   205	}
   206	
   207	static void io_poll_task_func(struct io_kiocb *req, bool *locked)
   208	{
   209		struct io_ring_ctx *ctx = req->ctx;
   210		int ret;
   211	
   212		ret = io_poll_check_events(req, locked);
   213		if (ret > 0)
   214			return;
   215	
   216		if (!ret) {
   217			struct io_poll *poll = io_kiocb_to_cmd(req);
   218	
   219			req->cqe.res = mangle_poll(req->cqe.res & poll->events);
   220		} else {
   221			req->cqe.res = ret;
   222			req_set_fail(req);
   223		}
   224	
   225		io_poll_remove_entries(req);
   226		spin_lock(&ctx->completion_lock);
   227		hash_del(&req->hash_node);
   228		req->cqe.flags = 0;
   229		__io_req_complete_post(req);
   230		io_commit_cqring(ctx);
   231		spin_unlock(&ctx->completion_lock);
   232		io_cqring_ev_posted(ctx);
   233	}
   234	
   235	static void io_apoll_task_func(struct io_kiocb *req, bool *locked)
   236	{
   237		struct io_ring_ctx *ctx = req->ctx;
   238		int ret;
   239	
   240		ret = io_poll_check_events(req, locked);
   241		if (ret > 0)
   242			return;
   243	
   244		io_poll_remove_entries(req);
   245		spin_lock(&ctx->completion_lock);
   246		hash_del(&req->hash_node);
   247		spin_unlock(&ctx->completion_lock);
   248	
   249		if (!ret)
   250			io_req_task_submit(req, locked);
   251		else
   252			io_req_complete_failed(req, ret);
   253	}
   254	
   255	static void __io_poll_execute(struct io_kiocb *req, int mask, __poll_t events)
   256	{
   257		io_req_set_res(req, mask, 0);
   258		/*
   259		 * This is useful for poll that is armed on behalf of another
   260		 * request, and where the wakeup path could be on a different
   261		 * CPU. We want to avoid pulling in req->apoll->events for that
   262		 * case.
   263		 */
   264		req->apoll_events = events;
   265		if (req->opcode == IORING_OP_POLL_ADD)
   266			req->io_task_work.func = io_poll_task_func;
   267		else
   268			req->io_task_work.func = io_apoll_task_func;
   269	
   270		trace_io_uring_task_add(req->ctx, req, req->cqe.user_data, req->opcode, mask);
   271		io_req_task_work_add(req);
   272	}
   273	
   274	static inline void io_poll_execute(struct io_kiocb *req, int res,
   275			__poll_t events)
   276	{
   277		if (io_poll_get_ownership(req))
   278			__io_poll_execute(req, res, events);
   279	}
   280	
   281	static void io_poll_cancel_req(struct io_kiocb *req)
   282	{
   283		io_poll_mark_cancelled(req);
   284		/* kick tw, which should complete the request */
   285		io_poll_execute(req, 0, 0);
   286	}
   287	
   288	#define wqe_to_req(wait)	((void *)((unsigned long) (wait)->private & ~1))
   289	#define wqe_is_double(wait)	((unsigned long) (wait)->private & 1)
   290	#define IO_ASYNC_POLL_COMMON	(EPOLLONESHOT | EPOLLPRI)
   291	
   292	static int io_poll_wake(struct wait_queue_entry *wait, unsigned mode, int sync,
   293				void *key)
   294	{
   295		struct io_kiocb *req = wqe_to_req(wait);
   296		struct io_poll *poll = container_of(wait, struct io_poll, wait);
   297		__poll_t mask = key_to_poll(key);
   298	
   299		if (unlikely(mask & POLLFREE)) {
   300			io_poll_mark_cancelled(req);
   301			/* we have to kick tw in case it's not already */
   302			io_poll_execute(req, 0, poll->events);
   303	
   304			/*
   305			 * If the waitqueue is being freed early but someone is already
   306			 * holds ownership over it, we have to tear down the request as
   307			 * best we can. That means immediately removing the request from
   308			 * its waitqueue and preventing all further accesses to the
   309			 * waitqueue via the request.
   310			 */
   311			list_del_init(&poll->wait.entry);
   312	
   313			/*
   314			 * Careful: this *must* be the last step, since as soon
   315			 * as req->head is NULL'ed out, the request can be
   316			 * completed and freed, since aio_poll_complete_work()
   317			 * will no longer need to take the waitqueue lock.
   318			 */
   319			smp_store_release(&poll->head, NULL);
   320			return 1;
   321		}
   322	
   323		/* for instances that support it check for an event match first */
   324		if (mask && !(mask & (poll->events & ~IO_ASYNC_POLL_COMMON)))
   325			return 0;
   326	
   327		if (io_poll_get_ownership(req)) {
   328			/* optional, saves extra locking for removal in tw handler */
   329			if (mask && poll->events & EPOLLONESHOT) {
   330				list_del_init(&poll->wait.entry);
   331				poll->head = NULL;
   332				if (wqe_is_double(wait))
   333					req->flags &= ~REQ_F_DOUBLE_POLL;
   334				else
   335					req->flags &= ~REQ_F_SINGLE_POLL;
   336			}
 > 337			__io_poll_execute(req, mask, poll->events);
   338		}
   339		return 1;
   340	}
   341	

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

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ