fs/nfsd/nfs4xdr.c:4683:24: sparse: sparse: incorrect type in return expression (different base types)

From: kernel test robot
Date: Wed Sep 23 2020 - 11:42:34 EST


tree: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git master
head: 805c6d3c19210c90c109107d189744e960eae025
commit: 23e50fe3a5e6045a573c69d4b0e3d78aa6183323 nfsd: implement the xattr functions and en/decode logic
date: 2 months ago
config: m68k-randconfig-s032-20200923 (attached as .config)
compiler: m68k-linux-gcc (GCC) 9.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.2-201-g24bdaac6-dirty
git checkout 23e50fe3a5e6045a573c69d4b0e3d78aa6183323
# save the attached .config to linux build tree
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-9.3.0 make.cross C=1 CF='-fdiagnostic-prefix -D__CHECK_ENDIAN__' ARCH=m68k

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


sparse warnings: (new ones prefixed by >>)

fs/nfsd/nfs4xdr.c:1860:16: sparse: sparse: incorrect type in assignment (different base types) @@ expected int status @@ got restricted __be32 @@
fs/nfsd/nfs4xdr.c:1860:16: sparse: expected int status
fs/nfsd/nfs4xdr.c:1860:16: sparse: got restricted __be32
fs/nfsd/nfs4xdr.c:1862:24: sparse: sparse: incorrect type in return expression (different base types) @@ expected restricted __be32 @@ got int status @@
fs/nfsd/nfs4xdr.c:1862:24: sparse: expected restricted __be32
fs/nfsd/nfs4xdr.c:1862:24: sparse: got int status
>> fs/nfsd/nfs4xdr.c:4683:24: sparse: sparse: incorrect type in return expression (different base types) @@ expected int @@ got restricted __be32 [usertype] @@
>> fs/nfsd/nfs4xdr.c:4683:24: sparse: expected int
>> fs/nfsd/nfs4xdr.c:4683:24: sparse: got restricted __be32 [usertype]
fs/nfsd/nfs4xdr.c:4693:32: sparse: sparse: incorrect type in return expression (different base types) @@ expected int @@ got restricted __be32 [usertype] @@
fs/nfsd/nfs4xdr.c:4693:32: sparse: expected int
fs/nfsd/nfs4xdr.c:4693:32: sparse: got restricted __be32 [usertype]
>> fs/nfsd/nfs4xdr.c:4730:13: sparse: sparse: incorrect type in assignment (different base types) @@ expected restricted __be32 [usertype] err @@ got int @@
>> fs/nfsd/nfs4xdr.c:4730:13: sparse: expected restricted __be32 [usertype] err
>> fs/nfsd/nfs4xdr.c:4730:13: sparse: got int
>> fs/nfsd/nfs4xdr.c:4882:15: sparse: sparse: incorrect type in assignment (different base types) @@ expected unsigned int [assigned] [usertype] count @@ got restricted __be32 [usertype] @@
>> fs/nfsd/nfs4xdr.c:4882:15: sparse: expected unsigned int [assigned] [usertype] count
fs/nfsd/nfs4xdr.c:4882:15: sparse: got restricted __be32 [usertype]

# https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=23e50fe3a5e6045a573c69d4b0e3d78aa6183323
git remote add linus https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
git fetch --no-tags linus master
git checkout 23e50fe3a5e6045a573c69d4b0e3d78aa6183323
vim +4683 fs/nfsd/nfs4xdr.c

4669
4670 /*
4671 * Encode kmalloc-ed buffer in to XDR stream.
4672 */
4673 static int
4674 nfsd4_vbuf_to_stream(struct xdr_stream *xdr, char *buf, u32 buflen)
4675 {
4676 u32 cplen;
4677 __be32 *p;
4678
4679 cplen = min_t(unsigned long, buflen,
4680 ((void *)xdr->end - (void *)xdr->p));
4681 p = xdr_reserve_space(xdr, cplen);
4682 if (!p)
> 4683 return nfserr_resource;
4684
4685 memcpy(p, buf, cplen);
4686 buf += cplen;
4687 buflen -= cplen;
4688
4689 while (buflen) {
4690 cplen = min_t(u32, buflen, PAGE_SIZE);
4691 p = xdr_reserve_space(xdr, cplen);
4692 if (!p)
4693 return nfserr_resource;
4694
4695 memcpy(p, buf, cplen);
4696
4697 if (cplen < PAGE_SIZE) {
4698 /*
4699 * We're done, with a length that wasn't page
4700 * aligned, so possibly not word aligned. Pad
4701 * any trailing bytes with 0.
4702 */
4703 xdr_encode_opaque_fixed(p, NULL, cplen);
4704 break;
4705 }
4706
4707 buflen -= PAGE_SIZE;
4708 buf += PAGE_SIZE;
4709 }
4710
4711 return 0;
4712 }
4713
4714 static __be32
4715 nfsd4_encode_getxattr(struct nfsd4_compoundres *resp, __be32 nfserr,
4716 struct nfsd4_getxattr *getxattr)
4717 {
4718 struct xdr_stream *xdr = &resp->xdr;
4719 __be32 *p, err;
4720
4721 p = xdr_reserve_space(xdr, 4);
4722 if (!p)
4723 return nfserr_resource;
4724
4725 *p = cpu_to_be32(getxattr->getxa_len);
4726
4727 if (getxattr->getxa_len == 0)
4728 return 0;
4729
> 4730 err = nfsd4_vbuf_to_stream(xdr, getxattr->getxa_buf,
4731 getxattr->getxa_len);
4732
4733 kvfree(getxattr->getxa_buf);
4734
4735 return err;
4736 }
4737
4738 static __be32
4739 nfsd4_encode_setxattr(struct nfsd4_compoundres *resp, __be32 nfserr,
4740 struct nfsd4_setxattr *setxattr)
4741 {
4742 struct xdr_stream *xdr = &resp->xdr;
4743 __be32 *p;
4744
4745 p = xdr_reserve_space(xdr, 20);
4746 if (!p)
4747 return nfserr_resource;
4748
4749 encode_cinfo(p, &setxattr->setxa_cinfo);
4750
4751 return 0;
4752 }
4753
4754 /*
4755 * See if there are cookie values that can be rejected outright.
4756 */
4757 static __be32
4758 nfsd4_listxattr_validate_cookie(struct nfsd4_listxattrs *listxattrs,
4759 u32 *offsetp)
4760 {
4761 u64 cookie = listxattrs->lsxa_cookie;
4762
4763 /*
4764 * If the cookie is larger than the maximum number we can fit
4765 * in either the buffer we just got back from vfs_listxattr, or,
4766 * XDR-encoded, in the return buffer, it's invalid.
4767 */
4768 if (cookie > (listxattrs->lsxa_len) / (XATTR_USER_PREFIX_LEN + 2))
4769 return nfserr_badcookie;
4770
4771 if (cookie > (listxattrs->lsxa_maxcount /
4772 (XDR_QUADLEN(XATTR_USER_PREFIX_LEN + 2) + 4)))
4773 return nfserr_badcookie;
4774
4775 *offsetp = (u32)cookie;
4776 return 0;
4777 }
4778
4779 static __be32
4780 nfsd4_encode_listxattrs(struct nfsd4_compoundres *resp, __be32 nfserr,
4781 struct nfsd4_listxattrs *listxattrs)
4782 {
4783 struct xdr_stream *xdr = &resp->xdr;
4784 u32 cookie_offset, count_offset, eof;
4785 u32 left, xdrleft, slen, count;
4786 u32 xdrlen, offset;
4787 u64 cookie;
4788 char *sp;
4789 __be32 status;
4790 __be32 *p;
4791 u32 nuser;
4792
4793 eof = 1;
4794
4795 status = nfsd4_listxattr_validate_cookie(listxattrs, &offset);
4796 if (status)
4797 goto out;
4798
4799 /*
4800 * Reserve space for the cookie and the name array count. Record
4801 * the offsets to save them later.
4802 */
4803 cookie_offset = xdr->buf->len;
4804 count_offset = cookie_offset + 8;
4805 p = xdr_reserve_space(xdr, 12);
4806 if (!p) {
4807 status = nfserr_resource;
4808 goto out;
4809 }
4810
4811 count = 0;
4812 left = listxattrs->lsxa_len;
4813 sp = listxattrs->lsxa_buf;
4814 nuser = 0;
4815
4816 xdrleft = listxattrs->lsxa_maxcount;
4817
4818 while (left > 0 && xdrleft > 0) {
4819 slen = strlen(sp);
4820
4821 /*
4822 * Check if this a user. attribute, skip it if not.
4823 */
4824 if (strncmp(sp, XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN))
4825 goto contloop;
4826
4827 slen -= XATTR_USER_PREFIX_LEN;
4828 xdrlen = 4 + ((slen + 3) & ~3);
4829 if (xdrlen > xdrleft) {
4830 if (count == 0) {
4831 /*
4832 * Can't even fit the first attribute name.
4833 */
4834 status = nfserr_toosmall;
4835 goto out;
4836 }
4837 eof = 0;
4838 goto wreof;
4839 }
4840
4841 left -= XATTR_USER_PREFIX_LEN;
4842 sp += XATTR_USER_PREFIX_LEN;
4843 if (nuser++ < offset)
4844 goto contloop;
4845
4846
4847 p = xdr_reserve_space(xdr, xdrlen);
4848 if (!p) {
4849 status = nfserr_resource;
4850 goto out;
4851 }
4852
4853 p = xdr_encode_opaque(p, sp, slen);
4854
4855 xdrleft -= xdrlen;
4856 count++;
4857 contloop:
4858 sp += slen + 1;
4859 left -= slen + 1;
4860 }
4861
4862 /*
4863 * If there were user attributes to copy, but we didn't copy
4864 * any, the offset was too large (e.g. the cookie was invalid).
4865 */
4866 if (nuser > 0 && count == 0) {
4867 status = nfserr_badcookie;
4868 goto out;
4869 }
4870
4871 wreof:
4872 p = xdr_reserve_space(xdr, 4);
4873 if (!p) {
4874 status = nfserr_resource;
4875 goto out;
4876 }
4877 *p = cpu_to_be32(eof);
4878
4879 cookie = offset + count;
4880
4881 write_bytes_to_xdr_buf(xdr->buf, cookie_offset, &cookie, 8);
> 4882 count = htonl(count);
4883 write_bytes_to_xdr_buf(xdr->buf, count_offset, &count, 4);
4884 out:
4885 if (listxattrs->lsxa_len)
4886 kvfree(listxattrs->lsxa_buf);
4887 return status;
4888 }
4889

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@xxxxxxxxxxxx

Attachment: .config.gz
Description: application/gzip