summaryrefslogtreecommitdiff
path: root/include/uapi/linux/nfs.h
blob: 946cb62d64b0b87805e9ae0e4ff4cafb40335d5b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
/*
 * NFS protocol definitions
 *
 * This file contains constants mostly for Version 2 of the protocol,
 * but also has a couple of NFSv3 bits in (notably the error codes).
 */
#ifndef _UAPI_LINUX_NFS_H
#define _UAPI_LINUX_NFS_H

#include <linux/types.h>

#define NFS_PROGRAM	100003
#define NFS_PORT	2049
#define NFS_RDMA_PORT	20049
#define NFS_MAXDATA	8192
#define NFS_MAXPATHLEN	1024
#define NFS_MAXNAMLEN	255
#define NFS_MAXGROUPS	16
#define NFS_FHSIZE	32
#define NFS_COOKIESIZE	4
#define NFS_FIFO_DEV	(-1)
#define NFSMODE_FMT	0170000
#define NFSMODE_DIR	0040000
#define NFSMODE_CHR	0020000
#define NFSMODE_BLK	0060000
#define NFSMODE_REG	0100000
#define NFSMODE_LNK	0120000
#define NFSMODE_SOCK	0140000
#define NFSMODE_FIFO	0010000

#define NFS_MNT_PROGRAM		100005
#define NFS_MNT_VERSION		1
#define NFS_MNT3_VERSION	3

#define NFS_PIPE_DIRNAME "nfs"

/*
 * NFS stats. The good thing with these values is that NFSv3 errors are
 * a superset of NFSv2 errors (with the exception of NFSERR_WFLUSH which
 * no-one uses anyway), so we can happily mix code as long as we make sure
 * no NFSv3 errors are returned to NFSv2 clients.
 * Error codes that have a `--' in the v2 column are not part of the
 * standard, but seem to be widely used nevertheless.
 */
 enum nfs_stat {
	NFS_OK = 0,			/* v2 v3 v4 */
	NFSERR_PERM = 1,		/* v2 v3 v4 */
	NFSERR_NOENT = 2,		/* v2 v3 v4 */
	NFSERR_IO = 5,			/* v2 v3 v4 */
	NFSERR_NXIO = 6,		/* v2 v3 v4 */
	NFSERR_EAGAIN = 11,		/* v2 v3 */
	NFSERR_ACCES = 13,		/* v2 v3 v4 */
	NFSERR_EXIST = 17,		/* v2 v3 v4 */
	NFSERR_XDEV = 18,		/*    v3 v4 */
	NFSERR_NODEV = 19,		/* v2 v3 v4 */
	NFSERR_NOTDIR = 20,		/* v2 v3 v4 */
	NFSERR_ISDIR = 21,		/* v2 v3 v4 */
	NFSERR_INVAL = 22,		/* v2 v3 v4 */
	NFSERR_FBIG = 27,		/* v2 v3 v4 */
	NFSERR_NOSPC = 28,		/* v2 v3 v4 */
	NFSERR_ROFS = 30,		/* v2 v3 v4 */
	NFSERR_MLINK = 31,		/*    v3 v4 */
	NFSERR_OPNOTSUPP = 45,		/* v2 v3 */
	NFSERR_NAMETOOLONG = 63,	/* v2 v3 v4 */
	NFSERR_NOTEMPTY = 66,		/* v2 v3 v4 */
	NFSERR_DQUOT = 69,		/* v2 v3 v4 */
	NFSERR_STALE = 70,		/* v2 v3 v4 */
	NFSERR_REMOTE = 71,		/* v2 v3 */
	NFSERR_WFLUSH = 99,		/* v2    */
	NFSERR_BADHANDLE = 10001,	/*    v3 v4 */
	NFSERR_NOT_SYNC = 10002,	/*    v3 */
	NFSERR_BAD_COOKIE = 10003,	/*    v3 v4 */
	NFSERR_NOTSUPP = 10004,		/*    v3 v4 */
	NFSERR_TOOSMALL = 10005,	/*    v3 v4 */
	NFSERR_SERVERFAULT = 10006,	/*    v3 v4 */
	NFSERR_BADTYPE = 10007,		/*    v3 v4 */
	NFSERR_JUKEBOX = 10008,		/*    v3 v4 */
	NFSERR_SAME = 10009,		/*       v4 */
	NFSERR_DENIED = 10010,		/*       v4 */
	NFSERR_EXPIRED = 10011,		/*       v4 */
	NFSERR_LOCKED = 10012,		/*       v4 */
	NFSERR_GRACE = 10013,		/*       v4 */
	NFSERR_FHEXPIRED = 10014,	/*       v4 */
	NFSERR_SHARE_DENIED = 10015,	/*       v4 */
	NFSERR_WRONGSEC = 10016,	/*       v4 */
	NFSERR_CLID_INUSE = 10017,	/*       v4 */
	NFSERR_RESOURCE = 10018,	/*       v4 */
	NFSERR_MOVED = 10019,		/*       v4 */
	NFSERR_NOFILEHANDLE = 10020,	/*       v4 */
	NFSERR_MINOR_VERS_MISMATCH = 10021,   /* v4 */
	NFSERR_STALE_CLIENTID = 10022,	/*       v4 */
	NFSERR_STALE_STATEID = 10023,   /*       v4 */
	NFSERR_OLD_STATEID = 10024,     /*       v4 */
	NFSERR_BAD_STATEID = 10025,     /*       v4 */  
	NFSERR_BAD_SEQID = 10026,	/*       v4 */
	NFSERR_NOT_SAME = 10027,	/*       v4 */
	NFSERR_LOCK_RANGE = 10028,	/*       v4 */
	NFSERR_SYMLINK = 10029,		/*       v4 */
	NFSERR_RESTOREFH = 10030,	/*       v4 */
	NFSERR_LEASE_MOVED = 10031,	/*       v4 */
	NFSERR_ATTRNOTSUPP = 10032,	/*       v4 */
	NFSERR_NO_GRACE = 10033,	/*       v4 */
	NFSERR_RECLAIM_BAD = 10034,	/*       v4 */
	NFSERR_RECLAIM_CONFLICT = 10035,/*       v4 */
	NFSERR_BAD_XDR = 10036,		/*       v4 */
	NFSERR_LOCKS_HELD = 10037,	/*       v4 */
	NFSERR_OPENMODE = 10038,       /*       v4 */
	NFSERR_BADOWNER = 10039,       /*       v4 */
	NFSERR_BADCHAR = 10040,        /*       v4 */
	NFSERR_BADNAME = 10041,        /*       v4 */
	NFSERR_BAD_RANGE = 10042,      /*       v4 */
	NFSERR_LOCK_NOTSUPP = 10043,   /*       v4 */
	NFSERR_OP_ILLEGAL = 10044,     /*       v4 */
	NFSERR_DEADLOCK = 10045,       /*       v4 */
	NFSERR_FILE_OPEN = 10046,      /*       v4 */
	NFSERR_ADMIN_REVOKED = 10047,  /*       v4 */
	NFSERR_CB_PATH_DOWN = 10048,   /*       v4 */
};

/* NFSv2 file types - beware, these are not the same in NFSv3 */

enum nfs_ftype {
	NFNON = 0,
	NFREG = 1,
	NFDIR = 2,
	NFBLK = 3,
	NFCHR = 4,
	NFLNK = 5,
	NFSOCK = 6,
	NFBAD = 7,
	NFFIFO = 8
};

#endif /* _UAPI_LINUX_NFS_H */
_((__packed__)), immediately after the 'union' keyword. This commit allows the 'union' keyword to be followed by attributes. Signed-off-by: Masahiro Yamada <masahiroy@kernel.org> Acked-by: Nicolas Schier <n.schier@avm.de> 2025-01-18genksyms: fix syntax error for attribute after 'struct'Masahiro Yamada A longstanding issue with genksyms is that it has hidden syntax errors. When a syntax error occurs, yyerror() is called. However, error_with_pos() is a no-op unless the -w option is provided. You can observe syntax errors by manually passing the -w option. For example, with CONFIG_MODVERSIONS=y on v6.13-rc1: $ make -s KCFLAGS=-D__GENKSYMS__ arch/x86/kernel/cpu/mshyperv.i $ cat arch/x86/kernel/cpu/mshyperv.i | scripts/genksyms/genksyms -w [ snip ] ./arch/x86/include/asm/svm.h:122: syntax error The syntax error occurs in the following code in arch/x86/include/asm/svm.h: struct __attribute__ ((__packed__)) vmcb_control_area { [ snip ] }; The issue arises from __attribute__ immediately after the 'struct' keyword. This commit allows the 'struct' keyword to be followed by attributes. The lexer must be adjusted because dont_want_brace_phase should not be decremented while processing attributes. Signed-off-by: Masahiro Yamada <masahiroy@kernel.org> Acked-by: Nicolas Schier <n.schier@avm.de> 2025-01-18genksyms: fix syntax error for attribute after abstact_declaratorMasahiro Yamada A longstanding issue with genksyms is that it has hidden syntax errors. When a syntax error occurs, yyerror() is called. However, error_with_pos() is a no-op unless the -w option is provided. You can observe syntax errors by manually passing the -w option. For example, with CONFIG_MODVERSIONS=y on v6.13-rc1: $ make -s KCFLAGS=-D__GENKSYMS__ kernel/module/main.i $ cat kernel/module/main.i | scripts/genksyms/genksyms -w [ snip ] kernel/module/main.c:97: syntax error The syntax error occurs in the following code in kernel/module/main.c: static void __mod_update_bounds(enum mod_mem_type type __maybe_unused, void *base, unsigned int size, struct mod_tree_root *tree) { [ snip ] } The issue arises from __maybe_unused, which is defined as __attribute__((__unused__)). This commit allows direct_abstract_declarator to be followed with attributes. Signed-off-by: Masahiro Yamada <masahiroy@kernel.org> Acked-by: Nicolas Schier <n.schier@avm.de> 2025-01-18genksyms: fix syntax error for attribute before nested_declaratorMasahiro Yamada A longstanding issue with genksyms is that it has hidden syntax errors. When a syntax error occurs, yyerror() is called. However, error_with_pos() is a no-op unless the -w option is provided. You can observe syntax errors by manually passing the -w option. For example, with CONFIG_MODVERSIONS=y on v6.13-rc1: $ make -s KCFLAGS=-D__GENKSYMS__ drivers/acpi/prmt.i $ cat drivers/acpi/prmt.i | scripts/genksyms/genksyms -w [ snip ] drivers/acpi/prmt.c:56: syntax error The syntax error occurs in the following code in drivers/acpi/prmt.c: struct prm_handler_info { [ snip ] efi_status_t (__efiapi *handler_addr)(u64, void *); [ snip ] }; The issue arises from __efiapi, which is defined as either __attribute__((ms_abi)) or __attribute__((regparm(0))). This commit allows nested_declarator to be prefixed with attributes. Signed-off-by: Masahiro Yamada <masahiroy@kernel.org> Acked-by: Nicolas Schier <n.schier@avm.de> 2025-01-18genksyms: fix syntax error for attribute before abstract_declaratorMasahiro Yamada A longstanding issue with genksyms is that it has hidden syntax errors. When a syntax error occurs, yyerror() is called. However, error_with_pos() is a no-op unless the -w option is provided. You can observe syntax errors by manually passing the -w option. For example, with CONFIG_MODVERSIONS=y on v6.13-rc1: $ make -s KCFLAGS=-D__GENKSYMS__ init/main.i $ cat init/main.i | scripts/genksyms/genksyms -w [ snip ] ./include/linux/efi.h:1225: syntax error The syntax error occurs in the following code in include/linux/efi.h: efi_status_t efi_call_acpi_prm_handler(efi_status_t (__efiapi *handler_addr)(u64, void *), u64 param_buffer_addr, void *context); The issue arises from __efiapi, which is defined as either __attribute__((ms_abi)) or __attribute__((regparm(0))). This commit allows abstract_declarator to be prefixed with attributes. To avoid conflicts, I tweaked the rule for decl_specifier_seq. Due to this change, a standalone attribute cannot become decl_specifier_seq. Otherwise, I do not know how to resolve the conflicts. The following code, which was previously accepted by genksyms, will now result in a syntax error: void my_func(__attribute__((unused))x); I do not think it is a big deal because GCC also fails to parse it. $ echo 'void my_func(__attribute__((unused))x);' | gcc -c -x c - <stdin>:1:37: error: unknown type name 'x' Signed-off-by: Masahiro Yamada <masahiroy@kernel.org> Acked-by: Nicolas Schier <n.schier@avm.de> 2025-01-18genksyms: decouple ATTRIBUTE_PHRASE from type-qualifierMasahiro Yamada The __attribute__ keyword can appear in more contexts than 'const' or 'volatile'. To avoid grammatical conflicts with future changes, ATTRIBUTE_PHRASE should not be reduced into type_qualifier. No functional changes are intended. Signed-off-by: Masahiro Yamada <masahiroy@kernel.org> Acked-by: Nicolas Schier <n.schier@avm.de> 2025-01-18genksyms: record attributes consistently for init-declaratorMasahiro Yamada I believe the missing action here is a bug. For rules with no explicit action, the following default is used: { $$ = $1; } However, in this case, $1 is the value of attribute_opt itself. As a result, the value of attribute_opt is always NULL. The following test code demonstrates inconsistent behavior. int x __attribute__((__aligned__(4))); int y __attribute__((__aligned__(4))) = 0; The attribute is recorded only when followed by an initializer. This commit adds the correct action to propagate the value of the ATTRIBUTE_PHRASE token. With this change, the attribute in the example above is consistently recorded for both 'x' and 'y'. [Before] $ cat <<EOF | scripts/genksyms/genksyms -d int x __attribute__((__aligned__(4))); int y __attribute__((__aligned__(4))) = 0; EOF Defn for type0 x == <int x > Defn for type0 y == <int y __attribute__ ( ( __aligned__ ( 4 ) ) ) > Hash table occupancy 2/4096 = 0.000488281 [After] $ cat <<EOF | scripts/genksyms/genksyms -d int x __attribute__((__aligned__(4))); int y __attribute__((__aligned__(4))) = 0; EOF Defn for type0 x == <int x __attribute__ ( ( __aligned__ ( 4 ) ) ) > Defn for type0 y == <int y __attribute__ ( ( __aligned__ ( 4 ) ) ) > Hash table occupancy 2/4096 = 0.000488281 Signed-off-by: Masahiro Yamada <masahiroy@kernel.org> Acked-by: Nicolas Schier <n.schier@avm.de> 2025-01-18genksyms: restrict direct-declarator to take one parameter-type-listMasahiro Yamada Similar to the previous commit, this change makes the parser logic a little more accurate. Currently, genksyms accepts the following invalid code: struct foo { int (*callback)(int)(int)(int); }; A direct-declarator should not recursively absorb multiple ( parameter-type-list ) constructs. In the example above, (*callback) should be followed by at most one (int). Signed-off-by: Masahiro Yamada <masahiroy@kernel.org> Acked-by: Nicolas Schier <n.schier@avm.de> 2025-01-18genksyms: restrict direct-abstract-declarator to take one parameter-type-listMasahiro Yamada While there is no more grammatical ambiguity in genksyms, the parser logic is still inaccurate. For example, genksyms accepts the following invalid C code: void my_func(int ()(int)); This should result in a syntax error because () cannot be reduced to <direct-abstract-declarator>. ( <abstract-declarator> ) can be reduced, but <abstract-declarator> must not be empty in the following grammar from K&R [1]: <direct-abstract-declarator> ::= ( <abstract-declarator> ) | {<direct-abstract-declarator>}? [ {<constant-expression>}? ] | {<direct-abstract-declarator>}? ( {<parameter-type-list>}? ) Furthermore, genksyms accepts the following weird code: void my_func(int (*callback)(int)(int)(int)); The parser allows <direct-abstract-declarator> to recursively absorb multiple ( {<parameter-type-list>}? ), but this behavior is incorrect. In the example above, (*callback) should be followed by at most one (int). [1]: https://cs.wmich.edu/~gupta/teaching/cs4850/sumII06/The%20syntax%20of%20C%20in%20Backus-Naur%20form.htm Signed-off-by: Masahiro Yamada <masahiroy@kernel.org> Acked-by: Nicolas Schier <n.schier@avm.de> 2025-01-18genksyms: remove Makefile hackMasahiro Yamada This workaround was introduced for suppressing the reduce/reduce conflict warnings because the %expect-rr directive, which is applicable only to GLR parsers, cannot be used for genksyms. Since there are no longer any conflicts, this Makefile hack is now unnecessary. Signed-off-by: Masahiro Yamada <masahiroy@kernel.org> Acked-by: Nicolas Schier <n.schier@avm.de> 2025-01-18genksyms: fix last 3 shift/reduce conflictsMasahiro Yamada The genksyms parser has ambiguities in its grammar, which are currently suppressed by a workaround in scripts/genksyms/Makefile. Building genksyms with W=1 generates the following warnings: YACC scripts/genksyms/parse.tab.[ch] scripts/genksyms/parse.y: warning: 3 shift/reduce conflicts [-Wconflicts-sr] scripts/genksyms/parse.y: note: rerun with option '-Wcounterexamples' to generate conflict counterexamples The ambiguity arises when decl_specifier_seq is followed by '(' because the following two interpretations are possible: - decl_specifier_seq direct_abstract_declarator '(' parameter_declaration_clause ')' - decl_specifier_seq '(' abstract_declarator ')' This issue occurs because the current parser allows an empty string to be reduced to direct_abstract_declarator, which is incorrect. K&R [1] explains the correct grammar: <parameter-declaration> ::= {<declaration-specifier>}+ <declarator> | {<declaration-specifier>}+ <abstract-declarator> | {<declaration-specifier>}+ <abstract-declarator> ::= <pointer> | <pointer> <direct-abstract-declarator> | <direct-abstract-declarator> <direct-abstract-declarator> ::= ( <abstract-declarator> ) | {<direct-abstract-declarator>}? [ {<constant-expression>}? ] | {<direct-abstract-declarator>}? ( {<parameter-type-list>}? ) This commit resolves all remaining conflicts. We need to consider the difference between the following two examples: [Example 1] ( <abstract-declarator> ) can become <direct-abstract-declarator> void my_func(int (foo)); ... is equivalent to: void my_func(int foo); [Example 2] ( <parameter-type-list> ) can become <direct-abstract-declarator> typedef int foo; void my_func(int (foo)); ... is equivalent to: void my_func(int (*callback)(int)); Please note that the function declaration is identical in both examples, but the preceding typedef creates the distinction. I introduced a new term, open_paren, to enable the type lookup immediately after the '(' token. Without this, we cannot distinguish between [Example 1] and [Example 2]. [1]: https://cs.wmich.edu/~gupta/teaching/cs4850/sumII06/The%20syntax%20of%20C%20in%20Backus-Naur%20form.htm Signed-off-by: Masahiro Yamada <masahiroy@kernel.org> Acked-by: Nicolas Schier <n.schier@avm.de> 2025-01-18genksyms: fix 6 shift/reduce conflicts and 5 reduce/reduce conflictsMasahiro Yamada The genksyms parser has ambiguities in its grammar, which are currently suppressed by a workaround in scripts/genksyms/Makefile. Building genksyms with W=1 generates the following warnings: YACC scripts/genksyms/parse.tab.[ch] scripts/genksyms/parse.y: warning: 9 shift/reduce conflicts [-Wconflicts-sr] scripts/genksyms/parse.y: warning: 5 reduce/reduce conflicts [-Wconflicts-rr] scripts/genksyms/parse.y: note: rerun with option '-Wcounterexamples' to generate conflict counterexamples The comment in the parser describes the current problem: /* This wasn't really a typedef name but an identifier that shadows one. */ Consider the following simple C code: typedef int foo; void my_func(foo foo) {} In the function parameter list (foo foo), the first 'foo' is a type specifier (typedef'ed as 'int'), while the second 'foo' is an identifier. However, the lexer cannot distinguish between the two. Since 'foo' is already typedef'ed, the lexer returns TYPE for both instances, instead of returning IDENT for the second one. To support shadowed identifiers, TYPE can be reduced to either a simple_type_specifier or a direct_abstract_declarator, which creates a grammatical ambiguity. Without analyzing the grammar context, it is very difficult to resolve this correctly. This commit introduces a flag, dont_want_type_specifier, which allows the parser to inform the lexer whether an identifier is expected. When dont_want_type_specifier is true, the type lookup is suppressed, and the lexer returns IDENT regardless of any preceding typedef. After this commit, only 3 shift/reduce conflicts will remain. Signed-off-by: Masahiro Yamada <masahiroy@kernel.org> Acked-by: Nicolas Schier <n.schier@avm.de> 2025-01-18genksyms: reduce type_qualifier directly to decl_specifierMasahiro Yamada A type_qualifier (const, volatile, etc.) is not a type_specifier. According to K&R [1], a type-qualifier should be directly reduced to a declaration-specifier. <declaration-specifier> ::= <storage-class-specifier> | <type-specifier> | <type-qualifier> [1]: https://cs.wmich.edu/~gupta/teaching/cs4850/sumII06/The%20syntax%20of%20C%20in%20Backus-Naur%20form.htm Signed-off-by: Masahiro Yamada <masahiroy@kernel.org> Acked-by: Nicolas Schier <n.schier@avm.de> 2025-01-18genksyms: rename cvar_qualifier to type_qualifierMasahiro Yamada I believe "cvar" stands for "Const, Volatile, Attribute, or Restrict". This is called "type-qualifier" in K&R. [1] Adopt this more generic naming. No functional changes are intended. [1] https://cs.wmich.edu/~gupta/teaching/cs4850/sumII06/The%20syntax%20of%20C%20in%20Backus-Naur%20form.htm Signed-off-by: Masahiro Yamada <masahiroy@kernel.org> Acked-by: Nicolas Schier <n.schier@avm.de> 2025-01-18genksyms: rename m_abstract_declarator to abstract_declaratorMasahiro Yamada This is called "abstract-declarator" in K&R. [1] I am not sure what "m_" stands for, but the name is clear enough without it. No functional changes are intended. [1] https://cs.wmich.edu/~gupta/teaching/cs4850/sumII06/The%20syntax%20of%20C%20in%20Backus-Naur%20form.htm Signed-off-by: Masahiro Yamada <masahiroy@kernel.org> Acked-by: Nicolas Schier <n.schier@avm.de> 2025-01-10genksyms: use uint32_t instead of unsigned long for calculating CRCMasahiro Yamada Currently, 'unsigned long' is used for intermediate variables when calculating CRCs. The size of 'long' differs depending on the architecture: it is 32 bits on 32-bit architectures and 64 bits on 64-bit architectures. The CRC values generated by genksyms represent the compatibility of exported symbols. Therefore, reproducibility is important. In other words, we need to ensure that the output is the same when the kernel source is identical, regardless of whether genksyms is running on a 32-bit or 64-bit build machine. Fortunately, the output from genksyms is not affected by the build machine's architecture because only the lower 32 bits of the 'unsigned long' variables are used. To make it even clearer that the CRC calculation is independent of the build machine's architecture, this commit explicitly uses the fixed-width type, uint32_t. Signed-off-by: Masahiro Yamada <masahiroy@kernel.org> 2025-01-10genksyms: use generic macros for hash table implementationMasahiro Yamada Use macros provided by hashtable.h Signed-off-by: Masahiro Yamada <masahiroy@kernel.org> 2025-01-10genksyms: refactor the return points in the for-loop in __add_symbol()Masahiro Yamada free_list() must be called before returning from this for-loop. Swap 'break' and the combination of free_list() and 'return'. This reduces the code and minimizes the risk of introducing memory leaks in future changes. Signed-off-by: Masahiro Yamada <masahiroy@kernel.org> 2025-01-10genksyms: reduce the indentation in the for-loop in __add_symbol()Masahiro Yamada To improve readability, reduce the indentation as follows: - Use 'continue' earlier when the symbol does not match - flip !sym->is_declared to flatten the if-else chain No functional changes are intended. Signed-off-by: Masahiro Yamada <masahiroy@kernel.org> 2025-01-10genksyms: fix memory leak when the same symbol is read from *.symref fileMasahiro Yamada When a symbol that is already registered is read again from *.symref file, __add_symbol() removes the previous one from the hash table without freeing it. [Test Case] $ cat foo.c #include <linux/export.h> void foo(void); void foo(void) {} EXPORT_SYMBOL(foo); $ cat foo.symref foo void foo ( void ) foo void foo ( void ) When a symbol is removed from the hash table, it must be freed along with its ->name and ->defn members. However, sym->name cannot be freed because it is sometimes shared with node->string, but not always. If sym->name and node->string share the same memory, free(sym->name) could lead to a double-free bug. To resolve this issue, always assign a strdup'ed string to sym->name. Fixes: 64e6c1e12372 ("genksyms: track symbol checksum changes") Signed-off-by: Masahiro Yamada <masahiroy@kernel.org> 2025-01-10genksyms: fix memory leak when the same symbol is added from sourceMasahiro Yamada When a symbol that is already registered is added again, __add_symbol() returns without freeing the symbol definition, making it unreachable. The following test cases demonstrate different memory leak points. [Test Case 1] Forward declaration with exactly the same definition $ cat foo.c #include <linux/export.h> void foo(void); void foo(void) {} EXPORT_SYMBOL(foo); [Test Case 2] Forward declaration with a different definition (e.g. attribute) $ cat foo.c #include <linux/export.h> void foo(void); __attribute__((__section__(".ref.text"))) void foo(void) {} EXPORT_SYMBOL(foo); [Test Case 3] Preserving an overridden symbol (compile with KBUILD_PRESERVE=1) $ cat foo.c #include <linux/export.h> void foo(void); void foo(void) { } EXPORT_SYMBOL(foo); $ cat foo.symref override foo void foo ( int ) The memory leaks in Test Case 1 and 2 have existed since the introduction of genksyms into the kernel tree. [1] The memory leak in Test Case 3 was introduced by commit 5dae9a550a74 ("genksyms: allow to ignore symbol checksum changes"). When multiple init_declarators are reduced to an init_declarator_list, the decl_spec must be duplicated. Otherwise, the following Test Case 4 would result in a double-free bug. [Test Case 4] $ cat foo.c #include <linux/export.h> extern int foo, bar; int foo, bar; EXPORT_SYMBOL(foo); In this case, 'foo' and 'bar' share the same decl_spec, 'int'. It must be unshared before being passed to add_symbol(). [1]: https://git.kernel.org/pub/scm/linux/kernel/git/history/history.git/commit/?id=46bd1da672d66ccd8a639d3c1f8a166048cca608 Fixes: 5dae9a550a74 ("genksyms: allow to ignore symbol checksum changes") Signed-off-by: Masahiro Yamada <masahiroy@kernel.org> 2024-11-28genksyms: reduce indentation in export_symbol()Masahiro Yamada Modify this function to return earlier when find_symbol() returns NULL, reducing the level of improve readability. No functional changes are intended. Signed-off-by: Masahiro Yamada <masahiroy@kernel.org> 2024-05-10kbuild: use $(src) instead of $(srctree)/$(src) for source directoryMasahiro Yamada Kbuild conventionally uses $(obj)/ for generated files, and $(src)/ for checked-in source files. It is merely a convention without any functional difference. In fact, $(obj) and $(src) are exactly the same, as defined in scripts/Makefile.build: src := $(obj) When the kernel is built in a separate output directory, $(src) does not accurately reflect the source directory location. While Kbuild resolves this discrepancy by specifying VPATH=$(srctree) to search for source files, it does not cover all cases. For example, when adding a header search path for local headers, -I$(srctree)/$(src) is typically passed to the compiler. This introduces inconsistency between upstream and downstream Makefiles because $(src) is used instead of $(srctree)/$(src) for the latter. To address this inconsistency, this commit changes the semantics of $(src) so that it always points to the directory in the source tree. Going forward, the variables used in Makefiles will have the following meanings: $(obj) - directory in the object tree $(src) - directory in the source tree (changed by this commit) $(objtree) - the top of the kernel object tree $(srctree) - the top of the kernel source tree Consequently, $(srctree)/$(src) in upstream Makefiles need to be replaced with $(src). Signed-off-by: Masahiro Yamada <masahiroy@kernel.org> Reviewed-by: Nicolas Schier <nicolas@fjasle.eu> 2023-11-28genksyms: use getopt_long() unconditionallyMasahiro Yamada getopt_long() is used by various tools in the kernel (e.g. Kconfig). It should be fine to use it all the time. Signed-off-by: Masahiro Yamada <masahiroy@kernel.org> 2023-11-28genksyms: remove the remnant of the -s optionMasahiro Yamada Commit 74d931716151 ("genksyms: remove symbol prefix support") removed the -s (--symbol-prefix) option. Clean up the left-over. Signed-off-by: Masahiro Yamada <masahiroy@kernel.org>