Loading drivers/rpmsg/qcom_glink_native.c +72 −1 Original line number Diff line number Diff line Loading @@ -28,10 +28,33 @@ #include <linux/slab.h> #include <linux/workqueue.h> #include <linux/mailbox_client.h> #include <linux/ipc_logging.h> #include "rpmsg_internal.h" #include "qcom_glink_native.h" #define GLINK_LOG_PAGE_CNT 2 #define GLINK_INFO(ctxt, x, ...) \ do { \ if (ctxt) \ ipc_log_string(ctxt, "[%s]: "x, __func__, ##__VA_ARGS__); \ } while (0) #define CH_INFO(ch, x, ...) \ do { \ if (ch->glink && ch->glink->ilc) \ ipc_log_string(ch->glink->ilc, "%s[%d:%d] %s: "x, ch->name, \ ch->lcid, ch->rcid, __func__, ##__VA_ARGS__); \ } while (0) #define GLINK_ERR(ctxt, x, ...) \ do { \ pr_err_ratelimited("[%s]: "x, __func__, ##__VA_ARGS__); \ if (ctxt) \ ipc_log_string(ctxt, "[%s]: "x, __func__, ##__VA_ARGS__); \ } while (0) #define GLINK_NAME_SIZE 32 #define GLINK_VERSION_1 1 Loading Loading @@ -98,6 +121,7 @@ struct glink_core_rx_intent { * @idr_lock: synchronizes @lcids and @rcids modifications * @lcids: idr of all channels with a known local channel id * @rcids: idr of all channels with a known remote channel id * @ilc: ipc logging context reference */ struct qcom_glink { struct device *dev; Loading @@ -124,6 +148,8 @@ struct qcom_glink { unsigned long features; bool intentless; void *ilc; }; enum { Loading Loading @@ -256,6 +282,7 @@ static void qcom_glink_channel_release(struct kref *ref) refcount); unsigned long flags; CH_INFO(channel, "\n"); spin_lock_irqsave(&channel->intent_lock, flags); idr_destroy(&channel->liids); idr_destroy(&channel->riids); Loading Loading @@ -340,6 +367,7 @@ static int qcom_glink_send_version(struct qcom_glink *glink) msg.param1 = cpu_to_le16(GLINK_VERSION_1); msg.param2 = cpu_to_le32(glink->features); GLINK_INFO(glink->ilc, "vers:%d features:%d\n", msg.param1, msg.param2); return qcom_glink_tx(glink, &msg, sizeof(msg), NULL, 0, true); } Loading @@ -351,6 +379,7 @@ static void qcom_glink_send_version_ack(struct qcom_glink *glink) msg.param1 = cpu_to_le16(GLINK_VERSION_1); msg.param2 = cpu_to_le32(glink->features); GLINK_INFO(glink->ilc, "vers:%d features:%d\n", msg.param1, msg.param2); qcom_glink_tx(glink, &msg, sizeof(msg), NULL, 0, true); } Loading @@ -363,6 +392,7 @@ static void qcom_glink_send_open_ack(struct qcom_glink *glink, msg.param1 = cpu_to_le16(channel->rcid); msg.param2 = cpu_to_le32(0); CH_INFO(channel, "\n"); qcom_glink_tx(glink, &msg, sizeof(msg), NULL, 0, true); } Loading @@ -382,6 +412,7 @@ static void qcom_glink_handle_intent_req_ack(struct qcom_glink *glink, channel->intent_req_result = granted; complete(&channel->intent_req_comp); CH_INFO(channel, "\n"); } /** Loading Loading @@ -417,6 +448,7 @@ static int qcom_glink_send_open_req(struct qcom_glink *glink, return ret; channel->lcid = ret; CH_INFO(channel, "\n"); req.msg.cmd = cpu_to_le16(RPM_CMD_OPEN); req.msg.param1 = cpu_to_le16(channel->lcid); Loading @@ -430,6 +462,8 @@ static int qcom_glink_send_open_req(struct qcom_glink *glink, return 0; remove_idr: CH_INFO(channel, "remote_idr\n"); spin_lock_irqsave(&glink->idr_lock, flags); idr_remove(&glink->lcids, channel->lcid); channel->lcid = 0; Loading @@ -447,6 +481,7 @@ static void qcom_glink_send_close_req(struct qcom_glink *glink, req.param1 = cpu_to_le16(channel->lcid); req.param2 = 0; CH_INFO(channel, "\n"); qcom_glink_tx(glink, &req, sizeof(req), NULL, 0, true); } Loading @@ -459,6 +494,7 @@ static void qcom_glink_send_close_ack(struct qcom_glink *glink, req.param1 = cpu_to_le16(rcid); req.param2 = 0; GLINK_INFO(glink->ilc, "rcid:%d\n", rcid); qcom_glink_tx(glink, &req, sizeof(req), NULL, 0, true); } Loading Loading @@ -490,6 +526,7 @@ static void qcom_glink_rx_done_work(struct work_struct *work) cmd.lcid = cid; cmd.liid = iid; CH_INFO(channel, "reuse:%d liid:%d", reuse, iid); qcom_glink_tx(glink, &cmd, sizeof(cmd), NULL, 0, true); if (!reuse) { kfree(intent->data); Loading Loading @@ -540,6 +577,8 @@ static void qcom_glink_receive_version(struct qcom_glink *glink, u32 version, u32 features) { GLINK_INFO(glink->ilc, "vers:%d features:%d\n", version, features); switch (version) { case 0: break; Loading Loading @@ -567,6 +606,8 @@ static void qcom_glink_receive_version_ack(struct qcom_glink *glink, u32 version, u32 features) { GLINK_INFO(glink->ilc, "vers:%d features:%d\n", version, features); switch (version) { case 0: /* Version negotiation failed */ Loading Loading @@ -602,6 +643,7 @@ static int qcom_glink_send_intent_req_ack(struct qcom_glink *glink, msg.param1 = cpu_to_le16(channel->lcid); msg.param2 = cpu_to_le32(granted); CH_INFO(channel, "\n"); qcom_glink_tx(glink, &msg, sizeof(msg), NULL, 0, true); return 0; Loading Loading @@ -635,6 +677,9 @@ static int qcom_glink_advertise_intent(struct qcom_glink *glink, cmd.size = cpu_to_le32(intent->size); cmd.liid = cpu_to_le32(intent->id); CH_INFO(channel, "count:%d size:%d liid:%d\n", 1, intent->size, intent->id); qcom_glink_tx(glink, &cmd, sizeof(cmd), NULL, 0, true); return 0; Loading Loading @@ -705,6 +750,7 @@ static void qcom_glink_handle_rx_done(struct qcom_glink *glink, } intent->in_use = false; CH_INFO(channel, "reuse:%d iid:%d\n", reuse, intent->id); if (!reuse) { idr_remove(&channel->riids, intent->id); Loading Loading @@ -818,6 +864,7 @@ static int qcom_glink_rx_data(struct qcom_glink *glink, size_t avail) /* Drop the message */ goto advance_rx; } CH_INFO(channel, "chunk_size:%d left_size:%d\n", chunk_size, left_size); if (glink->intentless) { /* Might have an ongoing, fragmented, message to append */ Loading Loading @@ -940,6 +987,8 @@ static void qcom_glink_handle_intent(struct qcom_glink *glink, intent->id = le32_to_cpu(msg->intents[i].iid); intent->size = le32_to_cpu(msg->intents[i].size); CH_INFO(channel, "riid:%d size:%d\n", intent->id, intent->size); spin_lock_irqsave(&channel->intent_lock, flags); ret = idr_alloc(&channel->riids, intent, intent->id, intent->id + 1, GFP_ATOMIC); Loading @@ -947,6 +996,7 @@ static void qcom_glink_handle_intent(struct qcom_glink *glink, if (ret < 0) dev_err(glink->dev, "failed to store remote intent\n"); } kfree(msg); Loading @@ -965,6 +1015,7 @@ static int qcom_glink_rx_open_ack(struct qcom_glink *glink, unsigned int lcid) return -EINVAL; } CH_INFO(channel, "\n"); complete(&channel->open_ack); return 0; Loading Loading @@ -1056,6 +1107,7 @@ static struct glink_channel *qcom_glink_create_local(struct qcom_glink *glink, if (IS_ERR(channel)) return ERR_CAST(channel); CH_INFO(channel, "\n"); ret = qcom_glink_send_open_req(glink, channel); if (ret) goto release_channel; Loading @@ -1073,12 +1125,15 @@ static struct glink_channel *qcom_glink_create_local(struct qcom_glink *glink, return channel; err_timeout: CH_INFO(channel, "err_timeout\n"); /* qcom_glink_send_open_req() did register the channel in lcids*/ spin_lock_irqsave(&glink->idr_lock, flags); idr_remove(&glink->lcids, channel->lcid); spin_unlock_irqrestore(&glink->idr_lock, flags); release_channel: CH_INFO(channel, "release_channel\n"); /* Release qcom_glink_send_open_req() reference */ kref_put(&channel->refcount, qcom_glink_channel_release); /* Release qcom_glink_alloc_channel() reference */ Loading @@ -1093,6 +1148,8 @@ static int qcom_glink_create_remote(struct qcom_glink *glink, { int ret; CH_INFO(channel, "\n"); qcom_glink_send_open_ack(glink, channel); ret = qcom_glink_send_open_req(glink, channel); Loading @@ -1108,6 +1165,8 @@ static int qcom_glink_create_remote(struct qcom_glink *glink, return 0; close_link: CH_INFO(channel, "close_link %d\n", ret); /* * Send a close request to "undo" our open-ack. The close-ack will * release the last reference. Loading Loading @@ -1235,6 +1294,8 @@ static int qcom_glink_request_intent(struct qcom_glink *glink, cmd.cid = channel->lcid; cmd.size = size; CH_INFO(channel, "size:%d\n", size); ret = qcom_glink_tx(glink, &cmd, sizeof(cmd), NULL, 0, true); if (ret) goto unlock; Loading Loading @@ -1439,17 +1500,21 @@ static int qcom_glink_rx_open(struct qcom_glink *glink, unsigned int rcid, channel->rpdev = rpdev; } CH_INFO(channel, "\n"); return 0; free_rpdev: CH_INFO(channel, "free_rpdev\n"); kfree(rpdev); rcid_remove: CH_INFO(channel, "rcid_remove\n"); spin_lock_irqsave(&glink->idr_lock, flags); idr_remove(&glink->rcids, channel->rcid); channel->rcid = 0; spin_unlock_irqrestore(&glink->idr_lock, flags); free_channel: CH_INFO(channel, "free_channel\n"); /* Release the reference, iff we took it */ if (create_device) kref_put(&channel->refcount, qcom_glink_channel_release); Loading @@ -1468,6 +1533,7 @@ static void qcom_glink_rx_close(struct qcom_glink *glink, unsigned int rcid) spin_unlock_irqrestore(&glink->idr_lock, flags); if (WARN(!channel, "close request on unknown channel\n")) return; CH_INFO(channel, "\n"); /* cancel pending rx_done work */ cancel_work_sync(&channel->intent_work); Loading Loading @@ -1501,6 +1567,7 @@ static void qcom_glink_rx_close_ack(struct qcom_glink *glink, unsigned int lcid) spin_unlock_irqrestore(&glink->idr_lock, flags); return; } CH_INFO(channel, "\n"); idr_remove(&glink->lcids, channel->lcid); channel->lcid = 0; Loading Loading @@ -1662,13 +1729,17 @@ struct qcom_glink *qcom_glink_native_probe(struct device *dev, glink->irq = irq; ret = qcom_glink_send_version(glink); if (ret) if (ret) { dev_err(dev, "failed to send version %d\n", ret); return ERR_PTR(ret); } ret = qcom_glink_create_chrdev(glink); if (ret) dev_err(glink->dev, "failed to register chrdev\n"); glink->ilc = ipc_log_context_create(GLINK_LOG_PAGE_CNT, glink->name, 0); return glink; } EXPORT_SYMBOL_GPL(qcom_glink_native_probe); Loading net/qrtr/qrtr.c +3 −5 Original line number Diff line number Diff line /* * Copyright (c) 2015, Sony Mobile Communications Inc. * Copyright (c) 2013, The Linux Foundation. All rights reserved. * Copyright (c) 2013, 2018 The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -1076,10 +1076,8 @@ static int qrtr_addr_doit(struct sk_buff *skb, struct nlmsghdr *nlh, struct ifaddrmsg *ifm; int rc; if (!netlink_capable(skb, CAP_NET_ADMIN)) return -EPERM; if (!netlink_capable(skb, CAP_SYS_ADMIN)) if (!netlink_capable(skb, CAP_NET_ADMIN) || !netlink_capable(skb, CAP_NET_BIND_SERVICE)) return -EPERM; ASSERT_RTNL(); Loading Loading
drivers/rpmsg/qcom_glink_native.c +72 −1 Original line number Diff line number Diff line Loading @@ -28,10 +28,33 @@ #include <linux/slab.h> #include <linux/workqueue.h> #include <linux/mailbox_client.h> #include <linux/ipc_logging.h> #include "rpmsg_internal.h" #include "qcom_glink_native.h" #define GLINK_LOG_PAGE_CNT 2 #define GLINK_INFO(ctxt, x, ...) \ do { \ if (ctxt) \ ipc_log_string(ctxt, "[%s]: "x, __func__, ##__VA_ARGS__); \ } while (0) #define CH_INFO(ch, x, ...) \ do { \ if (ch->glink && ch->glink->ilc) \ ipc_log_string(ch->glink->ilc, "%s[%d:%d] %s: "x, ch->name, \ ch->lcid, ch->rcid, __func__, ##__VA_ARGS__); \ } while (0) #define GLINK_ERR(ctxt, x, ...) \ do { \ pr_err_ratelimited("[%s]: "x, __func__, ##__VA_ARGS__); \ if (ctxt) \ ipc_log_string(ctxt, "[%s]: "x, __func__, ##__VA_ARGS__); \ } while (0) #define GLINK_NAME_SIZE 32 #define GLINK_VERSION_1 1 Loading Loading @@ -98,6 +121,7 @@ struct glink_core_rx_intent { * @idr_lock: synchronizes @lcids and @rcids modifications * @lcids: idr of all channels with a known local channel id * @rcids: idr of all channels with a known remote channel id * @ilc: ipc logging context reference */ struct qcom_glink { struct device *dev; Loading @@ -124,6 +148,8 @@ struct qcom_glink { unsigned long features; bool intentless; void *ilc; }; enum { Loading Loading @@ -256,6 +282,7 @@ static void qcom_glink_channel_release(struct kref *ref) refcount); unsigned long flags; CH_INFO(channel, "\n"); spin_lock_irqsave(&channel->intent_lock, flags); idr_destroy(&channel->liids); idr_destroy(&channel->riids); Loading Loading @@ -340,6 +367,7 @@ static int qcom_glink_send_version(struct qcom_glink *glink) msg.param1 = cpu_to_le16(GLINK_VERSION_1); msg.param2 = cpu_to_le32(glink->features); GLINK_INFO(glink->ilc, "vers:%d features:%d\n", msg.param1, msg.param2); return qcom_glink_tx(glink, &msg, sizeof(msg), NULL, 0, true); } Loading @@ -351,6 +379,7 @@ static void qcom_glink_send_version_ack(struct qcom_glink *glink) msg.param1 = cpu_to_le16(GLINK_VERSION_1); msg.param2 = cpu_to_le32(glink->features); GLINK_INFO(glink->ilc, "vers:%d features:%d\n", msg.param1, msg.param2); qcom_glink_tx(glink, &msg, sizeof(msg), NULL, 0, true); } Loading @@ -363,6 +392,7 @@ static void qcom_glink_send_open_ack(struct qcom_glink *glink, msg.param1 = cpu_to_le16(channel->rcid); msg.param2 = cpu_to_le32(0); CH_INFO(channel, "\n"); qcom_glink_tx(glink, &msg, sizeof(msg), NULL, 0, true); } Loading @@ -382,6 +412,7 @@ static void qcom_glink_handle_intent_req_ack(struct qcom_glink *glink, channel->intent_req_result = granted; complete(&channel->intent_req_comp); CH_INFO(channel, "\n"); } /** Loading Loading @@ -417,6 +448,7 @@ static int qcom_glink_send_open_req(struct qcom_glink *glink, return ret; channel->lcid = ret; CH_INFO(channel, "\n"); req.msg.cmd = cpu_to_le16(RPM_CMD_OPEN); req.msg.param1 = cpu_to_le16(channel->lcid); Loading @@ -430,6 +462,8 @@ static int qcom_glink_send_open_req(struct qcom_glink *glink, return 0; remove_idr: CH_INFO(channel, "remote_idr\n"); spin_lock_irqsave(&glink->idr_lock, flags); idr_remove(&glink->lcids, channel->lcid); channel->lcid = 0; Loading @@ -447,6 +481,7 @@ static void qcom_glink_send_close_req(struct qcom_glink *glink, req.param1 = cpu_to_le16(channel->lcid); req.param2 = 0; CH_INFO(channel, "\n"); qcom_glink_tx(glink, &req, sizeof(req), NULL, 0, true); } Loading @@ -459,6 +494,7 @@ static void qcom_glink_send_close_ack(struct qcom_glink *glink, req.param1 = cpu_to_le16(rcid); req.param2 = 0; GLINK_INFO(glink->ilc, "rcid:%d\n", rcid); qcom_glink_tx(glink, &req, sizeof(req), NULL, 0, true); } Loading Loading @@ -490,6 +526,7 @@ static void qcom_glink_rx_done_work(struct work_struct *work) cmd.lcid = cid; cmd.liid = iid; CH_INFO(channel, "reuse:%d liid:%d", reuse, iid); qcom_glink_tx(glink, &cmd, sizeof(cmd), NULL, 0, true); if (!reuse) { kfree(intent->data); Loading Loading @@ -540,6 +577,8 @@ static void qcom_glink_receive_version(struct qcom_glink *glink, u32 version, u32 features) { GLINK_INFO(glink->ilc, "vers:%d features:%d\n", version, features); switch (version) { case 0: break; Loading Loading @@ -567,6 +606,8 @@ static void qcom_glink_receive_version_ack(struct qcom_glink *glink, u32 version, u32 features) { GLINK_INFO(glink->ilc, "vers:%d features:%d\n", version, features); switch (version) { case 0: /* Version negotiation failed */ Loading Loading @@ -602,6 +643,7 @@ static int qcom_glink_send_intent_req_ack(struct qcom_glink *glink, msg.param1 = cpu_to_le16(channel->lcid); msg.param2 = cpu_to_le32(granted); CH_INFO(channel, "\n"); qcom_glink_tx(glink, &msg, sizeof(msg), NULL, 0, true); return 0; Loading Loading @@ -635,6 +677,9 @@ static int qcom_glink_advertise_intent(struct qcom_glink *glink, cmd.size = cpu_to_le32(intent->size); cmd.liid = cpu_to_le32(intent->id); CH_INFO(channel, "count:%d size:%d liid:%d\n", 1, intent->size, intent->id); qcom_glink_tx(glink, &cmd, sizeof(cmd), NULL, 0, true); return 0; Loading Loading @@ -705,6 +750,7 @@ static void qcom_glink_handle_rx_done(struct qcom_glink *glink, } intent->in_use = false; CH_INFO(channel, "reuse:%d iid:%d\n", reuse, intent->id); if (!reuse) { idr_remove(&channel->riids, intent->id); Loading Loading @@ -818,6 +864,7 @@ static int qcom_glink_rx_data(struct qcom_glink *glink, size_t avail) /* Drop the message */ goto advance_rx; } CH_INFO(channel, "chunk_size:%d left_size:%d\n", chunk_size, left_size); if (glink->intentless) { /* Might have an ongoing, fragmented, message to append */ Loading Loading @@ -940,6 +987,8 @@ static void qcom_glink_handle_intent(struct qcom_glink *glink, intent->id = le32_to_cpu(msg->intents[i].iid); intent->size = le32_to_cpu(msg->intents[i].size); CH_INFO(channel, "riid:%d size:%d\n", intent->id, intent->size); spin_lock_irqsave(&channel->intent_lock, flags); ret = idr_alloc(&channel->riids, intent, intent->id, intent->id + 1, GFP_ATOMIC); Loading @@ -947,6 +996,7 @@ static void qcom_glink_handle_intent(struct qcom_glink *glink, if (ret < 0) dev_err(glink->dev, "failed to store remote intent\n"); } kfree(msg); Loading @@ -965,6 +1015,7 @@ static int qcom_glink_rx_open_ack(struct qcom_glink *glink, unsigned int lcid) return -EINVAL; } CH_INFO(channel, "\n"); complete(&channel->open_ack); return 0; Loading Loading @@ -1056,6 +1107,7 @@ static struct glink_channel *qcom_glink_create_local(struct qcom_glink *glink, if (IS_ERR(channel)) return ERR_CAST(channel); CH_INFO(channel, "\n"); ret = qcom_glink_send_open_req(glink, channel); if (ret) goto release_channel; Loading @@ -1073,12 +1125,15 @@ static struct glink_channel *qcom_glink_create_local(struct qcom_glink *glink, return channel; err_timeout: CH_INFO(channel, "err_timeout\n"); /* qcom_glink_send_open_req() did register the channel in lcids*/ spin_lock_irqsave(&glink->idr_lock, flags); idr_remove(&glink->lcids, channel->lcid); spin_unlock_irqrestore(&glink->idr_lock, flags); release_channel: CH_INFO(channel, "release_channel\n"); /* Release qcom_glink_send_open_req() reference */ kref_put(&channel->refcount, qcom_glink_channel_release); /* Release qcom_glink_alloc_channel() reference */ Loading @@ -1093,6 +1148,8 @@ static int qcom_glink_create_remote(struct qcom_glink *glink, { int ret; CH_INFO(channel, "\n"); qcom_glink_send_open_ack(glink, channel); ret = qcom_glink_send_open_req(glink, channel); Loading @@ -1108,6 +1165,8 @@ static int qcom_glink_create_remote(struct qcom_glink *glink, return 0; close_link: CH_INFO(channel, "close_link %d\n", ret); /* * Send a close request to "undo" our open-ack. The close-ack will * release the last reference. Loading Loading @@ -1235,6 +1294,8 @@ static int qcom_glink_request_intent(struct qcom_glink *glink, cmd.cid = channel->lcid; cmd.size = size; CH_INFO(channel, "size:%d\n", size); ret = qcom_glink_tx(glink, &cmd, sizeof(cmd), NULL, 0, true); if (ret) goto unlock; Loading Loading @@ -1439,17 +1500,21 @@ static int qcom_glink_rx_open(struct qcom_glink *glink, unsigned int rcid, channel->rpdev = rpdev; } CH_INFO(channel, "\n"); return 0; free_rpdev: CH_INFO(channel, "free_rpdev\n"); kfree(rpdev); rcid_remove: CH_INFO(channel, "rcid_remove\n"); spin_lock_irqsave(&glink->idr_lock, flags); idr_remove(&glink->rcids, channel->rcid); channel->rcid = 0; spin_unlock_irqrestore(&glink->idr_lock, flags); free_channel: CH_INFO(channel, "free_channel\n"); /* Release the reference, iff we took it */ if (create_device) kref_put(&channel->refcount, qcom_glink_channel_release); Loading @@ -1468,6 +1533,7 @@ static void qcom_glink_rx_close(struct qcom_glink *glink, unsigned int rcid) spin_unlock_irqrestore(&glink->idr_lock, flags); if (WARN(!channel, "close request on unknown channel\n")) return; CH_INFO(channel, "\n"); /* cancel pending rx_done work */ cancel_work_sync(&channel->intent_work); Loading Loading @@ -1501,6 +1567,7 @@ static void qcom_glink_rx_close_ack(struct qcom_glink *glink, unsigned int lcid) spin_unlock_irqrestore(&glink->idr_lock, flags); return; } CH_INFO(channel, "\n"); idr_remove(&glink->lcids, channel->lcid); channel->lcid = 0; Loading Loading @@ -1662,13 +1729,17 @@ struct qcom_glink *qcom_glink_native_probe(struct device *dev, glink->irq = irq; ret = qcom_glink_send_version(glink); if (ret) if (ret) { dev_err(dev, "failed to send version %d\n", ret); return ERR_PTR(ret); } ret = qcom_glink_create_chrdev(glink); if (ret) dev_err(glink->dev, "failed to register chrdev\n"); glink->ilc = ipc_log_context_create(GLINK_LOG_PAGE_CNT, glink->name, 0); return glink; } EXPORT_SYMBOL_GPL(qcom_glink_native_probe); Loading
net/qrtr/qrtr.c +3 −5 Original line number Diff line number Diff line /* * Copyright (c) 2015, Sony Mobile Communications Inc. * Copyright (c) 2013, The Linux Foundation. All rights reserved. * Copyright (c) 2013, 2018 The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -1076,10 +1076,8 @@ static int qrtr_addr_doit(struct sk_buff *skb, struct nlmsghdr *nlh, struct ifaddrmsg *ifm; int rc; if (!netlink_capable(skb, CAP_NET_ADMIN)) return -EPERM; if (!netlink_capable(skb, CAP_SYS_ADMIN)) if (!netlink_capable(skb, CAP_NET_ADMIN) || !netlink_capable(skb, CAP_NET_BIND_SERVICE)) return -EPERM; ASSERT_RTNL(); Loading