On Fri, 2025-10-24 at 22:59 +0530, Ally Heev wrote:
> pointers with __free attribute initialized to NULL
> pose potential cleanup issues [1] when a function uses
> interdependent variables with cleanup attributes
>
> Link: https://docs.kernel.org/core-api/cleanup.html [1]
> Link:
> https://lore.kernel.org/all/[email protected]/
> Suggested-by: Dan Williams <[email protected]>
> Signed-off-by: Ally Heev <[email protected]>
[]
> diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl
[]
> @@ -7728,6 +7728,12 @@ sub process {
> ERROR("UNINITIALIZED_PTR_WITH_FREE",
> "pointer '$1' with __free attribute should be
> initialized\n" . $herecurr);
> }
> +
> +# check for pointers with __free attribute initialized to NULL
> + while ($line =~ /\*\s*($Ident)\s+$FreeAttribute\s*=\s*NULL\b/g)
> {
> + WARN("NULL_INITIALIZED_PTR_WITH_FREE",
> + "pointer '$1' with __free attribute should be
> initialized to a non-NULL address\n" . $herecurr);
> + }
> }
I think this a poor idea as almost all the instances where this
initialization is done are fine.
And there are a lot of them.
$ git grep -P '\b__free\b.*=\s*NULL\s*;' | wc -l
490
And what about these uses that depend on struct path members
.mnt and .dentry being NULL.
$ git grep -P '\b__free\b.*=\s*\{.*\}\s*;'
fs/configfs/symlink.c: struct path path __free(path_put) = {};
fs/fhandle.c: struct path path __free(path_put) = {};
fs/file_attr.c: struct path filepath __free(path_put) = {};
fs/file_attr.c: struct path filepath __free(path_put) = {};
fs/namei.c: struct path parent_path __free(path_put) = {};
fs/namei.c: struct path parent_path __free(path_put) = {};
fs/namespace.c: struct path old_path __free(path_put) = {};
fs/namespace.c: struct path path __free(path_put) = {};
fs/namespace.c: struct path old_path __free(path_put) = {};
fs/namespace.c: struct path path __free(path_put) = {};
fs/namespace.c: struct path to_path __free(path_put) = {};
fs/namespace.c: struct path from_path __free(path_put) = {};
fs/namespace.c: struct path new __free(path_put) = {};
fs/namespace.c: struct path old __free(path_put) = {};
fs/namespace.c: struct path root __free(path_put) = {};
fs/namespace.c: struct klistmount kls __free(klistmount_free) = {};
fs/namespace.c: struct path fs_root __free(path_put) = {};
fs/nsfs.c: struct path path __free(path_put) = {};
fs/nsfs.c: struct path path __free(path_put) = {};
fs/nsfs.c: struct path path __free(path_put) = {};
fs/overlayfs/params.c: struct path layer_path __free(path_put) = {};
fs/overlayfs/params.c: struct path path __free(path_put) = {};
fs/pidfs.c: struct path path __free(path_put) = {};
include/linux/path.h: * struct path path __free(path_put) = {};
kernel/acct.c: struct path internal __free(path_put) = {}; // in that order
kernel/trace/trace_uprobe.c: struct path path __free(path_put) = {};