License cleanup: add SPDX GPL-2.0 license identifier to files with no license
Many source files in the tree are missing licensing information, which
makes it harder for compliance tools to determine the correct license.
By default all files without license information are under the default
license of the kernel, which is GPL version 2.
Update the files which contain no license information with the 'GPL-2.0'
SPDX license identifier. The SPDX identifier is a legally binding
shorthand, which can be used instead of the full boiler plate text.
This patch is based on work done by Thomas Gleixner and Kate Stewart and
Philippe Ombredanne.
How this work was done:
Patches were generated and checked against linux-4.14-rc6 for a subset of
the use cases:
- file had no licensing information it it.
- file was a */uapi/* one with no licensing information in it,
- file was a */uapi/* one with existing licensing information,
Further patches will be generated in subsequent months to fix up cases
where non-standard license headers were used, and references to license
had to be inferred by heuristics based on keywords.
The analysis to determine which SPDX License Identifier to be applied to
a file was done in a spreadsheet of side by side results from of the
output of two independent scanners (ScanCode & Windriver) producing SPDX
tag:value files created by Philippe Ombredanne. Philippe prepared the
base worksheet, and did an initial spot review of a few 1000 files.
The 4.13 kernel was the starting point of the analysis with 60,537 files
assessed. Kate Stewart did a file by file comparison of the scanner
results in the spreadsheet to determine which SPDX license identifier(s)
to be applied to the file. She confirmed any determination that was not
immediately clear with lawyers working with the Linux Foundation.
Criteria used to select files for SPDX license identifier tagging was:
- Files considered eligible had to be source code files.
- Make and config files were included as candidates if they contained >5
lines of source
- File already had some variant of a license header in it (even if <5
lines).
All documentation files were explicitly excluded.
The following heuristics were used to determine which SPDX license
identifiers to apply.
- when both scanners couldn't find any license traces, file was
considered to have no license information in it, and the top level
COPYING file license applied.
For non */uapi/* files that summary was:
SPDX license identifier # files
---------------------------------------------------|-------
GPL-2.0 11139
and resulted in the first patch in this series.
If that file was a */uapi/* path one, it was "GPL-2.0 WITH
Linux-syscall-note" otherwise it was "GPL-2.0". Results of that was:
SPDX license identifier # files
---------------------------------------------------|-------
GPL-2.0 WITH Linux-syscall-note 930
and resulted in the second patch in this series.
- if a file had some form of licensing information in it, and was one
of the */uapi/* ones, it was denoted with the Linux-syscall-note if
any GPL family license was found in the file or had no licensing in
it (per prior point). Results summary:
SPDX license identifier # files
---------------------------------------------------|------
GPL-2.0 WITH Linux-syscall-note 270
GPL-2.0+ WITH Linux-syscall-note 169
((GPL-2.0 WITH Linux-syscall-note) OR BSD-2-Clause) 21
((GPL-2.0 WITH Linux-syscall-note) OR BSD-3-Clause) 17
LGPL-2.1+ WITH Linux-syscall-note 15
GPL-1.0+ WITH Linux-syscall-note 14
((GPL-2.0+ WITH Linux-syscall-note) OR BSD-3-Clause) 5
LGPL-2.0+ WITH Linux-syscall-note 4
LGPL-2.1 WITH Linux-syscall-note 3
((GPL-2.0 WITH Linux-syscall-note) OR MIT) 3
((GPL-2.0 WITH Linux-syscall-note) AND MIT) 1
and that resulted in the third patch in this series.
- when the two scanners agreed on the detected license(s), that became
the concluded license(s).
- when there was disagreement between the two scanners (one detected a
license but the other didn't, or they both detected different
licenses) a manual inspection of the file occurred.
- In most cases a manual inspection of the information in the file
resulted in a clear resolution of the license that should apply (and
which scanner probably needed to revisit its heuristics).
- When it was not immediately clear, the license identifier was
confirmed with lawyers working with the Linux Foundation.
- If there was any question as to the appropriate license identifier,
the file was flagged for further research and to be revisited later
in time.
In total, over 70 hours of logged manual review was done on the
spreadsheet to determine the SPDX license identifiers to apply to the
source files by Kate, Philippe, Thomas and, in some cases, confirmation
by lawyers working with the Linux Foundation.
Kate also obtained a third independent scan of the 4.13 code base from
FOSSology, and compared selected files where the other two scanners
disagreed against that SPDX file, to see if there was new insights. The
Windriver scanner is based on an older version of FOSSology in part, so
they are related.
Thomas did random spot checks in about 500 files from the spreadsheets
for the uapi headers and agreed with SPDX license identifier in the
files he inspected. For the non-uapi files Thomas did random spot checks
in about 15000 files.
In initial set of patches against 4.14-rc6, 3 files were found to have
copy/paste license identifier errors, and have been fixed to reflect the
correct identifier.
Additionally Philippe spent 10 hours this week doing a detailed manual
inspection and review of the 12,461 patched files from the initial patch
version early this week with:
- a full scancode scan run, collecting the matched texts, detected
license ids and scores
- reviewing anything where there was a license detected (about 500+
files) to ensure that the applied SPDX license was correct
- reviewing anything where there was no detection but the patch license
was not GPL-2.0 WITH Linux-syscall-note to ensure that the applied
SPDX license was correct
This produced a worksheet with 20 files needing minor correction. This
worksheet was then exported into 3 different .csv files for the
different types of files to be modified.
These .csv files were then reviewed by Greg. Thomas wrote a script to
parse the csv files and add the proper SPDX tag to the file, in the
format that the file expected. This script was further refined by Greg
based on the output to detect more types of files automatically and to
distinguish between header and source .c files (which need different
comment types.) Finally Greg ran the script using the .csv files to
generate the patches.
Reviewed-by: Kate Stewart <kstewart@linuxfoundation.org>
Reviewed-by: Philippe Ombredanne <pombredanne@nexb.com>
Reviewed-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2017-11-01 14:07:57 +00:00
|
|
|
/* SPDX-License-Identifier: GPL-2.0 */
|
2005-04-16 22:20:36 +00:00
|
|
|
/*
|
|
|
|
* Declarations of AX.25 type objects.
|
|
|
|
*
|
|
|
|
* Alan Cox (GW4PTS) 10/11/93
|
|
|
|
*/
|
|
|
|
#ifndef _AX25_H
|
|
|
|
#define _AX25_H
|
|
|
|
|
|
|
|
#include <linux/ax25.h>
|
|
|
|
#include <linux/spinlock.h>
|
|
|
|
#include <linux/timer.h>
|
|
|
|
#include <linux/list.h>
|
include cleanup: Update gfp.h and slab.h includes to prepare for breaking implicit slab.h inclusion from percpu.h
percpu.h is included by sched.h and module.h and thus ends up being
included when building most .c files. percpu.h includes slab.h which
in turn includes gfp.h making everything defined by the two files
universally available and complicating inclusion dependencies.
percpu.h -> slab.h dependency is about to be removed. Prepare for
this change by updating users of gfp and slab facilities include those
headers directly instead of assuming availability. As this conversion
needs to touch large number of source files, the following script is
used as the basis of conversion.
http://userweb.kernel.org/~tj/misc/slabh-sweep.py
The script does the followings.
* Scan files for gfp and slab usages and update includes such that
only the necessary includes are there. ie. if only gfp is used,
gfp.h, if slab is used, slab.h.
* When the script inserts a new include, it looks at the include
blocks and try to put the new include such that its order conforms
to its surrounding. It's put in the include block which contains
core kernel includes, in the same order that the rest are ordered -
alphabetical, Christmas tree, rev-Xmas-tree or at the end if there
doesn't seem to be any matching order.
* If the script can't find a place to put a new include (mostly
because the file doesn't have fitting include block), it prints out
an error message indicating which .h file needs to be added to the
file.
The conversion was done in the following steps.
1. The initial automatic conversion of all .c files updated slightly
over 4000 files, deleting around 700 includes and adding ~480 gfp.h
and ~3000 slab.h inclusions. The script emitted errors for ~400
files.
2. Each error was manually checked. Some didn't need the inclusion,
some needed manual addition while adding it to implementation .h or
embedding .c file was more appropriate for others. This step added
inclusions to around 150 files.
3. The script was run again and the output was compared to the edits
from #2 to make sure no file was left behind.
4. Several build tests were done and a couple of problems were fixed.
e.g. lib/decompress_*.c used malloc/free() wrappers around slab
APIs requiring slab.h to be added manually.
5. The script was run on all .h files but without automatically
editing them as sprinkling gfp.h and slab.h inclusions around .h
files could easily lead to inclusion dependency hell. Most gfp.h
inclusion directives were ignored as stuff from gfp.h was usually
wildly available and often used in preprocessor macros. Each
slab.h inclusion directive was examined and added manually as
necessary.
6. percpu.h was updated not to include slab.h.
7. Build test were done on the following configurations and failures
were fixed. CONFIG_GCOV_KERNEL was turned off for all tests (as my
distributed build env didn't work with gcov compiles) and a few
more options had to be turned off depending on archs to make things
build (like ipr on powerpc/64 which failed due to missing writeq).
* x86 and x86_64 UP and SMP allmodconfig and a custom test config.
* powerpc and powerpc64 SMP allmodconfig
* sparc and sparc64 SMP allmodconfig
* ia64 SMP allmodconfig
* s390 SMP allmodconfig
* alpha SMP allmodconfig
* um on x86_64 SMP allmodconfig
8. percpu.h modifications were reverted so that it could be applied as
a separate patch and serve as bisection point.
Given the fact that I had only a couple of failures from tests on step
6, I'm fairly confident about the coverage of this conversion patch.
If there is a breakage, it's likely to be something in one of the arch
headers which should be easily discoverable easily on most builds of
the specific arch.
Signed-off-by: Tejun Heo <tj@kernel.org>
Guess-its-ok-by: Christoph Lameter <cl@linux-foundation.org>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Lee Schermerhorn <Lee.Schermerhorn@hp.com>
2010-03-24 08:04:11 +00:00
|
|
|
#include <linux/slab.h>
|
2017-07-04 12:53:29 +00:00
|
|
|
#include <linux/refcount.h>
|
2015-03-02 06:05:28 +00:00
|
|
|
#include <net/neighbour.h>
|
2015-06-25 13:19:07 +00:00
|
|
|
#include <net/sock.h>
|
2018-04-13 17:44:18 +00:00
|
|
|
#include <linux/seq_file.h>
|
2005-04-16 22:20:36 +00:00
|
|
|
|
|
|
|
#define AX25_T1CLAMPLO 1
|
|
|
|
#define AX25_T1CLAMPHI (30 * HZ)
|
|
|
|
|
|
|
|
#define AX25_BPQ_HEADER_LEN 16
|
|
|
|
#define AX25_KISS_HEADER_LEN 1
|
|
|
|
|
|
|
|
#define AX25_HEADER_LEN 17
|
|
|
|
#define AX25_ADDR_LEN 7
|
|
|
|
#define AX25_DIGI_HEADER_LEN (AX25_MAX_DIGIS * AX25_ADDR_LEN)
|
|
|
|
#define AX25_MAX_HEADER_LEN (AX25_HEADER_LEN + AX25_DIGI_HEADER_LEN)
|
|
|
|
|
|
|
|
/* AX.25 Protocol IDs */
|
|
|
|
#define AX25_P_ROSE 0x01
|
2005-09-12 21:22:30 +00:00
|
|
|
#define AX25_P_VJCOMP 0x06 /* Compressed TCP/IP packet */
|
|
|
|
/* Van Jacobsen (RFC 1144) */
|
|
|
|
#define AX25_P_VJUNCOMP 0x07 /* Uncompressed TCP/IP packet */
|
|
|
|
/* Van Jacobsen (RFC 1144) */
|
|
|
|
#define AX25_P_SEGMENT 0x08 /* Segmentation fragment */
|
|
|
|
#define AX25_P_TEXNET 0xc3 /* TEXTNET datagram protocol */
|
|
|
|
#define AX25_P_LQ 0xc4 /* Link Quality Protocol */
|
|
|
|
#define AX25_P_ATALK 0xca /* Appletalk */
|
|
|
|
#define AX25_P_ATALK_ARP 0xcb /* Appletalk ARP */
|
|
|
|
#define AX25_P_IP 0xcc /* ARPA Internet Protocol */
|
2007-12-20 21:56:32 +00:00
|
|
|
#define AX25_P_ARP 0xcd /* ARPA Address Resolution */
|
2005-09-12 21:22:30 +00:00
|
|
|
#define AX25_P_FLEXNET 0xce /* FlexNet */
|
|
|
|
#define AX25_P_NETROM 0xcf /* NET/ROM */
|
|
|
|
#define AX25_P_TEXT 0xF0 /* No layer 3 protocol impl. */
|
2005-04-16 22:20:36 +00:00
|
|
|
|
|
|
|
/* AX.25 Segment control values */
|
|
|
|
#define AX25_SEG_REM 0x7F
|
|
|
|
#define AX25_SEG_FIRST 0x80
|
|
|
|
|
|
|
|
#define AX25_CBIT 0x80 /* Command/Response bit */
|
|
|
|
#define AX25_EBIT 0x01 /* HDLC Address Extension bit */
|
|
|
|
#define AX25_HBIT 0x80 /* Has been repeated bit */
|
|
|
|
|
|
|
|
#define AX25_SSSID_SPARE 0x60 /* Unused bits in SSID for standard AX.25 */
|
|
|
|
#define AX25_ESSID_SPARE 0x20 /* Unused bits in SSID for extended AX.25 */
|
|
|
|
#define AX25_DAMA_FLAG 0x20 /* Well, it is *NOT* unused! (dl1bke 951121 */
|
|
|
|
|
|
|
|
#define AX25_COND_ACK_PENDING 0x01
|
|
|
|
#define AX25_COND_REJECT 0x02
|
|
|
|
#define AX25_COND_PEER_RX_BUSY 0x04
|
|
|
|
#define AX25_COND_OWN_RX_BUSY 0x08
|
|
|
|
#define AX25_COND_DAMA_MODE 0x10
|
|
|
|
|
|
|
|
#ifndef _LINUX_NETDEVICE_H
|
|
|
|
#include <linux/netdevice.h>
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/* Upper sub-layer (LAPB) definitions */
|
|
|
|
|
|
|
|
/* Control field templates */
|
|
|
|
#define AX25_I 0x00 /* Information frames */
|
|
|
|
#define AX25_S 0x01 /* Supervisory frames */
|
|
|
|
#define AX25_RR 0x01 /* Receiver ready */
|
|
|
|
#define AX25_RNR 0x05 /* Receiver not ready */
|
|
|
|
#define AX25_REJ 0x09 /* Reject */
|
|
|
|
#define AX25_U 0x03 /* Unnumbered frames */
|
|
|
|
#define AX25_SABM 0x2f /* Set Asynchronous Balanced Mode */
|
|
|
|
#define AX25_SABME 0x6f /* Set Asynchronous Balanced Mode Extended */
|
|
|
|
#define AX25_DISC 0x43 /* Disconnect */
|
|
|
|
#define AX25_DM 0x0f /* Disconnected mode */
|
|
|
|
#define AX25_UA 0x63 /* Unnumbered acknowledge */
|
|
|
|
#define AX25_FRMR 0x87 /* Frame reject */
|
|
|
|
#define AX25_UI 0x03 /* Unnumbered information */
|
|
|
|
#define AX25_XID 0xaf /* Exchange information */
|
|
|
|
#define AX25_TEST 0xe3 /* Test */
|
|
|
|
|
|
|
|
#define AX25_PF 0x10 /* Poll/final bit for standard AX.25 */
|
|
|
|
#define AX25_EPF 0x01 /* Poll/final bit for extended AX.25 */
|
|
|
|
|
|
|
|
#define AX25_ILLEGAL 0x100 /* Impossible to be a real frame type */
|
|
|
|
|
|
|
|
#define AX25_POLLOFF 0
|
|
|
|
#define AX25_POLLON 1
|
|
|
|
|
|
|
|
/* AX25 L2 C-bit */
|
|
|
|
#define AX25_COMMAND 1
|
|
|
|
#define AX25_RESPONSE 2
|
|
|
|
|
|
|
|
/* Define Link State constants. */
|
|
|
|
|
|
|
|
enum {
|
2005-09-12 21:24:24 +00:00
|
|
|
AX25_STATE_0, /* Listening */
|
|
|
|
AX25_STATE_1, /* SABM sent */
|
|
|
|
AX25_STATE_2, /* DISC sent */
|
|
|
|
AX25_STATE_3, /* Established */
|
|
|
|
AX25_STATE_4 /* Recovery */
|
2005-04-16 22:20:36 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
#define AX25_MODULUS 8 /* Standard AX.25 modulus */
|
|
|
|
#define AX25_EMODULUS 128 /* Extended AX.25 modulus */
|
|
|
|
|
|
|
|
enum {
|
|
|
|
AX25_PROTO_STD_SIMPLEX,
|
|
|
|
AX25_PROTO_STD_DUPLEX,
|
2006-03-19 21:20:06 +00:00
|
|
|
#ifdef CONFIG_AX25_DAMA_SLAVE
|
2005-04-16 22:20:36 +00:00
|
|
|
AX25_PROTO_DAMA_SLAVE,
|
2006-03-19 21:20:06 +00:00
|
|
|
#ifdef CONFIG_AX25_DAMA_MASTER
|
|
|
|
AX25_PROTO_DAMA_MASTER,
|
|
|
|
#define AX25_PROTO_MAX AX25_PROTO_DAMA_MASTER
|
|
|
|
#endif
|
|
|
|
#endif
|
|
|
|
__AX25_PROTO_MAX,
|
|
|
|
AX25_PROTO_MAX = __AX25_PROTO_MAX -1
|
2005-04-16 22:20:36 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
enum {
|
|
|
|
AX25_VALUES_IPDEFMODE, /* 0=DG 1=VC */
|
|
|
|
AX25_VALUES_AXDEFMODE, /* 0=Normal 1=Extended Seq Nos */
|
|
|
|
AX25_VALUES_BACKOFF, /* 0=None 1=Linear 2=Exponential */
|
|
|
|
AX25_VALUES_CONMODE, /* Allow connected modes - 0=No 1=no "PID text" 2=all PIDs */
|
|
|
|
AX25_VALUES_WINDOW, /* Default window size for standard AX.25 */
|
|
|
|
AX25_VALUES_EWINDOW, /* Default window size for extended AX.25 */
|
|
|
|
AX25_VALUES_T1, /* Default T1 timeout value */
|
|
|
|
AX25_VALUES_T2, /* Default T2 timeout value */
|
|
|
|
AX25_VALUES_T3, /* Default T3 timeout value */
|
|
|
|
AX25_VALUES_IDLE, /* Connected mode idle timer */
|
|
|
|
AX25_VALUES_N2, /* Default N2 value */
|
|
|
|
AX25_VALUES_PACLEN, /* AX.25 MTU */
|
|
|
|
AX25_VALUES_PROTOCOL, /* Std AX.25, DAMA Slave, DAMA Master */
|
|
|
|
AX25_VALUES_DS_TIMEOUT, /* DAMA Slave timeout */
|
|
|
|
AX25_MAX_VALUES /* THIS MUST REMAIN THE LAST ENTRY OF THIS LIST */
|
|
|
|
};
|
|
|
|
|
|
|
|
#define AX25_DEF_IPDEFMODE 0 /* Datagram */
|
|
|
|
#define AX25_DEF_AXDEFMODE 0 /* Normal */
|
|
|
|
#define AX25_DEF_BACKOFF 1 /* Linear backoff */
|
|
|
|
#define AX25_DEF_CONMODE 2 /* Connected mode allowed */
|
|
|
|
#define AX25_DEF_WINDOW 2 /* Window=2 */
|
|
|
|
#define AX25_DEF_EWINDOW 32 /* Module-128 Window=32 */
|
2006-05-04 06:27:16 +00:00
|
|
|
#define AX25_DEF_T1 10000 /* T1=10s */
|
|
|
|
#define AX25_DEF_T2 3000 /* T2=3s */
|
|
|
|
#define AX25_DEF_T3 300000 /* T3=300s */
|
2005-04-16 22:20:36 +00:00
|
|
|
#define AX25_DEF_N2 10 /* N2=10 */
|
2006-05-04 06:27:16 +00:00
|
|
|
#define AX25_DEF_IDLE 0 /* Idle=None */
|
2005-04-16 22:20:36 +00:00
|
|
|
#define AX25_DEF_PACLEN 256 /* Paclen=256 */
|
|
|
|
#define AX25_DEF_PROTOCOL AX25_PROTO_STD_SIMPLEX /* Standard AX.25 */
|
2006-05-04 06:27:16 +00:00
|
|
|
#define AX25_DEF_DS_TIMEOUT 180000 /* DAMA timeout 3 minutes */
|
2005-04-16 22:20:36 +00:00
|
|
|
|
|
|
|
typedef struct ax25_uid_assoc {
|
2005-08-23 17:11:45 +00:00
|
|
|
struct hlist_node uid_node;
|
2017-07-04 12:53:29 +00:00
|
|
|
refcount_t refcount;
|
2012-05-24 18:55:00 +00:00
|
|
|
kuid_t uid;
|
2005-04-16 22:20:36 +00:00
|
|
|
ax25_address call;
|
|
|
|
} ax25_uid_assoc;
|
|
|
|
|
hlist: drop the node parameter from iterators
I'm not sure why, but the hlist for each entry iterators were conceived
list_for_each_entry(pos, head, member)
The hlist ones were greedy and wanted an extra parameter:
hlist_for_each_entry(tpos, pos, head, member)
Why did they need an extra pos parameter? I'm not quite sure. Not only
they don't really need it, it also prevents the iterator from looking
exactly like the list iterator, which is unfortunate.
Besides the semantic patch, there was some manual work required:
- Fix up the actual hlist iterators in linux/list.h
- Fix up the declaration of other iterators based on the hlist ones.
- A very small amount of places were using the 'node' parameter, this
was modified to use 'obj->member' instead.
- Coccinelle didn't handle the hlist_for_each_entry_safe iterator
properly, so those had to be fixed up manually.
The semantic patch which is mostly the work of Peter Senna Tschudin is here:
@@
iterator name hlist_for_each_entry, hlist_for_each_entry_continue, hlist_for_each_entry_from, hlist_for_each_entry_rcu, hlist_for_each_entry_rcu_bh, hlist_for_each_entry_continue_rcu_bh, for_each_busy_worker, ax25_uid_for_each, ax25_for_each, inet_bind_bucket_for_each, sctp_for_each_hentry, sk_for_each, sk_for_each_rcu, sk_for_each_from, sk_for_each_safe, sk_for_each_bound, hlist_for_each_entry_safe, hlist_for_each_entry_continue_rcu, nr_neigh_for_each, nr_neigh_for_each_safe, nr_node_for_each, nr_node_for_each_safe, for_each_gfn_indirect_valid_sp, for_each_gfn_sp, for_each_host;
type T;
expression a,c,d,e;
identifier b;
statement S;
@@
-T b;
<+... when != b
(
hlist_for_each_entry(a,
- b,
c, d) S
|
hlist_for_each_entry_continue(a,
- b,
c) S
|
hlist_for_each_entry_from(a,
- b,
c) S
|
hlist_for_each_entry_rcu(a,
- b,
c, d) S
|
hlist_for_each_entry_rcu_bh(a,
- b,
c, d) S
|
hlist_for_each_entry_continue_rcu_bh(a,
- b,
c) S
|
for_each_busy_worker(a, c,
- b,
d) S
|
ax25_uid_for_each(a,
- b,
c) S
|
ax25_for_each(a,
- b,
c) S
|
inet_bind_bucket_for_each(a,
- b,
c) S
|
sctp_for_each_hentry(a,
- b,
c) S
|
sk_for_each(a,
- b,
c) S
|
sk_for_each_rcu(a,
- b,
c) S
|
sk_for_each_from
-(a, b)
+(a)
S
+ sk_for_each_from(a) S
|
sk_for_each_safe(a,
- b,
c, d) S
|
sk_for_each_bound(a,
- b,
c) S
|
hlist_for_each_entry_safe(a,
- b,
c, d, e) S
|
hlist_for_each_entry_continue_rcu(a,
- b,
c) S
|
nr_neigh_for_each(a,
- b,
c) S
|
nr_neigh_for_each_safe(a,
- b,
c, d) S
|
nr_node_for_each(a,
- b,
c) S
|
nr_node_for_each_safe(a,
- b,
c, d) S
|
- for_each_gfn_sp(a, c, d, b) S
+ for_each_gfn_sp(a, c, d) S
|
- for_each_gfn_indirect_valid_sp(a, c, d, b) S
+ for_each_gfn_indirect_valid_sp(a, c, d) S
|
for_each_host(a,
- b,
c) S
|
for_each_host_safe(a,
- b,
c, d) S
|
for_each_mesh_entry(a,
- b,
c, d) S
)
...+>
[akpm@linux-foundation.org: drop bogus change from net/ipv4/raw.c]
[akpm@linux-foundation.org: drop bogus hunk from net/ipv6/raw.c]
[akpm@linux-foundation.org: checkpatch fixes]
[akpm@linux-foundation.org: fix warnings]
[akpm@linux-foudnation.org: redo intrusive kvm changes]
Tested-by: Peter Senna Tschudin <peter.senna@gmail.com>
Acked-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
Signed-off-by: Sasha Levin <sasha.levin@oracle.com>
Cc: Wu Fengguang <fengguang.wu@intel.com>
Cc: Marcelo Tosatti <mtosatti@redhat.com>
Cc: Gleb Natapov <gleb@redhat.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2013-02-28 01:06:00 +00:00
|
|
|
#define ax25_uid_for_each(__ax25, list) \
|
|
|
|
hlist_for_each_entry(__ax25, list, uid_node)
|
2005-08-23 17:11:45 +00:00
|
|
|
|
|
|
|
#define ax25_uid_hold(ax25) \
|
2017-07-04 12:53:29 +00:00
|
|
|
refcount_inc(&((ax25)->refcount))
|
2005-08-23 17:11:45 +00:00
|
|
|
|
|
|
|
static inline void ax25_uid_put(ax25_uid_assoc *assoc)
|
|
|
|
{
|
2017-07-04 12:53:29 +00:00
|
|
|
if (refcount_dec_and_test(&assoc->refcount)) {
|
2005-08-23 17:11:45 +00:00
|
|
|
kfree(assoc);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2005-04-16 22:20:36 +00:00
|
|
|
typedef struct {
|
|
|
|
ax25_address calls[AX25_MAX_DIGIS];
|
|
|
|
unsigned char repeated[AX25_MAX_DIGIS];
|
|
|
|
unsigned char ndigi;
|
2005-10-14 20:29:56 +00:00
|
|
|
signed char lastrepeat;
|
2005-04-16 22:20:36 +00:00
|
|
|
} ax25_digi;
|
|
|
|
|
|
|
|
typedef struct ax25_route {
|
|
|
|
struct ax25_route *next;
|
|
|
|
ax25_address callsign;
|
|
|
|
struct net_device *dev;
|
|
|
|
ax25_digi *digipeat;
|
|
|
|
char ip_mode;
|
|
|
|
} ax25_route;
|
|
|
|
|
2013-08-01 00:31:36 +00:00
|
|
|
void __ax25_put_route(ax25_route *ax25_rt);
|
2006-07-04 02:30:18 +00:00
|
|
|
|
ax25: fix possible use-after-free
syzbot found that ax25 routes where not properly protected
against concurrent use [1].
In this particular report the bug happened while
copying ax25->digipeat.
Fix this problem by making sure we call ax25_get_route()
while ax25_route_lock is held, so that no modification
could happen while using the route.
The current two ax25_get_route() callers do not sleep,
so this change should be fine.
Once we do that, ax25_get_route() no longer needs to
grab a reference on the found route.
[1]
ax25_connect(): syz-executor0 uses autobind, please contact jreuter@yaina.de
BUG: KASAN: use-after-free in memcpy include/linux/string.h:352 [inline]
BUG: KASAN: use-after-free in kmemdup+0x42/0x60 mm/util.c:113
Read of size 66 at addr ffff888066641a80 by task syz-executor2/531
ax25_connect(): syz-executor0 uses autobind, please contact jreuter@yaina.de
CPU: 1 PID: 531 Comm: syz-executor2 Not tainted 5.0.0-rc2+ #10
Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011
Call Trace:
__dump_stack lib/dump_stack.c:77 [inline]
dump_stack+0x1db/0x2d0 lib/dump_stack.c:113
print_address_description.cold+0x7c/0x20d mm/kasan/report.c:187
kasan_report.cold+0x1b/0x40 mm/kasan/report.c:317
check_memory_region_inline mm/kasan/generic.c:185 [inline]
check_memory_region+0x123/0x190 mm/kasan/generic.c:191
memcpy+0x24/0x50 mm/kasan/common.c:130
memcpy include/linux/string.h:352 [inline]
kmemdup+0x42/0x60 mm/util.c:113
kmemdup include/linux/string.h:425 [inline]
ax25_rt_autobind+0x25d/0x750 net/ax25/ax25_route.c:424
ax25_connect.cold+0x30/0xa4 net/ax25/af_ax25.c:1224
__sys_connect+0x357/0x490 net/socket.c:1664
__do_sys_connect net/socket.c:1675 [inline]
__se_sys_connect net/socket.c:1672 [inline]
__x64_sys_connect+0x73/0xb0 net/socket.c:1672
do_syscall_64+0x1a3/0x800 arch/x86/entry/common.c:290
entry_SYSCALL_64_after_hwframe+0x49/0xbe
RIP: 0033:0x458099
Code: 6d b7 fb ff c3 66 2e 0f 1f 84 00 00 00 00 00 66 90 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 0f 83 3b b7 fb ff c3 66 2e 0f 1f 84 00 00 00 00
RSP: 002b:00007f870ee22c78 EFLAGS: 00000246 ORIG_RAX: 000000000000002a
RAX: ffffffffffffffda RBX: 0000000000000003 RCX: 0000000000458099
RDX: 0000000000000048 RSI: 0000000020000080 RDI: 0000000000000005
RBP: 000000000073bf00 R08: 0000000000000000 R09: 0000000000000000
ax25_connect(): syz-executor4 uses autobind, please contact jreuter@yaina.de
R10: 0000000000000000 R11: 0000000000000246 R12: 00007f870ee236d4
R13: 00000000004be48e R14: 00000000004ce9a8 R15: 00000000ffffffff
Allocated by task 526:
save_stack+0x45/0xd0 mm/kasan/common.c:73
set_track mm/kasan/common.c:85 [inline]
__kasan_kmalloc mm/kasan/common.c:496 [inline]
__kasan_kmalloc.constprop.0+0xcf/0xe0 mm/kasan/common.c:469
kasan_kmalloc+0x9/0x10 mm/kasan/common.c:504
ax25_connect(): syz-executor5 uses autobind, please contact jreuter@yaina.de
kmem_cache_alloc_trace+0x151/0x760 mm/slab.c:3609
kmalloc include/linux/slab.h:545 [inline]
ax25_rt_add net/ax25/ax25_route.c:95 [inline]
ax25_rt_ioctl+0x3b9/0x1270 net/ax25/ax25_route.c:233
ax25_ioctl+0x322/0x10b0 net/ax25/af_ax25.c:1763
sock_do_ioctl+0xe2/0x400 net/socket.c:950
sock_ioctl+0x32f/0x6c0 net/socket.c:1074
vfs_ioctl fs/ioctl.c:46 [inline]
file_ioctl fs/ioctl.c:509 [inline]
do_vfs_ioctl+0x107b/0x17d0 fs/ioctl.c:696
ksys_ioctl+0xab/0xd0 fs/ioctl.c:713
__do_sys_ioctl fs/ioctl.c:720 [inline]
__se_sys_ioctl fs/ioctl.c:718 [inline]
__x64_sys_ioctl+0x73/0xb0 fs/ioctl.c:718
do_syscall_64+0x1a3/0x800 arch/x86/entry/common.c:290
entry_SYSCALL_64_after_hwframe+0x49/0xbe
ax25_connect(): syz-executor5 uses autobind, please contact jreuter@yaina.de
Freed by task 550:
save_stack+0x45/0xd0 mm/kasan/common.c:73
set_track mm/kasan/common.c:85 [inline]
__kasan_slab_free+0x102/0x150 mm/kasan/common.c:458
kasan_slab_free+0xe/0x10 mm/kasan/common.c:466
__cache_free mm/slab.c:3487 [inline]
kfree+0xcf/0x230 mm/slab.c:3806
ax25_rt_add net/ax25/ax25_route.c:92 [inline]
ax25_rt_ioctl+0x304/0x1270 net/ax25/ax25_route.c:233
ax25_ioctl+0x322/0x10b0 net/ax25/af_ax25.c:1763
sock_do_ioctl+0xe2/0x400 net/socket.c:950
sock_ioctl+0x32f/0x6c0 net/socket.c:1074
vfs_ioctl fs/ioctl.c:46 [inline]
file_ioctl fs/ioctl.c:509 [inline]
do_vfs_ioctl+0x107b/0x17d0 fs/ioctl.c:696
ksys_ioctl+0xab/0xd0 fs/ioctl.c:713
__do_sys_ioctl fs/ioctl.c:720 [inline]
__se_sys_ioctl fs/ioctl.c:718 [inline]
__x64_sys_ioctl+0x73/0xb0 fs/ioctl.c:718
do_syscall_64+0x1a3/0x800 arch/x86/entry/common.c:290
entry_SYSCALL_64_after_hwframe+0x49/0xbe
The buggy address belongs to the object at ffff888066641a80
which belongs to the cache kmalloc-96 of size 96
The buggy address is located 0 bytes inside of
96-byte region [ffff888066641a80, ffff888066641ae0)
The buggy address belongs to the page:
page:ffffea0001999040 count:1 mapcount:0 mapping:ffff88812c3f04c0 index:0x0
flags: 0x1fffc0000000200(slab)
ax25_connect(): syz-executor4 uses autobind, please contact jreuter@yaina.de
raw: 01fffc0000000200 ffffea0001817948 ffffea0002341dc8 ffff88812c3f04c0
raw: 0000000000000000 ffff888066641000 0000000100000020 0000000000000000
page dumped because: kasan: bad access detected
Memory state around the buggy address:
ffff888066641980: fb fb fb fb fb fb fb fb fb fb fb fb fc fc fc fc
ffff888066641a00: 00 00 00 00 00 00 00 00 02 fc fc fc fc fc fc fc
>ffff888066641a80: fb fb fb fb fb fb fb fb fb fb fb fb fc fc fc fc
^
ffff888066641b00: fb fb fb fb fb fb fb fb fb fb fb fb fc fc fc fc
ffff888066641b80: 00 00 00 00 00 00 00 00 00 00 00 00 fc fc fc fc
Signed-off-by: Eric Dumazet <edumazet@google.com>
Cc: Ralf Baechle <ralf@linux-mips.org>
Reported-by: syzbot <syzkaller@googlegroups.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2019-01-22 18:40:59 +00:00
|
|
|
extern rwlock_t ax25_route_lock;
|
|
|
|
|
|
|
|
static inline void ax25_route_lock_use(void)
|
|
|
|
{
|
|
|
|
read_lock(&ax25_route_lock);
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline void ax25_route_lock_unuse(void)
|
|
|
|
{
|
|
|
|
read_unlock(&ax25_route_lock);
|
|
|
|
}
|
|
|
|
|
2005-04-16 22:20:36 +00:00
|
|
|
typedef struct {
|
|
|
|
char slave; /* slave_mode? */
|
|
|
|
struct timer_list slave_timer; /* timeout timer */
|
|
|
|
unsigned short slave_timeout; /* when? */
|
|
|
|
} ax25_dama_info;
|
|
|
|
|
|
|
|
struct ctl_table;
|
|
|
|
|
|
|
|
typedef struct ax25_dev {
|
|
|
|
struct ax25_dev *next;
|
2021-12-07 01:30:33 +00:00
|
|
|
|
2005-04-16 22:20:36 +00:00
|
|
|
struct net_device *dev;
|
2021-12-07 01:30:33 +00:00
|
|
|
netdevice_tracker dev_tracker;
|
|
|
|
|
2005-04-16 22:20:36 +00:00
|
|
|
struct net_device *forward;
|
2012-04-19 13:34:18 +00:00
|
|
|
struct ctl_table_header *sysheader;
|
2005-04-16 22:20:36 +00:00
|
|
|
int values[AX25_MAX_VALUES];
|
|
|
|
#if defined(CONFIG_AX25_DAMA_SLAVE) || defined(CONFIG_AX25_DAMA_MASTER)
|
|
|
|
ax25_dama_info dama;
|
|
|
|
#endif
|
ax25: add refcount in ax25_dev to avoid UAF bugs
If we dereference ax25_dev after we call kfree(ax25_dev) in
ax25_dev_device_down(), it will lead to concurrency UAF bugs.
There are eight syscall functions suffer from UAF bugs, include
ax25_bind(), ax25_release(), ax25_connect(), ax25_ioctl(),
ax25_getname(), ax25_sendmsg(), ax25_getsockopt() and
ax25_info_show().
One of the concurrency UAF can be shown as below:
(USE) | (FREE)
| ax25_device_event
| ax25_dev_device_down
ax25_bind | ...
... | kfree(ax25_dev)
ax25_fillin_cb() | ...
ax25_fillin_cb_from_dev() |
... |
The root cause of UAF bugs is that kfree(ax25_dev) in
ax25_dev_device_down() is not protected by any locks.
When ax25_dev, which there are still pointers point to,
is released, the concurrency UAF bug will happen.
This patch introduces refcount into ax25_dev in order to
guarantee that there are no pointers point to it when ax25_dev
is released.
Signed-off-by: Duoming Zhou <duoming@zju.edu.cn>
Signed-off-by: David S. Miller <davem@davemloft.net>
2022-01-28 04:47:16 +00:00
|
|
|
refcount_t refcount;
|
ax25: Fix ax25 session cleanup problems
There are session cleanup problems in ax25_release() and
ax25_disconnect(). If we setup a session and then disconnect,
the disconnected session is still in "LISTENING" state that
is shown below.
Active AX.25 sockets
Dest Source Device State Vr/Vs Send-Q Recv-Q
DL9SAU-4 DL9SAU-3 ??? LISTENING 000/000 0 0
DL9SAU-3 DL9SAU-4 ??? LISTENING 000/000 0 0
The first reason is caused by del_timer_sync() in ax25_release().
The timers of ax25 are used for correct session cleanup. If we use
ax25_release() to close ax25 sessions and ax25_dev is not null,
the del_timer_sync() functions in ax25_release() will execute.
As a result, the sessions could not be cleaned up correctly,
because the timers have stopped.
In order to solve this problem, this patch adds a device_up flag
in ax25_dev in order to judge whether the device is up. If there
are sessions to be cleaned up, the del_timer_sync() in
ax25_release() will not execute. What's more, we add ax25_cb_del()
in ax25_kill_by_device(), because the timers have been stopped
and there are no functions that could delete ax25_cb if we do not
call ax25_release(). Finally, we reorder the position of
ax25_list_lock in ax25_cb_del() in order to synchronize among
different functions that call ax25_cb_del().
The second reason is caused by improper check in ax25_disconnect().
The incoming ax25 sessions which ax25->sk is null will close
heartbeat timer, because the check "if(!ax25->sk || ..)" is
satisfied. As a result, the session could not be cleaned up properly.
In order to solve this problem, this patch changes the improper
check to "if(ax25->sk && ..)" in ax25_disconnect().
What`s more, the ax25_disconnect() may be called twice, which is
not necessary. For example, ax25_kill_by_device() calls
ax25_disconnect() and sets ax25->state to AX25_STATE_0, but
ax25_release() calls ax25_disconnect() again.
In order to solve this problem, this patch add a check in
ax25_release(). If the flag of ax25->sk equals to SOCK_DEAD,
the ax25_disconnect() in ax25_release() should not be executed.
Fixes: 82e31755e55f ("ax25: Fix UAF bugs in ax25 timers")
Fixes: 8a367e74c012 ("ax25: Fix segfault after sock connection timeout")
Reported-and-tested-by: Thomas Osterried <thomas@osterried.de>
Signed-off-by: Duoming Zhou <duoming@zju.edu.cn>
Link: https://lore.kernel.org/r/20220530152158.108619-1-duoming@zju.edu.cn
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
2022-05-30 15:21:58 +00:00
|
|
|
bool device_up;
|
2005-04-16 22:20:36 +00:00
|
|
|
} ax25_dev;
|
|
|
|
|
|
|
|
typedef struct ax25_cb {
|
|
|
|
struct hlist_node ax25_node;
|
|
|
|
ax25_address source_addr, dest_addr;
|
|
|
|
ax25_digi *digipeat;
|
|
|
|
ax25_dev *ax25_dev;
|
2022-07-28 05:18:21 +00:00
|
|
|
netdevice_tracker dev_tracker;
|
2005-04-16 22:20:36 +00:00
|
|
|
unsigned char iamdigi;
|
|
|
|
unsigned char state, modulus, pidincl;
|
|
|
|
unsigned short vs, vr, va;
|
|
|
|
unsigned char condition, backoff;
|
|
|
|
unsigned char n2, n2count;
|
|
|
|
struct timer_list t1timer, t2timer, t3timer, idletimer;
|
|
|
|
unsigned long t1, t2, t3, idle, rtt;
|
|
|
|
unsigned short paclen, fragno, fraglen;
|
|
|
|
struct sk_buff_head write_queue;
|
|
|
|
struct sk_buff_head reseq_queue;
|
|
|
|
struct sk_buff_head ack_queue;
|
|
|
|
struct sk_buff_head frag_queue;
|
|
|
|
unsigned char window;
|
|
|
|
struct timer_list timer, dtimer;
|
|
|
|
struct sock *sk; /* Backlink to socket */
|
2017-07-04 12:53:31 +00:00
|
|
|
refcount_t refcount;
|
2005-04-16 22:20:36 +00:00
|
|
|
} ax25_cb;
|
|
|
|
|
2015-06-25 13:19:07 +00:00
|
|
|
struct ax25_sock {
|
|
|
|
struct sock sk;
|
|
|
|
struct ax25_cb *cb;
|
|
|
|
};
|
|
|
|
|
2023-03-17 15:55:37 +00:00
|
|
|
#define ax25_sk(ptr) container_of_const(ptr, struct ax25_sock, sk)
|
2015-06-25 13:19:07 +00:00
|
|
|
|
|
|
|
static inline struct ax25_cb *sk_to_ax25(const struct sock *sk)
|
|
|
|
{
|
|
|
|
return ax25_sk(sk)->cb;
|
|
|
|
}
|
2005-04-16 22:20:36 +00:00
|
|
|
|
hlist: drop the node parameter from iterators
I'm not sure why, but the hlist for each entry iterators were conceived
list_for_each_entry(pos, head, member)
The hlist ones were greedy and wanted an extra parameter:
hlist_for_each_entry(tpos, pos, head, member)
Why did they need an extra pos parameter? I'm not quite sure. Not only
they don't really need it, it also prevents the iterator from looking
exactly like the list iterator, which is unfortunate.
Besides the semantic patch, there was some manual work required:
- Fix up the actual hlist iterators in linux/list.h
- Fix up the declaration of other iterators based on the hlist ones.
- A very small amount of places were using the 'node' parameter, this
was modified to use 'obj->member' instead.
- Coccinelle didn't handle the hlist_for_each_entry_safe iterator
properly, so those had to be fixed up manually.
The semantic patch which is mostly the work of Peter Senna Tschudin is here:
@@
iterator name hlist_for_each_entry, hlist_for_each_entry_continue, hlist_for_each_entry_from, hlist_for_each_entry_rcu, hlist_for_each_entry_rcu_bh, hlist_for_each_entry_continue_rcu_bh, for_each_busy_worker, ax25_uid_for_each, ax25_for_each, inet_bind_bucket_for_each, sctp_for_each_hentry, sk_for_each, sk_for_each_rcu, sk_for_each_from, sk_for_each_safe, sk_for_each_bound, hlist_for_each_entry_safe, hlist_for_each_entry_continue_rcu, nr_neigh_for_each, nr_neigh_for_each_safe, nr_node_for_each, nr_node_for_each_safe, for_each_gfn_indirect_valid_sp, for_each_gfn_sp, for_each_host;
type T;
expression a,c,d,e;
identifier b;
statement S;
@@
-T b;
<+... when != b
(
hlist_for_each_entry(a,
- b,
c, d) S
|
hlist_for_each_entry_continue(a,
- b,
c) S
|
hlist_for_each_entry_from(a,
- b,
c) S
|
hlist_for_each_entry_rcu(a,
- b,
c, d) S
|
hlist_for_each_entry_rcu_bh(a,
- b,
c, d) S
|
hlist_for_each_entry_continue_rcu_bh(a,
- b,
c) S
|
for_each_busy_worker(a, c,
- b,
d) S
|
ax25_uid_for_each(a,
- b,
c) S
|
ax25_for_each(a,
- b,
c) S
|
inet_bind_bucket_for_each(a,
- b,
c) S
|
sctp_for_each_hentry(a,
- b,
c) S
|
sk_for_each(a,
- b,
c) S
|
sk_for_each_rcu(a,
- b,
c) S
|
sk_for_each_from
-(a, b)
+(a)
S
+ sk_for_each_from(a) S
|
sk_for_each_safe(a,
- b,
c, d) S
|
sk_for_each_bound(a,
- b,
c) S
|
hlist_for_each_entry_safe(a,
- b,
c, d, e) S
|
hlist_for_each_entry_continue_rcu(a,
- b,
c) S
|
nr_neigh_for_each(a,
- b,
c) S
|
nr_neigh_for_each_safe(a,
- b,
c, d) S
|
nr_node_for_each(a,
- b,
c) S
|
nr_node_for_each_safe(a,
- b,
c, d) S
|
- for_each_gfn_sp(a, c, d, b) S
+ for_each_gfn_sp(a, c, d) S
|
- for_each_gfn_indirect_valid_sp(a, c, d, b) S
+ for_each_gfn_indirect_valid_sp(a, c, d) S
|
for_each_host(a,
- b,
c) S
|
for_each_host_safe(a,
- b,
c, d) S
|
for_each_mesh_entry(a,
- b,
c, d) S
)
...+>
[akpm@linux-foundation.org: drop bogus change from net/ipv4/raw.c]
[akpm@linux-foundation.org: drop bogus hunk from net/ipv6/raw.c]
[akpm@linux-foundation.org: checkpatch fixes]
[akpm@linux-foundation.org: fix warnings]
[akpm@linux-foudnation.org: redo intrusive kvm changes]
Tested-by: Peter Senna Tschudin <peter.senna@gmail.com>
Acked-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
Signed-off-by: Sasha Levin <sasha.levin@oracle.com>
Cc: Wu Fengguang <fengguang.wu@intel.com>
Cc: Marcelo Tosatti <mtosatti@redhat.com>
Cc: Gleb Natapov <gleb@redhat.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2013-02-28 01:06:00 +00:00
|
|
|
#define ax25_for_each(__ax25, list) \
|
|
|
|
hlist_for_each_entry(__ax25, list, ax25_node)
|
2005-04-16 22:20:36 +00:00
|
|
|
|
|
|
|
#define ax25_cb_hold(__ax25) \
|
2017-07-04 12:53:31 +00:00
|
|
|
refcount_inc(&((__ax25)->refcount))
|
2005-04-16 22:20:36 +00:00
|
|
|
|
|
|
|
static __inline__ void ax25_cb_put(ax25_cb *ax25)
|
|
|
|
{
|
2017-07-04 12:53:31 +00:00
|
|
|
if (refcount_dec_and_test(&ax25->refcount)) {
|
2005-10-28 20:53:13 +00:00
|
|
|
kfree(ax25->digipeat);
|
2005-04-16 22:20:36 +00:00
|
|
|
kfree(ax25);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-02-03 15:08:11 +00:00
|
|
|
static inline void ax25_dev_hold(ax25_dev *ax25_dev)
|
|
|
|
{
|
|
|
|
refcount_inc(&ax25_dev->refcount);
|
|
|
|
}
|
ax25: add refcount in ax25_dev to avoid UAF bugs
If we dereference ax25_dev after we call kfree(ax25_dev) in
ax25_dev_device_down(), it will lead to concurrency UAF bugs.
There are eight syscall functions suffer from UAF bugs, include
ax25_bind(), ax25_release(), ax25_connect(), ax25_ioctl(),
ax25_getname(), ax25_sendmsg(), ax25_getsockopt() and
ax25_info_show().
One of the concurrency UAF can be shown as below:
(USE) | (FREE)
| ax25_device_event
| ax25_dev_device_down
ax25_bind | ...
... | kfree(ax25_dev)
ax25_fillin_cb() | ...
ax25_fillin_cb_from_dev() |
... |
The root cause of UAF bugs is that kfree(ax25_dev) in
ax25_dev_device_down() is not protected by any locks.
When ax25_dev, which there are still pointers point to,
is released, the concurrency UAF bug will happen.
This patch introduces refcount into ax25_dev in order to
guarantee that there are no pointers point to it when ax25_dev
is released.
Signed-off-by: Duoming Zhou <duoming@zju.edu.cn>
Signed-off-by: David S. Miller <davem@davemloft.net>
2022-01-28 04:47:16 +00:00
|
|
|
|
2022-02-03 15:08:11 +00:00
|
|
|
static inline void ax25_dev_put(ax25_dev *ax25_dev)
|
ax25: add refcount in ax25_dev to avoid UAF bugs
If we dereference ax25_dev after we call kfree(ax25_dev) in
ax25_dev_device_down(), it will lead to concurrency UAF bugs.
There are eight syscall functions suffer from UAF bugs, include
ax25_bind(), ax25_release(), ax25_connect(), ax25_ioctl(),
ax25_getname(), ax25_sendmsg(), ax25_getsockopt() and
ax25_info_show().
One of the concurrency UAF can be shown as below:
(USE) | (FREE)
| ax25_device_event
| ax25_dev_device_down
ax25_bind | ...
... | kfree(ax25_dev)
ax25_fillin_cb() | ...
ax25_fillin_cb_from_dev() |
... |
The root cause of UAF bugs is that kfree(ax25_dev) in
ax25_dev_device_down() is not protected by any locks.
When ax25_dev, which there are still pointers point to,
is released, the concurrency UAF bug will happen.
This patch introduces refcount into ax25_dev in order to
guarantee that there are no pointers point to it when ax25_dev
is released.
Signed-off-by: Duoming Zhou <duoming@zju.edu.cn>
Signed-off-by: David S. Miller <davem@davemloft.net>
2022-01-28 04:47:16 +00:00
|
|
|
{
|
|
|
|
if (refcount_dec_and_test(&ax25_dev->refcount)) {
|
|
|
|
kfree(ax25_dev);
|
|
|
|
}
|
|
|
|
}
|
2005-06-20 20:31:11 +00:00
|
|
|
static inline __be16 ax25_type_trans(struct sk_buff *skb, struct net_device *dev)
|
2005-04-25 01:53:06 +00:00
|
|
|
{
|
|
|
|
skb->dev = dev;
|
2007-03-19 22:30:44 +00:00
|
|
|
skb_reset_mac_header(skb);
|
2005-04-25 01:53:06 +00:00
|
|
|
skb->pkt_type = PACKET_HOST;
|
|
|
|
return htons(ETH_P_AX25);
|
|
|
|
}
|
|
|
|
|
2005-04-16 22:20:36 +00:00
|
|
|
/* af_ax25.c */
|
|
|
|
extern struct hlist_head ax25_list;
|
|
|
|
extern spinlock_t ax25_list_lock;
|
2013-08-01 00:31:36 +00:00
|
|
|
void ax25_cb_add(ax25_cb *);
|
2005-04-16 22:20:36 +00:00
|
|
|
struct sock *ax25_find_listener(ax25_address *, int, struct net_device *, int);
|
|
|
|
struct sock *ax25_get_socket(ax25_address *, ax25_address *, int);
|
2021-10-12 15:58:35 +00:00
|
|
|
ax25_cb *ax25_find_cb(const ax25_address *, ax25_address *, ax25_digi *,
|
2013-08-01 00:31:36 +00:00
|
|
|
struct net_device *);
|
|
|
|
void ax25_send_to_raw(ax25_address *, struct sk_buff *, int);
|
|
|
|
void ax25_destroy_socket(ax25_cb *);
|
|
|
|
ax25_cb * __must_check ax25_create_cb(void);
|
|
|
|
void ax25_fillin_cb(ax25_cb *, ax25_dev *);
|
|
|
|
struct sock *ax25_make_new(struct sock *, struct ax25_dev *);
|
2005-04-16 22:20:36 +00:00
|
|
|
|
|
|
|
/* ax25_addr.c */
|
2006-12-07 23:47:08 +00:00
|
|
|
extern const ax25_address ax25_bcast;
|
|
|
|
extern const ax25_address ax25_defaddr;
|
|
|
|
extern const ax25_address null_ax25_address;
|
2013-08-01 00:31:36 +00:00
|
|
|
char *ax2asc(char *buf, const ax25_address *);
|
|
|
|
void asc2ax(ax25_address *addr, const char *callsign);
|
|
|
|
int ax25cmp(const ax25_address *, const ax25_address *);
|
|
|
|
int ax25digicmp(const ax25_digi *, const ax25_digi *);
|
|
|
|
const unsigned char *ax25_addr_parse(const unsigned char *, int,
|
2006-12-07 23:43:13 +00:00
|
|
|
ax25_address *, ax25_address *, ax25_digi *, int *, int *);
|
2013-08-01 00:31:36 +00:00
|
|
|
int ax25_addr_build(unsigned char *, const ax25_address *,
|
|
|
|
const ax25_address *, const ax25_digi *, int, int);
|
|
|
|
int ax25_addr_size(const ax25_digi *);
|
|
|
|
void ax25_digi_invert(const ax25_digi *, ax25_digi *);
|
2005-04-16 22:20:36 +00:00
|
|
|
|
|
|
|
/* ax25_dev.c */
|
|
|
|
extern ax25_dev *ax25_dev_list;
|
|
|
|
extern spinlock_t ax25_dev_lock;
|
|
|
|
|
2018-02-13 16:52:01 +00:00
|
|
|
#if IS_ENABLED(CONFIG_AX25)
|
2005-04-16 22:20:36 +00:00
|
|
|
static inline ax25_dev *ax25_dev_ax25dev(struct net_device *dev)
|
|
|
|
{
|
|
|
|
return dev->ax25_ptr;
|
|
|
|
}
|
2018-02-13 16:52:01 +00:00
|
|
|
#endif
|
2005-04-16 22:20:36 +00:00
|
|
|
|
2013-08-01 00:31:36 +00:00
|
|
|
ax25_dev *ax25_addr_ax25dev(ax25_address *);
|
|
|
|
void ax25_dev_device_up(struct net_device *);
|
|
|
|
void ax25_dev_device_down(struct net_device *);
|
|
|
|
int ax25_fwd_ioctl(unsigned int, struct ax25_fwd_struct *);
|
|
|
|
struct net_device *ax25_fwd_dev(struct net_device *);
|
|
|
|
void ax25_dev_free(void);
|
2005-04-16 22:20:36 +00:00
|
|
|
|
|
|
|
/* ax25_ds_in.c */
|
2013-08-01 00:31:36 +00:00
|
|
|
int ax25_ds_frame_in(ax25_cb *, struct sk_buff *, int);
|
2005-04-16 22:20:36 +00:00
|
|
|
|
|
|
|
/* ax25_ds_subr.c */
|
2013-08-01 00:31:36 +00:00
|
|
|
void ax25_ds_nr_error_recovery(ax25_cb *);
|
|
|
|
void ax25_ds_enquiry_response(ax25_cb *);
|
|
|
|
void ax25_ds_establish_data_link(ax25_cb *);
|
|
|
|
void ax25_dev_dama_off(ax25_dev *);
|
|
|
|
void ax25_dama_on(ax25_cb *);
|
|
|
|
void ax25_dama_off(ax25_cb *);
|
2005-04-16 22:20:36 +00:00
|
|
|
|
|
|
|
/* ax25_ds_timer.c */
|
2013-08-01 00:31:36 +00:00
|
|
|
void ax25_ds_setup_timer(ax25_dev *);
|
|
|
|
void ax25_ds_set_timer(ax25_dev *);
|
|
|
|
void ax25_ds_del_timer(ax25_dev *);
|
|
|
|
void ax25_ds_timer(ax25_cb *);
|
|
|
|
void ax25_ds_t1_timeout(ax25_cb *);
|
|
|
|
void ax25_ds_heartbeat_expiry(ax25_cb *);
|
|
|
|
void ax25_ds_t3timer_expiry(ax25_cb *);
|
|
|
|
void ax25_ds_idletimer_expiry(ax25_cb *);
|
2005-04-16 22:20:36 +00:00
|
|
|
|
|
|
|
/* ax25_iface.c */
|
2006-12-14 23:50:01 +00:00
|
|
|
|
|
|
|
struct ax25_protocol {
|
|
|
|
struct ax25_protocol *next;
|
|
|
|
unsigned int pid;
|
|
|
|
int (*func)(struct sk_buff *, ax25_cb *);
|
|
|
|
};
|
|
|
|
|
2013-08-01 00:31:36 +00:00
|
|
|
void ax25_register_pid(struct ax25_protocol *ap);
|
|
|
|
void ax25_protocol_release(unsigned int);
|
2006-12-14 23:51:23 +00:00
|
|
|
|
|
|
|
struct ax25_linkfail {
|
|
|
|
struct hlist_node lf_node;
|
|
|
|
void (*func)(ax25_cb *, int);
|
|
|
|
};
|
|
|
|
|
2013-08-01 00:31:36 +00:00
|
|
|
void ax25_linkfail_register(struct ax25_linkfail *lf);
|
|
|
|
void ax25_linkfail_release(struct ax25_linkfail *lf);
|
2021-10-12 15:58:35 +00:00
|
|
|
int __must_check ax25_listen_register(const ax25_address *,
|
|
|
|
struct net_device *);
|
|
|
|
void ax25_listen_release(const ax25_address *, struct net_device *);
|
2013-08-01 00:31:36 +00:00
|
|
|
int(*ax25_protocol_function(unsigned int))(struct sk_buff *, ax25_cb *);
|
2021-10-12 15:58:35 +00:00
|
|
|
int ax25_listen_mine(const ax25_address *, struct net_device *);
|
2013-08-01 00:31:36 +00:00
|
|
|
void ax25_link_failed(ax25_cb *, int);
|
|
|
|
int ax25_protocol_is_registered(unsigned int);
|
2005-04-16 22:20:36 +00:00
|
|
|
|
|
|
|
/* ax25_in.c */
|
2013-08-01 00:31:36 +00:00
|
|
|
int ax25_rx_iframe(ax25_cb *, struct sk_buff *);
|
|
|
|
int ax25_kiss_rcv(struct sk_buff *, struct net_device *, struct packet_type *,
|
|
|
|
struct net_device *);
|
2005-04-16 22:20:36 +00:00
|
|
|
|
|
|
|
/* ax25_ip.c */
|
2015-03-03 15:41:47 +00:00
|
|
|
netdev_tx_t ax25_ip_xmit(struct sk_buff *skb);
|
2007-10-09 08:40:57 +00:00
|
|
|
extern const struct header_ops ax25_header_ops;
|
2005-04-16 22:20:36 +00:00
|
|
|
|
|
|
|
/* ax25_out.c */
|
2021-10-12 15:58:35 +00:00
|
|
|
ax25_cb *ax25_send_frame(struct sk_buff *, int, const ax25_address *,
|
|
|
|
ax25_address *, ax25_digi *, struct net_device *);
|
2013-08-01 00:31:36 +00:00
|
|
|
void ax25_output(ax25_cb *, int, struct sk_buff *);
|
|
|
|
void ax25_kick(ax25_cb *);
|
|
|
|
void ax25_transmit_buffer(ax25_cb *, struct sk_buff *, int);
|
|
|
|
void ax25_queue_xmit(struct sk_buff *skb, struct net_device *dev);
|
|
|
|
int ax25_check_iframes_acked(ax25_cb *, unsigned short);
|
2005-04-16 22:20:36 +00:00
|
|
|
|
|
|
|
/* ax25_route.c */
|
2013-08-01 00:31:36 +00:00
|
|
|
void ax25_rt_device_down(struct net_device *);
|
|
|
|
int ax25_rt_ioctl(unsigned int, void __user *);
|
2018-04-13 17:44:18 +00:00
|
|
|
extern const struct seq_operations ax25_rt_seqops;
|
2013-08-01 00:31:36 +00:00
|
|
|
ax25_route *ax25_get_route(ax25_address *addr, struct net_device *dev);
|
|
|
|
int ax25_rt_autobind(ax25_cb *, ax25_address *);
|
|
|
|
struct sk_buff *ax25_rt_build_path(struct sk_buff *, ax25_address *,
|
|
|
|
ax25_address *, ax25_digi *);
|
|
|
|
void ax25_rt_free(void);
|
2005-04-16 22:20:36 +00:00
|
|
|
|
|
|
|
/* ax25_std_in.c */
|
2013-08-01 00:31:36 +00:00
|
|
|
int ax25_std_frame_in(ax25_cb *, struct sk_buff *, int);
|
2005-04-16 22:20:36 +00:00
|
|
|
|
|
|
|
/* ax25_std_subr.c */
|
2013-08-01 00:31:36 +00:00
|
|
|
void ax25_std_nr_error_recovery(ax25_cb *);
|
|
|
|
void ax25_std_establish_data_link(ax25_cb *);
|
|
|
|
void ax25_std_transmit_enquiry(ax25_cb *);
|
|
|
|
void ax25_std_enquiry_response(ax25_cb *);
|
|
|
|
void ax25_std_timeout_response(ax25_cb *);
|
2005-04-16 22:20:36 +00:00
|
|
|
|
|
|
|
/* ax25_std_timer.c */
|
2013-08-01 00:31:36 +00:00
|
|
|
void ax25_std_heartbeat_expiry(ax25_cb *);
|
|
|
|
void ax25_std_t1timer_expiry(ax25_cb *);
|
|
|
|
void ax25_std_t2timer_expiry(ax25_cb *);
|
|
|
|
void ax25_std_t3timer_expiry(ax25_cb *);
|
|
|
|
void ax25_std_idletimer_expiry(ax25_cb *);
|
2005-04-16 22:20:36 +00:00
|
|
|
|
|
|
|
/* ax25_subr.c */
|
2013-08-01 00:31:36 +00:00
|
|
|
void ax25_clear_queues(ax25_cb *);
|
|
|
|
void ax25_frames_acked(ax25_cb *, unsigned short);
|
|
|
|
void ax25_requeue_frames(ax25_cb *);
|
|
|
|
int ax25_validate_nr(ax25_cb *, unsigned short);
|
|
|
|
int ax25_decode(ax25_cb *, struct sk_buff *, int *, int *, int *);
|
|
|
|
void ax25_send_control(ax25_cb *, int, int, int);
|
|
|
|
void ax25_return_dm(struct net_device *, ax25_address *, ax25_address *,
|
|
|
|
ax25_digi *);
|
|
|
|
void ax25_calculate_t1(ax25_cb *);
|
|
|
|
void ax25_calculate_rtt(ax25_cb *);
|
|
|
|
void ax25_disconnect(ax25_cb *, int);
|
2005-04-16 22:20:36 +00:00
|
|
|
|
|
|
|
/* ax25_timer.c */
|
2013-08-01 00:31:36 +00:00
|
|
|
void ax25_setup_timers(ax25_cb *);
|
|
|
|
void ax25_start_heartbeat(ax25_cb *);
|
|
|
|
void ax25_start_t1timer(ax25_cb *);
|
|
|
|
void ax25_start_t2timer(ax25_cb *);
|
|
|
|
void ax25_start_t3timer(ax25_cb *);
|
|
|
|
void ax25_start_idletimer(ax25_cb *);
|
|
|
|
void ax25_stop_heartbeat(ax25_cb *);
|
|
|
|
void ax25_stop_t1timer(ax25_cb *);
|
|
|
|
void ax25_stop_t2timer(ax25_cb *);
|
|
|
|
void ax25_stop_t3timer(ax25_cb *);
|
|
|
|
void ax25_stop_idletimer(ax25_cb *);
|
|
|
|
int ax25_t1timer_running(ax25_cb *);
|
|
|
|
unsigned long ax25_display_timer(struct timer_list *);
|
2005-04-16 22:20:36 +00:00
|
|
|
|
|
|
|
/* ax25_uid.c */
|
|
|
|
extern int ax25_uid_policy;
|
2013-08-01 00:31:36 +00:00
|
|
|
ax25_uid_assoc *ax25_findbyuid(kuid_t);
|
|
|
|
int __must_check ax25_uid_ioctl(int, struct sockaddr_ax25 *);
|
2018-04-13 17:44:18 +00:00
|
|
|
extern const struct seq_operations ax25_uid_seqops;
|
2013-08-01 00:31:36 +00:00
|
|
|
void ax25_uid_free(void);
|
2005-04-16 22:20:36 +00:00
|
|
|
|
|
|
|
/* sysctl_net_ax25.c */
|
|
|
|
#ifdef CONFIG_SYSCTL
|
2013-08-01 00:31:36 +00:00
|
|
|
int ax25_register_dev_sysctl(ax25_dev *ax25_dev);
|
|
|
|
void ax25_unregister_dev_sysctl(ax25_dev *ax25_dev);
|
2005-04-16 22:20:36 +00:00
|
|
|
#else
|
2012-04-23 14:25:49 +00:00
|
|
|
static inline int ax25_register_dev_sysctl(ax25_dev *ax25_dev) { return 0; }
|
|
|
|
static inline void ax25_unregister_dev_sysctl(ax25_dev *ax25_dev) {}
|
2005-04-16 22:20:36 +00:00
|
|
|
#endif /* CONFIG_SYSCTL */
|
|
|
|
|
|
|
|
#endif
|