From: Dan Carpenter <dan.carpenter@oracle.com>
To: repnop@google.com
Cc: Amir Goldstein <amir73il@gmail.com>, linux-fsdevel@vger.kernel.org
Subject: [bug report] fanotify: fix copy_event_to_user() fid error clean up
Date: Wed, 21 Jul 2021 05:54:07 -0700 [thread overview]
Message-ID: <20210721125407.GA25822@kili> (raw)
Hello Matthew Bobrowski,
The patch f644bc449b37: "fanotify: fix copy_event_to_user() fid error
clean up" from Jun 11, 2021, leads to the following static checker
warning:
fs/notify/fanotify/fanotify_user.c:533 copy_event_to_user()
error: we previously assumed 'f' could be null (see line 462)
fs/notify/fanotify/fanotify_user.c
401 static ssize_t copy_event_to_user(struct fsnotify_group *group,
402 struct fanotify_event *event,
403 char __user *buf, size_t count)
404 {
405 struct fanotify_event_metadata metadata;
406 struct path *path = fanotify_event_path(event);
407 struct fanotify_info *info = fanotify_event_info(event);
408 unsigned int fid_mode = FAN_GROUP_FLAG(group, FANOTIFY_FID_BITS);
409 struct file *f = NULL;
410 int ret, fd = FAN_NOFD;
411 int info_type = 0;
412
413 pr_debug("%s: group=%p event=%p\n", __func__, group, event);
414
415 metadata.event_len = FAN_EVENT_METADATA_LEN +
416 fanotify_event_info_len(fid_mode, event);
417 metadata.metadata_len = FAN_EVENT_METADATA_LEN;
418 metadata.vers = FANOTIFY_METADATA_VERSION;
419 metadata.reserved = 0;
420 metadata.mask = event->mask & FANOTIFY_OUTGOING_EVENTS;
421 metadata.pid = pid_vnr(event->pid);
422 /*
423 * For an unprivileged listener, event->pid can be used to identify the
424 * events generated by the listener process itself, without disclosing
425 * the pids of other processes.
426 */
427 if (FAN_GROUP_FLAG(group, FANOTIFY_UNPRIV) &&
428 task_tgid(current) != event->pid)
429 metadata.pid = 0;
430
431 /*
432 * For now, fid mode is required for an unprivileged listener and
433 * fid mode does not report fd in events. Keep this check anyway
434 * for safety in case fid mode requirement is relaxed in the future
435 * to allow unprivileged listener to get events with no fd and no fid.
436 */
437 if (!FAN_GROUP_FLAG(group, FANOTIFY_UNPRIV) &&
438 path && path->mnt && path->dentry) {
439 fd = create_fd(group, path, &f);
440 if (fd < 0)
441 return fd;
442 }
"f" is NULL on the else path
443 metadata.fd = fd;
444
445 ret = -EFAULT;
446 /*
447 * Sanity check copy size in case get_one_event() and
448 * event_len sizes ever get out of sync.
449 */
450 if (WARN_ON_ONCE(metadata.event_len > count))
451 goto out_close_fd;
452
453 if (copy_to_user(buf, &metadata, FAN_EVENT_METADATA_LEN))
454 goto out_close_fd;
^^^^^^^^^^^^^^^^^
This is problematic
455
456 buf += FAN_EVENT_METADATA_LEN;
457 count -= FAN_EVENT_METADATA_LEN;
458
459 if (fanotify_is_perm_event(event->mask))
460 FANOTIFY_PERM(event)->fd = fd;
461
462 if (f)
^^^
463 fd_install(fd, f);
464
465 /* Event info records order is: dir fid + name, child fid */
466 if (fanotify_event_dir_fh_len(event)) {
467 info_type = info->name_len ? FAN_EVENT_INFO_TYPE_DFID_NAME :
468 FAN_EVENT_INFO_TYPE_DFID;
469 ret = copy_info_to_user(fanotify_event_fsid(event),
470 fanotify_info_dir_fh(info),
471 info_type, fanotify_info_name(info),
472 info->name_len, buf, count);
473 if (ret < 0)
474 goto out_close_fd;
475
476 buf += ret;
477 count -= ret;
478 }
479
480 if (fanotify_event_object_fh_len(event)) {
481 const char *dot = NULL;
482 int dot_len = 0;
483
484 if (fid_mode == FAN_REPORT_FID || info_type) {
485 /*
486 * With only group flag FAN_REPORT_FID only type FID is
487 * reported. Second info record type is always FID.
488 */
489 info_type = FAN_EVENT_INFO_TYPE_FID;
490 } else if ((fid_mode & FAN_REPORT_NAME) &&
491 (event->mask & FAN_ONDIR)) {
492 /*
493 * With group flag FAN_REPORT_NAME, if name was not
494 * recorded in an event on a directory, report the
495 * name "." with info type DFID_NAME.
496 */
497 info_type = FAN_EVENT_INFO_TYPE_DFID_NAME;
498 dot = ".";
499 dot_len = 1;
500 } else if ((event->mask & ALL_FSNOTIFY_DIRENT_EVENTS) ||
501 (event->mask & FAN_ONDIR)) {
502 /*
503 * With group flag FAN_REPORT_DIR_FID, a single info
504 * record has type DFID for directory entry modification
505 * event and for event on a directory.
506 */
507 info_type = FAN_EVENT_INFO_TYPE_DFID;
508 } else {
509 /*
510 * With group flags FAN_REPORT_DIR_FID|FAN_REPORT_FID,
511 * a single info record has type FID for event on a
512 * non-directory, when there is no directory to report.
513 * For example, on FAN_DELETE_SELF event.
514 */
515 info_type = FAN_EVENT_INFO_TYPE_FID;
516 }
517
518 ret = copy_info_to_user(fanotify_event_fsid(event),
519 fanotify_event_object_fh(event),
520 info_type, dot, dot_len, buf, count);
521 if (ret < 0)
522 goto out_close_fd;
^^^^^^^^^^^^^^^^^
523
524 buf += ret;
525 count -= ret;
526 }
527
528 return metadata.event_len;
529
530 out_close_fd:
531 if (fd != FAN_NOFD) {
532 put_unused_fd(fd);
--> 533 fput(f);
^^^^^^^
This leads to a NULL dereference
534 }
535 return ret;
536 }
regards,
dan carpenter
next reply other threads:[~2021-07-21 12:54 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-07-21 12:54 Dan Carpenter [this message]
2021-07-21 22:38 ` [bug report] fanotify: fix copy_event_to_user() fid error clean up Matthew Bobrowski
2021-07-22 9:01 ` Amir Goldstein
2021-07-22 9:31 ` Dan Carpenter
2021-07-22 14:01 ` Dan Carpenter
2021-07-22 23:13 ` Matthew Bobrowski
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=20210721125407.GA25822@kili \
--to=dan.carpenter@oracle.com \
--cc=amir73il@gmail.com \
--cc=linux-fsdevel@vger.kernel.org \
--cc=repnop@google.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 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.