linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: kernel test robot <lkp@intel.com>
To: Niklas Cassel <niklas.cassel@wdc.com>
Cc: kbuild-all@lists.01.org, linux-kernel@vger.kernel.org,
	Kees Cook <keescook@chromium.org>,
	Damien Le Moal <damien.lemoal@opensource.wdc.com>
Subject: [kees:for-next/execve 1/1] fs/binfmt_flat.c:816:39: sparse: sparse: incorrect type in argument 1 (different address spaces)
Date: Mon, 18 Apr 2022 23:30:28 +0800	[thread overview]
Message-ID: <202204182333.OIUOotK8-lkp@intel.com> (raw)

tree:   https://git.kernel.org/pub/scm/linux/kernel/git/kees/linux.git for-next/execve
head:   a767e6fd68d2ca84578649acc072f21b81edfb3a
commit: a767e6fd68d2ca84578649acc072f21b81edfb3a [1/1] binfmt_flat: do not stop relocating GOT entries prematurely on riscv
config: m68k-randconfig-s032-20220417 (https://download.01.org/0day-ci/archive/20220418/202204182333.OIUOotK8-lkp@intel.com/config)
compiler: m68k-linux-gcc (GCC) 11.2.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-dirty
        # https://git.kernel.org/pub/scm/linux/kernel/git/kees/linux.git/commit/?id=a767e6fd68d2ca84578649acc072f21b81edfb3a
        git remote add kees https://git.kernel.org/pub/scm/linux/kernel/git/kees/linux.git
        git fetch --no-tags kees for-next/execve
        git checkout a767e6fd68d2ca84578649acc072f21b81edfb3a
        # save the config file to linux build tree
        mkdir build_dir
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-11.2.0 make.cross C=1 CF='-fdiagnostic-prefix -D__CHECK_ENDIAN__' O=build_dir ARCH=m68k SHELL=/bin/bash

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>


sparse warnings: (new ones prefixed by >>)
>> fs/binfmt_flat.c:816:39: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected unsigned int [noderef] [usertype] __user *rp @@     got unsigned int [usertype] *[noderef] __user @@
   fs/binfmt_flat.c:816:39: sparse:     expected unsigned int [noderef] [usertype] __user *rp
   fs/binfmt_flat.c:816:39: sparse:     got unsigned int [usertype] *[noderef] __user
   fs/binfmt_flat.c:856:29: sparse: sparse: restricted __be32 degrades to integer
   fs/binfmt_flat.c:899:29: sparse: sparse: restricted __be32 degrades to integer

vim +816 fs/binfmt_flat.c

   563	
   564		/*
   565		 * Check initial limits. This avoids letting people circumvent
   566		 * size limits imposed on them by creating programs with large
   567		 * arrays in the data or bss.
   568		 */
   569		rlim = rlimit(RLIMIT_DATA);
   570		if (rlim >= RLIM_INFINITY)
   571			rlim = ~0;
   572		if (data_len + bss_len > rlim) {
   573			ret = -ENOMEM;
   574			goto err;
   575		}
   576	
   577		/* Flush all traces of the currently running executable */
   578		if (id == 0) {
   579			ret = begin_new_exec(bprm);
   580			if (ret)
   581				goto err;
   582	
   583			/* OK, This is the point of no return */
   584			set_personality(PER_LINUX_32BIT);
   585			setup_new_exec(bprm);
   586		}
   587	
   588		/*
   589		 * calculate the extra space we need to map in
   590		 */
   591		extra = max_t(unsigned long, bss_len + stack_len,
   592				relocs * sizeof(unsigned long));
   593	
   594		/*
   595		 * there are a couple of cases here,  the separate code/data
   596		 * case,  and then the fully copied to RAM case which lumps
   597		 * it all together.
   598		 */
   599		if (!IS_ENABLED(CONFIG_MMU) && !(flags & (FLAT_FLAG_RAM|FLAT_FLAG_GZIP))) {
   600			/*
   601			 * this should give us a ROM ptr,  but if it doesn't we don't
   602			 * really care
   603			 */
   604			pr_debug("ROM mapping of file (we hope)\n");
   605	
   606			textpos = vm_mmap(bprm->file, 0, text_len, PROT_READ|PROT_EXEC,
   607					  MAP_PRIVATE, 0);
   608			if (!textpos || IS_ERR_VALUE(textpos)) {
   609				ret = textpos;
   610				if (!textpos)
   611					ret = -ENOMEM;
   612				pr_err("Unable to mmap process text, errno %d\n", ret);
   613				goto err;
   614			}
   615	
   616			len = data_len + extra +
   617				DATA_START_OFFSET_WORDS * sizeof(unsigned long);
   618			len = PAGE_ALIGN(len);
   619			realdatastart = vm_mmap(NULL, 0, len,
   620				PROT_READ|PROT_WRITE|PROT_EXEC, MAP_PRIVATE, 0);
   621	
   622			if (realdatastart == 0 || IS_ERR_VALUE(realdatastart)) {
   623				ret = realdatastart;
   624				if (!realdatastart)
   625					ret = -ENOMEM;
   626				pr_err("Unable to allocate RAM for process data, "
   627				       "errno %d\n", ret);
   628				vm_munmap(textpos, text_len);
   629				goto err;
   630			}
   631			datapos = ALIGN(realdatastart +
   632					DATA_START_OFFSET_WORDS * sizeof(unsigned long),
   633					FLAT_DATA_ALIGN);
   634	
   635			pr_debug("Allocated data+bss+stack (%u bytes): %lx\n",
   636				 data_len + bss_len + stack_len, datapos);
   637	
   638			fpos = ntohl(hdr->data_start);
   639	#ifdef CONFIG_BINFMT_ZFLAT
   640			if (flags & FLAT_FLAG_GZDATA) {
   641				result = decompress_exec(bprm, fpos, (char *)datapos,
   642							 full_data, 0);
   643			} else
   644	#endif
   645			{
   646				result = read_code(bprm->file, datapos, fpos,
   647						full_data);
   648			}
   649			if (IS_ERR_VALUE(result)) {
   650				ret = result;
   651				pr_err("Unable to read data+bss, errno %d\n", ret);
   652				vm_munmap(textpos, text_len);
   653				vm_munmap(realdatastart, len);
   654				goto err;
   655			}
   656	
   657			reloc = (__be32 __user *)
   658				(datapos + (ntohl(hdr->reloc_start) - text_len));
   659			memp = realdatastart;
   660			memp_size = len;
   661		} else {
   662	
   663			len = text_len + data_len + extra +
   664				DATA_START_OFFSET_WORDS * sizeof(u32);
   665			len = PAGE_ALIGN(len);
   666			textpos = vm_mmap(NULL, 0, len,
   667				PROT_READ | PROT_EXEC | PROT_WRITE, MAP_PRIVATE, 0);
   668	
   669			if (!textpos || IS_ERR_VALUE(textpos)) {
   670				ret = textpos;
   671				if (!textpos)
   672					ret = -ENOMEM;
   673				pr_err("Unable to allocate RAM for process text/data, "
   674				       "errno %d\n", ret);
   675				goto err;
   676			}
   677	
   678			realdatastart = textpos + ntohl(hdr->data_start);
   679			datapos = ALIGN(realdatastart +
   680					DATA_START_OFFSET_WORDS * sizeof(u32),
   681					FLAT_DATA_ALIGN);
   682	
   683			reloc = (__be32 __user *)
   684				(datapos + (ntohl(hdr->reloc_start) - text_len));
   685			memp = textpos;
   686			memp_size = len;
   687	#ifdef CONFIG_BINFMT_ZFLAT
   688			/*
   689			 * load it all in and treat it like a RAM load from now on
   690			 */
   691			if (flags & FLAT_FLAG_GZIP) {
   692	#ifndef CONFIG_MMU
   693				result = decompress_exec(bprm, sizeof(struct flat_hdr),
   694						 (((char *)textpos) + sizeof(struct flat_hdr)),
   695						 (text_len + full_data
   696							  - sizeof(struct flat_hdr)),
   697						 0);
   698				memmove((void *) datapos, (void *) realdatastart,
   699						full_data);
   700	#else
   701				/*
   702				 * This is used on MMU systems mainly for testing.
   703				 * Let's use a kernel buffer to simplify things.
   704				 */
   705				long unz_text_len = text_len - sizeof(struct flat_hdr);
   706				long unz_len = unz_text_len + full_data;
   707				char *unz_data = vmalloc(unz_len);
   708				if (!unz_data) {
   709					result = -ENOMEM;
   710				} else {
   711					result = decompress_exec(bprm, sizeof(struct flat_hdr),
   712								 unz_data, unz_len, 0);
   713					if (result == 0 &&
   714					    (copy_to_user((void __user *)textpos + sizeof(struct flat_hdr),
   715							  unz_data, unz_text_len) ||
   716					     copy_to_user((void __user *)datapos,
   717							  unz_data + unz_text_len, full_data)))
   718						result = -EFAULT;
   719					vfree(unz_data);
   720				}
   721	#endif
   722			} else if (flags & FLAT_FLAG_GZDATA) {
   723				result = read_code(bprm->file, textpos, 0, text_len);
   724				if (!IS_ERR_VALUE(result)) {
   725	#ifndef CONFIG_MMU
   726					result = decompress_exec(bprm, text_len, (char *) datapos,
   727							 full_data, 0);
   728	#else
   729					char *unz_data = vmalloc(full_data);
   730					if (!unz_data) {
   731						result = -ENOMEM;
   732					} else {
   733						result = decompress_exec(bprm, text_len,
   734							       unz_data, full_data, 0);
   735						if (result == 0 &&
   736						    copy_to_user((void __user *)datapos,
   737								 unz_data, full_data))
   738							result = -EFAULT;
   739						vfree(unz_data);
   740					}
   741	#endif
   742				}
   743			} else
   744	#endif /* CONFIG_BINFMT_ZFLAT */
   745			{
   746				result = read_code(bprm->file, textpos, 0, text_len);
   747				if (!IS_ERR_VALUE(result))
   748					result = read_code(bprm->file, datapos,
   749							   ntohl(hdr->data_start),
   750							   full_data);
   751			}
   752			if (IS_ERR_VALUE(result)) {
   753				ret = result;
   754				pr_err("Unable to read code+data+bss, errno %d\n", ret);
   755				vm_munmap(textpos, text_len + data_len + extra +
   756					  DATA_START_OFFSET_WORDS * sizeof(u32));
   757				goto err;
   758			}
   759		}
   760	
   761		start_code = textpos + sizeof(struct flat_hdr);
   762		end_code = textpos + text_len;
   763		text_len -= sizeof(struct flat_hdr); /* the real code len */
   764	
   765		/* The main program needs a little extra setup in the task structure */
   766		if (id == 0) {
   767			current->mm->start_code = start_code;
   768			current->mm->end_code = end_code;
   769			current->mm->start_data = datapos;
   770			current->mm->end_data = datapos + data_len;
   771			/*
   772			 * set up the brk stuff, uses any slack left in data/bss/stack
   773			 * allocation.  We put the brk after the bss (between the bss
   774			 * and stack) like other platforms.
   775			 * Userspace code relies on the stack pointer starting out at
   776			 * an address right at the end of a page.
   777			 */
   778			current->mm->start_brk = datapos + data_len + bss_len;
   779			current->mm->brk = (current->mm->start_brk + 3) & ~3;
   780	#ifndef CONFIG_MMU
   781			current->mm->context.end_brk = memp + memp_size - stack_len;
   782	#endif
   783		}
   784	
   785		if (flags & FLAT_FLAG_KTRACE) {
   786			pr_info("Mapping is %lx, Entry point is %x, data_start is %x\n",
   787				textpos, 0x00ffffff&ntohl(hdr->entry), ntohl(hdr->data_start));
   788			pr_info("%s %s: TEXT=%lx-%lx DATA=%lx-%lx BSS=%lx-%lx\n",
   789				id ? "Lib" : "Load", bprm->filename,
   790				start_code, end_code, datapos, datapos + data_len,
   791				datapos + data_len, (datapos + data_len + bss_len + 3) & ~3);
   792		}
   793	
   794		/* Store the current module values into the global library structure */
   795		libinfo->lib_list[id].start_code = start_code;
   796		libinfo->lib_list[id].start_data = datapos;
   797		libinfo->lib_list[id].start_brk = datapos + data_len + bss_len;
   798		libinfo->lib_list[id].text_len = text_len;
   799		libinfo->lib_list[id].loaded = 1;
   800		libinfo->lib_list[id].entry = (0x00ffffff & ntohl(hdr->entry)) + textpos;
   801		libinfo->lib_list[id].build_date = ntohl(hdr->build_date);
   802	
   803		/*
   804		 * We just load the allocations into some temporary memory to
   805		 * help simplify all this mumbo jumbo
   806		 *
   807		 * We've got two different sections of relocation entries.
   808		 * The first is the GOT which resides at the beginning of the data segment
   809		 * and is terminated with a -1.  This one can be relocated in place.
   810		 * The second is the extra relocation entries tacked after the image's
   811		 * data segment. These require a little more processing as the entry is
   812		 * really an offset into the image which contains an offset into the
   813		 * image.
   814		 */
   815		if (flags & FLAT_FLAG_GOTPIC) {
 > 816			rp = skip_got_header((u32 * __user) datapos);
   817			for (; ; rp++) {
   818				u32 addr, rp_val;
   819				if (get_user(rp_val, rp))
   820					return -EFAULT;
   821				if (rp_val == 0xffffffff)
   822					break;
   823				if (rp_val) {
   824					addr = calc_reloc(rp_val, libinfo, id, 0);
   825					if (addr == RELOC_FAILED) {
   826						ret = -ENOEXEC;
   827						goto err;
   828					}
   829					if (put_user(addr, rp))
   830						return -EFAULT;
   831				}
   832			}
   833		}
   834	
   835		/*
   836		 * Now run through the relocation entries.
   837		 * We've got to be careful here as C++ produces relocatable zero
   838		 * entries in the constructor and destructor tables which are then
   839		 * tested for being not zero (which will always occur unless we're
   840		 * based from address zero).  This causes an endless loop as __start
   841		 * is at zero.  The solution used is to not relocate zero addresses.
   842		 * This has the negative side effect of not allowing a global data
   843		 * reference to be statically initialised to _stext (I've moved
   844		 * __start to address 4 so that is okay).
   845		 */
   846		if (rev > OLD_FLAT_VERSION) {
   847			for (i = 0; i < relocs; i++) {
   848				u32 addr, relval;
   849				__be32 tmp;
   850	
   851				/*
   852				 * Get the address of the pointer to be
   853				 * relocated (of course, the address has to be
   854				 * relocated first).
   855				 */
   856				if (get_user(tmp, reloc + i))
   857					return -EFAULT;
   858				relval = ntohl(tmp);
   859				addr = flat_get_relocate_addr(relval);
   860				rp = (u32 __user *)calc_reloc(addr, libinfo, id, 1);
   861				if (rp == (u32 __user *)RELOC_FAILED) {
   862					ret = -ENOEXEC;
   863					goto err;
   864				}
   865	
   866				/* Get the pointer's value.  */
   867				ret = flat_get_addr_from_rp(rp, relval, flags, &addr);
   868				if (unlikely(ret))
   869					goto err;
   870	
   871				if (addr != 0) {
   872					/*
   873					 * Do the relocation.  PIC relocs in the data section are
   874					 * already in target order
   875					 */
   876					if ((flags & FLAT_FLAG_GOTPIC) == 0) {
   877						/*
   878						 * Meh, the same value can have a different
   879						 * byte order based on a flag..
   880						 */
   881						addr = ntohl((__force __be32)addr);
   882					}
   883					addr = calc_reloc(addr, libinfo, id, 0);
   884					if (addr == RELOC_FAILED) {
   885						ret = -ENOEXEC;
   886						goto err;
   887					}
   888	
   889					/* Write back the relocated pointer.  */
   890					ret = flat_put_addr_at_rp(rp, addr, relval);
   891					if (unlikely(ret))
   892						goto err;
   893				}
   894			}
   895	#ifdef CONFIG_BINFMT_FLAT_OLD
   896		} else {
   897			for (i = 0; i < relocs; i++) {
   898				__be32 relval;
   899				if (get_user(relval, reloc + i))
   900					return -EFAULT;
   901				old_reloc(ntohl(relval));
   902			}
   903	#endif /* CONFIG_BINFMT_FLAT_OLD */
   904		}
   905	
   906		flush_icache_user_range(start_code, end_code);
   907	
   908		/* zero the BSS,  BRK and stack areas */
   909		if (clear_user((void __user *)(datapos + data_len), bss_len +
   910			       (memp + memp_size - stack_len -		/* end brk */
   911			       libinfo->lib_list[id].start_brk) +	/* start brk */
   912			       stack_len))
   913			return -EFAULT;
   914	
   915		return 0;
   916	err:
   917		return ret;
   918	}
   919	

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

                 reply	other threads:[~2022-04-18 15:49 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

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=202204182333.OIUOotK8-lkp@intel.com \
    --to=lkp@intel.com \
    --cc=damien.lemoal@opensource.wdc.com \
    --cc=kbuild-all@lists.01.org \
    --cc=keescook@chromium.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=niklas.cassel@wdc.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).