Revision 9c1c2b35f1d94de8325344c2777d7ee67492db3b authored by Jeff Layton on 03 April 2019, 17:16:01 UTC, committed by Ilya Dryomov on 21 January 2020, 18:02:37 UTC
Currently, we just assume that it will stick around by virtue of the
submitter's reference, but later patches will allow the syscall to
return early and we can't rely on that reference at that point.

While I'm not aware of any reports of it, Xiubo pointed out that this
may fix a use-after-free.  If the wait for a reply times out or is
canceled via signal, and then the reply comes in after the syscall
returns, the client can end up trying to access r_parent without a
reference.

Take an extra reference to the inode when setting r_parent and release
it when releasing the request.

Cc: stable@vger.kernel.org
Signed-off-by: Jeff Layton <jlayton@kernel.org>
Reviewed-by: "Yan, Zheng" <zyan@redhat.com>
Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
1 parent def9d27
Raw File
br_private_stp.h
/* SPDX-License-Identifier: GPL-2.0-or-later */
/*
 *	Linux ethernet bridge
 *
 *	Authors:
 *	Lennert Buytenhek		<buytenh@gnu.org>
 */

#ifndef _BR_PRIVATE_STP_H
#define _BR_PRIVATE_STP_H

#define BPDU_TYPE_CONFIG 0
#define BPDU_TYPE_TCN 0x80

/* IEEE 802.1D-1998 timer values */
#define BR_MIN_HELLO_TIME	(1*HZ)
#define BR_MAX_HELLO_TIME	(10*HZ)

#define BR_MIN_FORWARD_DELAY	(2*HZ)
#define BR_MAX_FORWARD_DELAY	(30*HZ)

#define BR_MIN_MAX_AGE		(6*HZ)
#define BR_MAX_MAX_AGE		(40*HZ)

#define BR_MIN_PATH_COST	1
#define BR_MAX_PATH_COST	65535

struct br_config_bpdu {
	unsigned int	topology_change:1;
	unsigned int	topology_change_ack:1;
	bridge_id	root;
	int		root_path_cost;
	bridge_id	bridge_id;
	port_id		port_id;
	int		message_age;
	int		max_age;
	int		hello_time;
	int		forward_delay;
};

/* called under bridge lock */
static inline int br_is_designated_port(const struct net_bridge_port *p)
{
	return !memcmp(&p->designated_bridge, &p->br->bridge_id, 8) &&
		(p->designated_port == p->port_id);
}


/* br_stp.c */
void br_become_root_bridge(struct net_bridge *br);
void br_config_bpdu_generation(struct net_bridge *);
void br_configuration_update(struct net_bridge *);
void br_port_state_selection(struct net_bridge *);
void br_received_config_bpdu(struct net_bridge_port *p,
			     const struct br_config_bpdu *bpdu);
void br_received_tcn_bpdu(struct net_bridge_port *p);
void br_transmit_config(struct net_bridge_port *p);
void br_transmit_tcn(struct net_bridge *br);
void br_topology_change_detection(struct net_bridge *br);
void __br_set_topology_change(struct net_bridge *br, unsigned char val);

/* br_stp_bpdu.c */
void br_send_config_bpdu(struct net_bridge_port *, struct br_config_bpdu *);
void br_send_tcn_bpdu(struct net_bridge_port *);

#endif
back to top