Search code examples
cpointersstrcmpincomplete-type

Passing argument 1 of 'strcmp' from incompatible pointer type


I'm aware that these questions are asked all of the time, however in this scenario I'm not quite sure what the proper solution would be. The function is an edited function of do_new_mount in a fork of the 3.4.x linux kernel for context. The intended purpose is to check against the type of filesystem and in turn issue the async flag if the correct conditions are meant.

The line:

if (!err && ((!strcmp(type, "ext4") &&

Full function (async part is added, which is causing the error):

static int do_new_mount(struct path *path, const char *fstype, int flags,
            int mnt_flags, const char *name, void *data)
{
struct file_system_type *type;
struct user_namespace *user_ns;
struct vfsmount *mnt;
int err;

if (!fstype)
    return -EINVAL;

/* we need capabilities... */
user_ns = real_mount(path->mnt)->mnt_ns->user_ns;
if (!ns_capable(user_ns, CAP_SYS_ADMIN))
    return -EPERM;

type = get_fs_type(fstype);
if (!type)
    return -ENODEV;

if (user_ns != &init_user_ns) {
    if (!(type->fs_flags & FS_USERNS_MOUNT)) {
        put_filesystem(type);
        return -EPERM;
    }
    /* Only in special cases allow devices from mounts
     * created outside the initial user namespace.
     */
    if (!(type->fs_flags & FS_USERNS_DEV_MOUNT)) {
        flags |= MS_NODEV;
        mnt_flags |= MNT_NODEV;
    }
}

mnt = vfs_kern_mount(type, flags, name, data);
if (!IS_ERR(mnt) && (type->fs_flags & FS_HAS_SUBTYPE) &&
    !mnt->mnt_sb->s_subtype)
    mnt = fs_set_subtype(mnt, fstype);

put_filesystem(type);
if (IS_ERR(mnt))
    return PTR_ERR(mnt);

err = do_add_mount(real_mount(mnt), path, mnt_flags);
if (err)
    mntput(mnt);
#ifdef CONFIG_ASYNC_FSYNC
if (!err && ((!strcmp(type, "ext4") &&
    !strcmp(path->dentry->d_name.name, "data")) ||
    (!strcmp(type, "fuse") &&
    !strcmp(path->dentry->d_name.name, "emulated"))))
            mnt->mnt_sb->fsync_flags |= FLAG_ASYNC_FSYNC;
#endif
return err;
}

Solution

  • Obviously type is of type struct file_system_type * which is not what strcmp() is expecting. I'm guessing that the first field in struct file_system_type is a char* and so it works.

    The solution would be either cast type to a char* OR properly dereference it's first member. (obviously the 2nd approach is better)