qcacmn: Add support to use generic netlink sockets for userspace apps

Currently user space communication functions[cnss diag, PTT socket app]
in host driver uses netlink user sockets which is a security concern from
Linux Android SE policies.

Add support for to use netlink family cld80211 which uses generic
netlink sockets.

Change-Id: Ia833249c1f312415e38563d90214979cea3d9f0e
CRs-Fixed: 2015931
This commit is contained in:
Selvaraj, Sridhar 2017-03-07 16:59:51 +05:30 • committed by Sandeep Puligilla
commit 7c6b935c64
6 changed files with 555 additions and 40 deletions

View file

@ -119,6 +119,19 @@ typedef struct sAniAppRegReq {
tAniNlModTypes type; /* module id */
int pid; /* process id */
} tAniNlAppRegReq;
/**
* struct sptt_app_reg_req - PTT register request structure
* @radio: Radio ID
* @wmsg: ANI header
*
* payload structure received as nl data from PTT app/user space
*/
typedef struct sptt_app_reg_req {
int radio;
tAniHdr wmsg;
} ptt_app_reg_req;
typedef struct sAniNlAppRegRsp {
tAniHdr wniHdr; /* Generic WNI msg header */
tAniNlAppRegReq regReq; /* The original request msg */

View file

@ -39,6 +39,14 @@
#include <qdf_types.h>
#include <qdf_trace.h>
#ifdef CNSS_GENL
#include <net/cnss_nl.h>
#else
/** ptt Process ID */
static int32_t ptt_pid = INVALID_PID;
#endif
#define PTT_SOCK_DEBUG
#ifdef PTT_SOCK_DEBUG
#define PTT_TRACE(level, args ...) QDF_TRACE(QDF_MODULE_ID_QDF, level, ## args)
@ -46,9 +54,6 @@
#define PTT_TRACE(level, args ...)
#endif
/** ptt Process ID */
static int32_t ptt_pid = INVALID_PID;
#ifdef PTT_SOCK_DEBUG_VERBOSE
/* Utility function to perform a hex dump */
static void ptt_sock_dump_buf(const unsigned char *pbuf, int cnt)
@ -66,6 +71,45 @@ static void ptt_sock_dump_buf(const unsigned char *pbuf, int cnt)
}
#endif
/**
* nl_srv_ucast_ptt() - Wrapper function to send ucast msgs to PTT
* @skb: sk buffer pointer
* @dst_pid: Destination PID
* @flag: flags
*
* Sends the ucast message to PTT with generic nl socket if CNSS_GENL
* is enabled. Else, use the legacy netlink socket to send.
*
* Return: zero on success, error code otherwise
*/
static int nl_srv_ucast_ptt(struct sk_buff *skb, int dst_pid, int flag)
{
#ifdef CNSS_GENL
return nl_srv_ucast(skb, dst_pid, flag, ANI_NL_MSG_PUMAC,
CLD80211_MCGRP_DIAG_EVENTS);
#else
return nl_srv_ucast(skb, dst_pid, flag);
#endif
}
/**
* nl_srv_bcast_ptt() - Wrapper function to send bcast msgs to DIAG mcast group
* @skb: sk buffer pointer
*
* Sends the bcast message to DIAG multicast group with generic nl socket
* if CNSS_GENL is enabled. Else, use the legacy netlink socket to send.
*
* Return: zero on success, error code otherwise
*/
static int nl_srv_bcast_ptt(struct sk_buff *skb)
{
#ifdef CNSS_GENL
return nl_srv_bcast(skb, CLD80211_MCGRP_DIAG_EVENTS, ANI_NL_MSG_PUMAC);
#else
return nl_srv_bcast(skb);
#endif
}
/**
* ptt_sock_send_msg_to_app() - Send nl message to user space
* wmsg: Message header
@ -121,9 +165,9 @@ int ptt_sock_send_msg_to_app(tAniHdr *wmsg, int radio, int src_mod, int pid)
#endif
if (pid != INVALID_PID)
err = nl_srv_ucast(skb, pid, MSG_DONTWAIT);
err = nl_srv_ucast_ptt(skb, pid, MSG_DONTWAIT);
else
err = nl_srv_bcast(skb);
err = nl_srv_bcast_ptt(skb);
if (err)
PTT_TRACE(QDF_TRACE_LEVEL_INFO,
@ -132,6 +176,7 @@ int ptt_sock_send_msg_to_app(tAniHdr *wmsg, int radio, int src_mod, int pid)
return err;
}
#ifndef CNSS_GENL
/*
* Process tregisteration request and send registration response messages
* to the PTT Socket App in user space
@ -204,6 +249,73 @@ static int ptt_sock_rx_nlink_msg(struct sk_buff *skb)
}
return 0;
}
#endif
#ifdef CNSS_GENL
/**
* ptt_cmd_handler() - Handler function for PTT commands
* @data: Data to be parsed
* @data_len: Length of the data received
* @ctx: Registered context reference
* @pid: Process id of the user space application
*
* This function handles the command from PTT user space application
*
* Return: None
*/
static void ptt_cmd_handler(const void *data, int data_len, void *ctx, int pid)
{
ptt_app_reg_req *payload;
struct nlattr *tb[CLD80211_ATTR_MAX + 1];
if (nla_parse(tb, CLD80211_ATTR_MAX, data, data_len, NULL)) {
PTT_TRACE(QDF_TRACE_LEVEL_ERROR, "Invalid ATTR");
return;
}
if (!tb[CLD80211_ATTR_DATA]) {
PTT_TRACE(QDF_TRACE_LEVEL_ERROR, "attr ATTR_DATA failed");
return;
}
payload = (ptt_app_reg_req *)(nla_data(tb[CLD80211_ATTR_DATA]));
switch (payload->wmsg.type) {
case ANI_MSG_APP_REG_REQ:
ptt_sock_send_msg_to_app(&payload->wmsg, payload->radio,
ANI_NL_MSG_PUMAC, pid);
break;
default:
PTT_TRACE(QDF_TRACE_LEVEL_ERROR, "Unknown msg type %d",
payload->wmsg.type);
break;
}
}
/**
* ptt_sock_activate_svc() - API to register PTT/PUMAC command handler
*
* API to register the PTT/PUMAC command handlers. Argument @pAdapter
* is sent for prototype compatibility between new genl and legacy
* implementation
*
* Return: 0
*/
int ptt_sock_activate_svc(void)
{
register_cld_cmd_cb(ANI_NL_MSG_PUMAC, ptt_cmd_handler, NULL);
register_cld_cmd_cb(ANI_NL_MSG_PTT, ptt_cmd_handler, NULL);
return 0;
}
/**
* ptt_sock_deactivate_svc() - Dummy API to deactivate PTT service
*
* Return: Void
*/
void ptt_sock_deactivate_svc(void)
{
}
#else
/**
* ptt_sock_activate_svc() - activate PTT service
@ -227,5 +339,5 @@ void ptt_sock_deactivate_svc(void)
{
ptt_pid = INVALID_PID;
}
#endif
#endif /* PTT_SOCK_SVC_ENABLE */