Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RHEL 8.9 nullptr dereference #377

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions dist/dattobd.spec
Original file line number Diff line number Diff line change
Expand Up @@ -473,7 +473,7 @@ fi
if [ ! -d %{_systemd_services}/reboot.target.wants/ ]; then
mkdir -p %{_systemd_services}/reboot.target.wants
fi
ln -s %{_systemd_services}/umount-rootfs.service %{_systemd_services}/reboot.target.wants/umount-rootfs.service
ln -fs %{_systemd_services}/umount-rootfs.service %{_systemd_services}/reboot.target.wants/umount-rootfs.service

%postun -n %{libname}
/sbin/ldconfig
Expand Down Expand Up @@ -517,7 +517,7 @@ rm -rf %{buildroot}


%post
ln -s %{_systemd_services}/umount-rootfs.service %{_systemd_services}/reboot.target.wants/umount-rootfs.service
ln -fs %{_systemd_services}/umount-rootfs.service %{_systemd_services}/reboot.target.wants/umount-rootfs.service

%doc README.md doc/STRUCTURE.md
%if "%{_vendor}" == "redhat"
Expand Down
21 changes: 12 additions & 9 deletions src/bdev_state_handler.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ void auto_transition_active(unsigned int minor, const char *dir_name)
{
struct snap_device *dev = snap_devices[minor];

LOG_DEBUG("ENTER %s minor: %d", __func__, minor);
LOG_DEBUG("ENTER %s minor: %d", __func__, minor);
mutex_lock(&ioctl_mutex);

if (test_bit(UNVERIFIED, &dev->sd_state)) {
Expand Down Expand Up @@ -107,8 +107,7 @@ int __handle_bdev_mount_writable(const char *dir_name,
struct snap_device *dev;
struct block_device *cur_bdev;

LOG_DEBUG("ENTER __handle_bdev_mount_writable");

LOG_DEBUG("ENTER %s", __func__);
tracer_for_each(dev, i)
{
if (!dev || test_bit(ACTIVE, &dev->sd_state) ||
Expand All @@ -122,7 +121,7 @@ int __handle_bdev_mount_writable(const char *dir_name,
if (test_bit(UNVERIFIED, &dev->sd_state)) {
// get the block device for the unverified tracer we are
// looking into
cur_bdev = blkdev_get_by_path(dev->sd_bdev_path,
cur_bdev = dattodb_blkdev_by_path(dev->sd_bdev_path,
FMODE_READ, NULL);
if (IS_ERR(cur_bdev)) {
cur_bdev = NULL;
Expand Down Expand Up @@ -159,7 +158,7 @@ int __handle_bdev_mount_writable(const char *dir_name,
ret = -ENODEV;

out:
LOG_DEBUG("EXIT __handle_bdev_mount_writable");
LOG_DEBUG("EXIT %s", __func__);
*idx_out = i;
return ret;
}
Expand Down Expand Up @@ -194,6 +193,10 @@ int handle_bdev_mount_event(const char *dir_name, int follow_flags,
#else
ret = user_path_at(AT_FDCWD, dir_name, lookup_flags, &path);
#endif //LINUX_VERSION_CODE
if (ret) {
LOG_DEBUG("error finding path");
goto out;
}

LOG_DEBUG("path->dentry: %s, path->mnt->mnt_root: %s", path.dentry->d_name.name, path.mnt->mnt_root->d_name.name);

Expand Down Expand Up @@ -245,10 +248,10 @@ void post_umount_check(int dormant_ret, int umount_ret, unsigned int idx,
struct snap_device *dev;
struct super_block *sb;

//LOG_DEBUG("ENTER %s", __func__);
LOG_DEBUG("ENTER %s", __func__);
// if we didn't do anything or failed, just return
if (dormant_ret){
//LOG_DEBUG("dormant_ret");
if (dormant_ret) {
LOG_DEBUG("EXIT %s, dormant_ret", __func__);
return;
}
dev = snap_devices[idx];
Expand All @@ -257,7 +260,7 @@ void post_umount_check(int dormant_ret, int umount_ret, unsigned int idx,
// reactivate
if (umount_ret) {
struct block_device *bdev;
bdev = blkdev_get_by_path(dev->sd_bdev_path, FMODE_READ, NULL);
bdev = dattodb_blkdev_by_path(dev->sd_bdev_path, FMODE_READ, NULL);
if (!bdev || IS_ERR(bdev)) {
LOG_DEBUG("device gone, moving to error state");
tracer_set_fail_state(dev, -ENODEV);
Expand Down
2 changes: 1 addition & 1 deletion src/bio_helper.c
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ void dattobd_set_bio_ops(struct bio *bio, req_op_t op, unsigned op_flags)
}
#endif

#ifndef HAVE_BIO_BI_OPF
#if !defined(HAVE_BIO_BI_OPF) && defined(HAVE_ENUM_REQ_OP)
void dattobd_set_bio_ops(struct bio *bio, req_op_t op, unsigned op_flags)
{
bio->bi_rw = 0;
Expand Down
114 changes: 101 additions & 13 deletions src/blkdev.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

#include "blkdev.h"

#ifndef HAVE_BLKDEV_GET_BY_PATH
#if !defined HAVE_BLKDEV_GET_BY_PATH && !defined HAVE_BLKDEV_GET_BY_PATH_4

/**
* dattobd_lookup_bdev() - Looks up the inode associated with the path, verifies
Expand Down Expand Up @@ -58,13 +58,8 @@ static struct block_device *dattobd_lookup_bdev(const char *pathname,
goto out;
}

#endif

#ifndef HAVE_BLKDEV_GET_BY_PATH
//#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,38)

/**
* blkdev_get_by_path() - Fetches the @block_device struct associated with the
* _blkdev_get_by_path() - Fetches the @block_device struct associated with the
* @pathname. This is very similar to @dattobd_lookup_bdev with minor
* additional validation.
*
Expand All @@ -76,7 +71,7 @@ static struct block_device *dattobd_lookup_bdev(const char *pathname,
* On success the @block_device structure otherwise an error created via
* ERR_PTR().
*/
struct block_device *blkdev_get_by_path(const char *pathname, fmode_t mode,
static struct block_device *_blkdev_get_by_path(const char *pathname, fmode_t mode,
void *holder)
{
struct block_device *bdev;
Expand All @@ -85,15 +80,108 @@ struct block_device *blkdev_get_by_path(const char *pathname, fmode_t mode,
return bdev;

if ((mode & FMODE_WRITE) && bdev_read_only(bdev)) {
#ifdef HAVE_BLKDEV_PUT_1
blkdev_put(bdev);
#else
blkdev_put(bdev, mode);
#endif
dattobd_blkdev_put(bdev);
return ERR_PTR(-EACCES);
}

return bdev;
}

#endif

/**
* dattodb_blkdev_by_path() - Fetches the @block_device struct associated with the
* @path. This function uses different methods based on available kernel functions
* to retrieve the block device.
*
* @path: the path name of a block special file.
* @mode: The mode used to open the block special file, likely just FMODE_READ.
* @holder: unused.
*
* Return:
* On success the @block_device structure otherwise an error created via
* ERR_PTR().
*/
struct block_device *dattodb_blkdev_by_path(const char *path, fmode_t mode,
void *holder)
{
#if defined HAVE_BLKDEV_GET_BY_PATH_4
return blkdev_get_by_path(path, mode, holder, NULL);

#elif defined HAVE_BLKDEV_GET_BY_PATH
return blkdev_get_by_path(path, mode, holder);

#else
return _blkdev_get_by_path(path, mode, holder);
#endif
}

/**
* dattobd_get_super() - Scans the superblock list and finds the superblock of the
* file system mounted on the @bd given. This function uses different methods
* based on available kernel functions to retrieve the super block.
*
* @block_device: mounted block device structure pointer.
*
* Return:
* On success the @super_block structure pointer otherwise NULL.
*/
struct super_block *dattobd_get_super(struct block_device * bd)
{
#if defined HAVE_BD_SUPER
return (bd != NULL) ? bd->bd_super : NULL;

#elif defined HAVE_GET_SUPER
return get_super(bdev);

#else
struct super_block* (*get_active_superblock)(struct block_device*)= (GET_ACTIVE_SUPER_ADDR != 0) ? (struct super_block* (*)(struct block_device*))(GET_ACTIVE_SUPER_ADDR +(long long)(((void*)kfree)-(void*)KFREE_ADDR)):NULL;
return get_active_superblock(bd);
#endif
}

/**
* dattobd_drop_super() - Releases the superblock of the file system.
* This function performs the appropriate action based on the available
* kernel functions to release or drop the superblock.
*
* @sb: super block structure pointer to be released.
*
* Return:
* void.
*/
void dattobd_drop_super(struct super_block *sb)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pls simplify to #if defined HAVE_GET_SUPER return drop_super(sb) #endif return;

{
#if defined HAVE_BD_SUPER
return;

#elif defined HAVE_GET_SUPER
return drop_super(sb);

#else
return;
#endif
}

/**
* dattobd_blkdev_put() - Releases a reference to a block device.
* This function performs the appropriate action based on the available
* kernel functions to release block device.
*
* @bd: block device structure pointer to be released.
*
* Return:
* void.
*/
void dattobd_blkdev_put(struct block_device *bd)
{
#if defined HAVE_BLKDEV_PUT_1
return blkdev_put(bd);

#elif defined HAVE_BLKDEV_PUT_2
return blkdev_put(bd,NULL);

#else
return blkdev_put(bd, FMODE_READ);
#endif
}
25 changes: 7 additions & 18 deletions src/blkdev.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,6 @@

struct block_device;

#ifdef HAVE_BLKDEV_PUT_1
//#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,28)
#define dattobd_blkdev_put(bdev) blkdev_put(bdev);
#else
#define dattobd_blkdev_put(bdev) blkdev_put(bdev, FMODE_READ);
#endif

#ifndef bdev_whole
//#if LINUX_VERSION_CODE < KERNEL_VERSION(5,11,0)
#define bdev_whole(bdev) ((bdev)->bd_contains)
Expand All @@ -33,18 +26,14 @@ struct block_device;
#define dattobd_bdev_size(bdev) part_nr_sects_read((bdev)->bd_part)
#endif

#ifndef HAVE_BLKDEV_GET_BY_PATH
//#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,38)
struct block_device *blkdev_get_by_path(const char *path, fmode_t mode,

struct block_device *dattodb_blkdev_by_path(const char *path, fmode_t mode,
void *holder);
#endif

#ifdef HAVE_BD_SUPER
#define dattobd_get_super(bdev) (bdev)->bd_super
#define dattobd_drop_super(sb)
#else
#define dattobd_get_super(bdev) get_super(bdev)
#define dattobd_drop_super(sb) drop_super(sb)
#endif
struct super_block *dattobd_get_super(struct block_device * bd);

void dattobd_drop_super(struct super_block *sb);

void dattobd_blkdev_put(struct block_device *bd);

#endif /* BLKDEV_H_ */
14 changes: 14 additions & 0 deletions src/configure-tests/feature-tests/bd_has_submit_bio.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// SPDX-License-Identifier: GPL-2.0-only

/*
* Copyright (C) 2024 Datto Inc.
*/

#include "includes.h"

MODULE_LICENSE("GPL");

static inline void dummy(void){
struct block_device* bd;
bd->bd_has_submit_bio=false;
}
30 changes: 30 additions & 0 deletions src/configure-tests/feature-tests/bdops_open_with_blk_mode.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// SPDX-License-Identifier: GPL-2.0-only

/*
* Copyright (C) 2024 Datto Inc.
*/

#include "includes.h"

MODULE_LICENSE("GPL");

static int snap_open(struct gendisk *gd, blk_mode_t mode){
(void)gd;
(void)mode;
return 0;
}

static void snap_release(struct gendisk *gd){
(void)gd;
}

static inline void dummy(void){
struct gendisk gd;
struct block_device_operations bdo = {
.open = snap_open,
.release = snap_release,
};

bdo.open(&gd, FMODE_READ);
bdo.release(&gd);
}
14 changes: 14 additions & 0 deletions src/configure-tests/feature-tests/blkdev_get_by_path_4.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// SPDX-License-Identifier: GPL-2.0-only

/*
* Copyright (C) 2024 Datto Inc.
*/

#include "includes.h"

MODULE_LICENSE("GPL");

static inline void dummy(void){
struct block_device *bd = blkdev_get_by_path("path", FMODE_READ, NULL, NULL);
bd = NULL;
}
15 changes: 15 additions & 0 deletions src/configure-tests/feature-tests/blkdev_put_2.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// SPDX-License-Identifier: GPL-2.0-only

/*
* Copyright (C) 2024 Datto Inc.
*/

#include "includes.h"

MODULE_LICENSE("GPL");

static inline void dummy(void){
struct block_device dev;
void* info;
blkdev_put(&dev,info);
}
2 changes: 1 addition & 1 deletion src/configure-tests/feature-tests/gd_owns_queue.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,6 @@
MODULE_LICENSE("GPL");

static inline void dummy(void){
struct gendisk *sd_gd; = NULL;
struct gendisk *sd_gd = NULL;
set_bit(GD_OWNS_QUEUE, &sd_gd->state);
}
14 changes: 14 additions & 0 deletions src/configure-tests/feature-tests/get_super.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// SPDX-License-Identifier: GPL-2.0-only

/*
* Copyright (C) 2024 Datto Inc.
*/

#include "includes.h"

MODULE_LICENSE("GPL");

static inline void dummy(void){
struct block_device bdev;
get_super(&bdev);
}
Loading