tipc: Fix skb_under_panic when configuring TIPC without privileges
This patch prevents a TIPC configuration command requiring network administrator privileges from triggering an skbuff underrun if it is issued by a process lacking those privileges. The revised error handling code avoids the use of a potentially uninitialized global variable by transforming the unauthorized command into a new command, then following the standard command processing path to generate the required error message. Signed-off-by: Allan Stephens <allan.stephens@windriver.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
dc58c78c04
commit
59f0c4523f
3 changed files with 23 additions and 9 deletions
|
@ -2,7 +2,7 @@
|
||||||
* include/linux/tipc_config.h: Include file for TIPC configuration interface
|
* include/linux/tipc_config.h: Include file for TIPC configuration interface
|
||||||
*
|
*
|
||||||
* Copyright (c) 2003-2006, Ericsson AB
|
* Copyright (c) 2003-2006, Ericsson AB
|
||||||
* Copyright (c) 2005, Wind River Systems
|
* Copyright (c) 2005-2007, Wind River Systems
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
@ -135,6 +135,14 @@
|
||||||
#define TIPC_CMD_SET_MAX_SLAVES 0x800A /* tx unsigned, rx none */
|
#define TIPC_CMD_SET_MAX_SLAVES 0x800A /* tx unsigned, rx none */
|
||||||
#define TIPC_CMD_SET_NETID 0x800B /* tx unsigned, rx none */
|
#define TIPC_CMD_SET_NETID 0x800B /* tx unsigned, rx none */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Reserved commands:
|
||||||
|
* May not be issued by any process.
|
||||||
|
* Used internally by TIPC.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define TIPC_CMD_NOT_NET_ADMIN 0xC001 /* tx none, rx none */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* TLV types defined for TIPC
|
* TLV types defined for TIPC
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
* net/tipc/config.c: TIPC configuration management code
|
* net/tipc/config.c: TIPC configuration management code
|
||||||
*
|
*
|
||||||
* Copyright (c) 2002-2006, Ericsson AB
|
* Copyright (c) 2002-2006, Ericsson AB
|
||||||
* Copyright (c) 2004-2006, Wind River Systems
|
* Copyright (c) 2004-2007, Wind River Systems
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
@ -602,6 +602,10 @@ struct sk_buff *tipc_cfg_do_cmd(u32 orig_node, u16 cmd, const void *request_area
|
||||||
case TIPC_CMD_GET_NETID:
|
case TIPC_CMD_GET_NETID:
|
||||||
rep_tlv_buf = tipc_cfg_reply_unsigned(tipc_net_id);
|
rep_tlv_buf = tipc_cfg_reply_unsigned(tipc_net_id);
|
||||||
break;
|
break;
|
||||||
|
case TIPC_CMD_NOT_NET_ADMIN:
|
||||||
|
rep_tlv_buf =
|
||||||
|
tipc_cfg_reply_error_string(TIPC_CFG_NOT_NET_ADMIN);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
rep_tlv_buf = tipc_cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED
|
rep_tlv_buf = tipc_cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED
|
||||||
" (unknown command)");
|
" (unknown command)");
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
* net/tipc/netlink.c: TIPC configuration handling
|
* net/tipc/netlink.c: TIPC configuration handling
|
||||||
*
|
*
|
||||||
* Copyright (c) 2005-2006, Ericsson AB
|
* Copyright (c) 2005-2006, Ericsson AB
|
||||||
* Copyright (c) 2005, Wind River Systems
|
* Copyright (c) 2005-2007, Wind River Systems
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
@ -45,15 +45,17 @@ static int handle_cmd(struct sk_buff *skb, struct genl_info *info)
|
||||||
struct nlmsghdr *req_nlh = info->nlhdr;
|
struct nlmsghdr *req_nlh = info->nlhdr;
|
||||||
struct tipc_genlmsghdr *req_userhdr = info->userhdr;
|
struct tipc_genlmsghdr *req_userhdr = info->userhdr;
|
||||||
int hdr_space = NLMSG_SPACE(GENL_HDRLEN + TIPC_GENL_HDRLEN);
|
int hdr_space = NLMSG_SPACE(GENL_HDRLEN + TIPC_GENL_HDRLEN);
|
||||||
|
u16 cmd;
|
||||||
|
|
||||||
if ((req_userhdr->cmd & 0xC000) && (!capable(CAP_NET_ADMIN)))
|
if ((req_userhdr->cmd & 0xC000) && (!capable(CAP_NET_ADMIN)))
|
||||||
rep_buf = tipc_cfg_reply_error_string(TIPC_CFG_NOT_NET_ADMIN);
|
cmd = TIPC_CMD_NOT_NET_ADMIN;
|
||||||
else
|
else
|
||||||
rep_buf = tipc_cfg_do_cmd(req_userhdr->dest,
|
cmd = req_userhdr->cmd;
|
||||||
req_userhdr->cmd,
|
|
||||||
NLMSG_DATA(req_nlh) + GENL_HDRLEN + TIPC_GENL_HDRLEN,
|
rep_buf = tipc_cfg_do_cmd(req_userhdr->dest, cmd,
|
||||||
NLMSG_PAYLOAD(req_nlh, GENL_HDRLEN + TIPC_GENL_HDRLEN),
|
NLMSG_DATA(req_nlh) + GENL_HDRLEN + TIPC_GENL_HDRLEN,
|
||||||
hdr_space);
|
NLMSG_PAYLOAD(req_nlh, GENL_HDRLEN + TIPC_GENL_HDRLEN),
|
||||||
|
hdr_space);
|
||||||
|
|
||||||
if (rep_buf) {
|
if (rep_buf) {
|
||||||
skb_push(rep_buf, hdr_space);
|
skb_push(rep_buf, hdr_space);
|
||||||
|
|
Loading…
Reference in a new issue