All of lore.kernel.org
 help / color / mirror / Atom feed
From: Dan Carpenter <dan.carpenter@oracle.com>
To: amir73il@gmail.com
Cc: linux-fsdevel@vger.kernel.org
Subject: [bug report] fanotify: record name info for FAN_DIR_MODIFY event
Date: Tue, 16 Nov 2021 14:45:16 +0300	[thread overview]
Message-ID: <20211116114516.GA11780@kili> (raw)

Hello Amir Goldstein,

The patch cacfb956d46e: "fanotify: record name info for
FAN_DIR_MODIFY event" from Mar 19, 2020, leads to the following
Smatch static checker warning:

	fs/notify/fanotify/fanotify_user.c:401 copy_fid_info_to_user()
	error: we previously assumed 'fh' could be null (see line 362)

fs/notify/fanotify/fanotify_user.c
    354 static int copy_fid_info_to_user(__kernel_fsid_t *fsid, struct fanotify_fh *fh,
    355                                  int info_type, const char *name,
    356                                  size_t name_len,
    357                                  char __user *buf, size_t count)
    358 {
    359         struct fanotify_event_info_fid info = { };
    360         struct file_handle handle = { };
    361         unsigned char bounce[FANOTIFY_INLINE_FH_LEN], *fh_buf;
    362         size_t fh_len = fh ? fh->len : 0;
                                ^^^^^^^^^^^^^
The patch adds a check for in "fh" is NULL

    363         size_t info_len = fanotify_fid_info_len(fh_len, name_len);
    364         size_t len = info_len;
    365 
    366         pr_debug("%s: fh_len=%zu name_len=%zu, info_len=%zu, count=%zu\n",
    367                  __func__, fh_len, name_len, info_len, count);
    368 
    369         if (WARN_ON_ONCE(len < sizeof(info) || len > count))
    370                 return -EFAULT;
    371 
    372         /*
    373          * Copy event info fid header followed by variable sized file handle
    374          * and optionally followed by variable sized filename.
    375          */
    376         switch (info_type) {
    377         case FAN_EVENT_INFO_TYPE_FID:
    378         case FAN_EVENT_INFO_TYPE_DFID:
    379                 if (WARN_ON_ONCE(name_len))
    380                         return -EFAULT;
    381                 break;
    382         case FAN_EVENT_INFO_TYPE_DFID_NAME:
    383                 if (WARN_ON_ONCE(!name || !name_len))
    384                         return -EFAULT;
    385                 break;
    386         default:
    387                 return -EFAULT;
    388         }
    389 
    390         info.hdr.info_type = info_type;
    391         info.hdr.len = len;
    392         info.fsid = *fsid;
    393         if (copy_to_user(buf, &info, sizeof(info)))
    394                 return -EFAULT;
    395 
    396         buf += sizeof(info);
    397         len -= sizeof(info);
    398         if (WARN_ON_ONCE(len < sizeof(handle)))
    399                 return -EFAULT;
    400 
--> 401         handle.handle_type = fh->type;
                                     ^^^^^^^^
But this code dereferences "fh" without checking.

    402         handle.handle_bytes = fh_len;
    403 
    404         /* Mangle handle_type for bad file_handle */
    405         if (!fh_len)
    406                 handle.handle_type = FILEID_INVALID;
    407 
    408         if (copy_to_user(buf, &handle, sizeof(handle)))
    409                 return -EFAULT;
    410 
    411         buf += sizeof(handle);
    412         len -= sizeof(handle);
    413         if (WARN_ON_ONCE(len < fh_len))
    414                 return -EFAULT;
    415 
    416         /*
    417          * For an inline fh and inline file name, copy through stack to exclude
    418          * the copy from usercopy hardening protections.
    419          */
    420         fh_buf = fanotify_fh_buf(fh);
    421         if (fh_len <= FANOTIFY_INLINE_FH_LEN) {
    422                 memcpy(bounce, fh_buf, fh_len);
    423                 fh_buf = bounce;
    424         }
    425         if (copy_to_user(buf, fh_buf, fh_len))
    426                 return -EFAULT;
    427 
    428         buf += fh_len;
    429         len -= fh_len;
    430 
    431         if (name_len) {
    432                 /* Copy the filename with terminating null */
    433                 name_len++;
    434                 if (WARN_ON_ONCE(len < name_len))
    435                         return -EFAULT;
    436 
    437                 if (copy_to_user(buf, name, name_len))
    438                         return -EFAULT;
    439 
    440                 buf += name_len;
    441                 len -= name_len;
    442         }
    443 
    444         /* Pad with 0's */
    445         WARN_ON_ONCE(len < 0 || len >= FANOTIFY_EVENT_ALIGN);
    446         if (len > 0 && clear_user(buf, len))
    447                 return -EFAULT;
    448 
    449         return info_len;
    450 }

regards,
dan carpenter

             reply	other threads:[~2021-11-16 11:46 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-11-16 11:45 Dan Carpenter [this message]
2021-11-16 15:21 ` [bug report] fanotify: record name info for FAN_DIR_MODIFY event Amir Goldstein
2021-11-16 17:57   ` Dan Carpenter
2021-11-16 18:01     ` Dan Carpenter
2021-11-16 18:30       ` Amir Goldstein

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=20211116114516.GA11780@kili \
    --to=dan.carpenter@oracle.com \
    --cc=amir73il@gmail.com \
    --cc=linux-fsdevel@vger.kernel.org \
    /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.