[bug report] ovl: make sure that real fid is 32bit aligned in memory

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hello Amir Goldstein,

The patch cbe7fba8edfc: "ovl: make sure that real fid is 32bit
aligned in memory" from Nov 15, 2019, leads to the following static
checker warning:

	fs/overlayfs/export.c:791 ovl_fid_to_fh()
	warn: check that subtract can't underflow

fs/overlayfs/export.c
   775  static struct ovl_fh *ovl_fid_to_fh(struct fid *fid, int buflen, int fh_type)
   776  {
   777          struct ovl_fh *fh;
   778  
   779          /* If on-wire inner fid is aligned - nothing to do */
   780          if (fh_type == OVL_FILEID_V1)
   781                  return (struct ovl_fh *)fid;
   782  
   783          if (fh_type != OVL_FILEID_V0)
   784                  return ERR_PTR(-EINVAL);
   785  
   786          fh = kzalloc(buflen, GFP_KERNEL);
   787          if (!fh)
   788                  return ERR_PTR(-ENOMEM);
   789  
   790          /* Copy unaligned inner fh into aligned buffer */
   791          memcpy(&fh->fb, fid, buflen - OVL_FH_WIRE_OFFSET);
                                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^

   792          return fh;
   793  }

Samtch thinks buflen can be "0,4-128".  OVL_FH_WIRE_OFFSET is 3. The
problem is that 0 - 3 is a negative and the memcpy() will crash.

In do_handle_to_path() we do:

	handle_dwords = handle->handle_bytes >> 2;

Handle ->handle_bytes is non-zero but when it's >> 2 then it can become
zero.  It's a round down.  In ovl_fh_to_dentry() we do:

	int len = fh_len << 2;

If we rounded down to zero then "len" is still zero.  Obviously one fix
would be to add a check in ovl_fid_to_fh().

	if (buflen < sizeof(*fh))
		return ERR_PTR(-EINVAL);

But that feels like papering over the bug.

regards,
dan carpenter



[Index of Archives]     [Linux Filesystems Devel]     [Linux NFS]     [Linux NILFS]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux