LKML Archive on lore.kernel.org
help / color / mirror / Atom feed
* [PATCH 1/5] [NETLINK]: Fix use after free in netlink_recvmsg
@ 2007-05-03 9:53 David Howells
2007-05-03 9:53 ` [PATCH 2/5] [AFS]: Fix memory leak in SRXAFSCB_GetCapabilities David Howells
` (4 more replies)
0 siblings, 5 replies; 13+ messages in thread
From: David Howells @ 2007-05-03 9:53 UTC (permalink / raw)
To: akpm; +Cc: linux-kernel, linux-fsdevel, netdev, kaber, dhowells
When the user passes in MSG_TRUNC the skb is used after getting freed.
Signed-off-by: Patrick McHardy <kaber@trash.net>
Signed-off-by: David Howells <dhowells@redhat.com>
---
net/netlink/af_netlink.c | 6 ++----
1 files changed, 2 insertions(+), 4 deletions(-)
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c
index 42d2fb9..7419f70 100644
--- a/net/netlink/af_netlink.c
+++ b/net/netlink/af_netlink.c
@@ -1245,16 +1245,14 @@ static int netlink_recvmsg(struct kiocb *kiocb, struct socket *sock,
siocb->scm = &scm;
}
siocb->scm->creds = *NETLINK_CREDS(skb);
+ if (flags & MSG_TRUNC)
+ copied = skb->len;
skb_free_datagram(sk, skb);
if (nlk->cb && atomic_read(&sk->sk_rmem_alloc) <= sk->sk_rcvbuf / 2)
netlink_dump(sk);
scm_recv(sock, msg, siocb->scm, flags);
-
- if (flags & MSG_TRUNC)
- copied = skb->len;
-
out:
netlink_rcv_wake(sk);
return err ? : copied;
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH 2/5] [AFS]: Fix memory leak in SRXAFSCB_GetCapabilities
2007-05-03 9:53 [PATCH 1/5] [NETLINK]: Fix use after free in netlink_recvmsg David Howells
@ 2007-05-03 9:53 ` David Howells
2007-05-03 10:27 ` David Miller
2007-05-03 9:53 ` [PATCH 3/5] [NET]: Add __dev_getfirstbyhwtype David Howells
` (3 subsequent siblings)
4 siblings, 1 reply; 13+ messages in thread
From: David Howells @ 2007-05-03 9:53 UTC (permalink / raw)
To: akpm; +Cc: linux-kernel, linux-fsdevel, netdev, kaber, dhowells
The interface array is not freed on exit.
Signed-off-by: Patrick McHardy <kaber@trash.net>
Signed-off-by: David Howells <dhowells@redhat.com>
---
fs/afs/cmservice.c | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
diff --git a/fs/afs/cmservice.c b/fs/afs/cmservice.c
index 6685f4c..d5b2ad6 100644
--- a/fs/afs/cmservice.c
+++ b/fs/afs/cmservice.c
@@ -443,6 +443,7 @@ static void SRXAFSCB_GetCapabilities(struct work_struct *work)
reply.ia.netmask[loop] = ifs[loop].netmask.s_addr;
reply.ia.mtu[loop] = htonl(ifs[loop].mtu);
}
+ kfree(ifs);
}
reply.cap.capcount = htonl(1);
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH 3/5] [NET]: Add __dev_getfirstbyhwtype
2007-05-03 9:53 [PATCH 1/5] [NETLINK]: Fix use after free in netlink_recvmsg David Howells
2007-05-03 9:53 ` [PATCH 2/5] [AFS]: Fix memory leak in SRXAFSCB_GetCapabilities David Howells
@ 2007-05-03 9:53 ` David Howells
2007-05-03 10:28 ` David Miller
2007-05-03 9:53 ` [PATCH 4/5] [AFS]: Replace rtnetlink client by direct dev_base walking David Howells
` (2 subsequent siblings)
4 siblings, 1 reply; 13+ messages in thread
From: David Howells @ 2007-05-03 9:53 UTC (permalink / raw)
To: akpm; +Cc: linux-kernel, linux-fsdevel, netdev, kaber, dhowells
Add __dev_getfirstbyhwtype for callers that don't want a reference but
some data from the device and thus need to take the rtnl anyway.
Signed-off-by: Patrick McHardy <kaber@trash.net>
Signed-off-by: David Howells <dhowells@redhat.com>
---
include/linux/netdevice.h | 1 +
net/core/dev.c | 21 ++++++++++++++++-----
2 files changed, 17 insertions(+), 5 deletions(-)
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index ac0c92b..4428f1c 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -582,6 +582,7 @@ extern int netdev_boot_setup_check(struct net_device *dev);
extern unsigned long netdev_boot_base(const char *prefix, int unit);
extern struct net_device *dev_getbyhwaddr(unsigned short type, char *hwaddr);
extern struct net_device *dev_getfirstbyhwtype(unsigned short type);
+extern struct net_device *__dev_getfirstbyhwtype(unsigned short type);
extern void dev_add_pack(struct packet_type *pt);
extern void dev_remove_pack(struct packet_type *pt);
extern void __dev_remove_pack(struct packet_type *pt);
diff --git a/net/core/dev.c b/net/core/dev.c
index eb99900..c305819 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -576,17 +576,28 @@ struct net_device *dev_getbyhwaddr(unsigned short type, char *ha)
EXPORT_SYMBOL(dev_getbyhwaddr);
-struct net_device *dev_getfirstbyhwtype(unsigned short type)
+struct net_device *__dev_getfirstbyhwtype(unsigned short type)
{
struct net_device *dev;
- rtnl_lock();
+ ASSERT_RTNL();
for (dev = dev_base; dev; dev = dev->next) {
- if (dev->type == type) {
- dev_hold(dev);
+ if (dev->type == type)
break;
- }
}
+ return dev;
+}
+
+EXPORT_SYMBOL(__dev_getfirstbyhwtype);
+
+struct net_device *dev_getfirstbyhwtype(unsigned short type)
+{
+ struct net_device *dev;
+
+ rtnl_lock();
+ dev = __dev_getfirstbyhwtype(type);
+ if (dev)
+ dev_hold(dev);
rtnl_unlock();
return dev;
}
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH 4/5] [AFS]: Replace rtnetlink client by direct dev_base walking
2007-05-03 9:53 [PATCH 1/5] [NETLINK]: Fix use after free in netlink_recvmsg David Howells
2007-05-03 9:53 ` [PATCH 2/5] [AFS]: Fix memory leak in SRXAFSCB_GetCapabilities David Howells
2007-05-03 9:53 ` [PATCH 3/5] [NET]: Add __dev_getfirstbyhwtype David Howells
@ 2007-05-03 9:53 ` David Howells
2007-05-03 10:28 ` David Miller
2007-05-03 9:53 ` [PATCH 5/5] AFS: Adjust the new netdevice scanning code David Howells
2007-05-03 10:27 ` [PATCH 1/5] [NETLINK]: Fix use after free in netlink_recvmsg David Miller
4 siblings, 1 reply; 13+ messages in thread
From: David Howells @ 2007-05-03 9:53 UTC (permalink / raw)
To: akpm; +Cc: linux-kernel, linux-fsdevel, netdev, kaber, dhowells
Replace the large and complicated rtnetlink client by two simple
functions for getting the MAC address for the first ethernet device
and building a list of IPv4 addresses.
Signed-off-by: Patrick McHardy <kaber@trash.net>
Signed-off-by: David Howells <dhowells@redhat.com>
---
fs/afs/Makefile | 2
fs/afs/internal.h | 1
fs/afs/netdevices.c | 54 +++++
fs/afs/use-rtnetlink.c | 473 ------------------------------------------------
4 files changed, 55 insertions(+), 475 deletions(-)
diff --git a/fs/afs/Makefile b/fs/afs/Makefile
index 01545eb..cf83e5d 100644
--- a/fs/afs/Makefile
+++ b/fs/afs/Makefile
@@ -18,7 +18,7 @@ kafs-objs := \
security.o \
server.o \
super.o \
- use-rtnetlink.o \
+ netdevices.o \
vlclient.o \
vlocation.o \
vnode.o \
diff --git a/fs/afs/internal.h b/fs/afs/internal.h
index 3363e31..551db89 100644
--- a/fs/afs/internal.h
+++ b/fs/afs/internal.h
@@ -349,7 +349,6 @@ struct afs_permits {
* record of one of a system's set of network interfaces
*/
struct afs_interface {
- unsigned index; /* interface index */
struct in_addr address; /* IPv4 address bound to interface */
struct in_addr netmask; /* netmask applied to address */
unsigned mtu; /* MTU of interface */
diff --git a/fs/afs/netdevices.c b/fs/afs/netdevices.c
new file mode 100644
index 0000000..2b30873
--- /dev/null
+++ b/fs/afs/netdevices.c
@@ -0,0 +1,54 @@
+/* AFS network device helpers
+ *
+ * Copyright (c) 2007 Patrick McHardy <kaber@trash.net>
+ */
+
+#include <linux/string.h>
+#include <linux/rtnetlink.h>
+#include <linux/inetdevice.h>
+#include <linux/netdevice.h>
+#include <linux/if_arp.h>
+#include "internal.h"
+
+int afs_get_MAC_address(u8 mac[ETH_ALEN])
+{
+ struct net_device *dev;
+ int ret = -ENODEV;
+
+ rtnl_lock();
+ dev = __dev_getfirstbyhwtype(ARPHRD_ETHER);
+ if (dev) {
+ memcpy(mac, dev->dev_addr, ETH_ALEN);
+ ret = 0;
+ }
+ rtnl_unlock();
+ return ret;
+}
+
+int afs_get_ipv4_interfaces(struct afs_interface *bufs, size_t maxbufs,
+ bool wantloopback)
+{
+ struct net_device *dev;
+ struct in_device *idev;
+ int n = 0;
+
+ rtnl_lock();
+ for (dev = dev_base; dev; dev = dev->next) {
+ if (dev->type == ARPHRD_LOOPBACK && !wantloopback)
+ continue;
+ idev = __in_dev_get_rtnl(dev);
+ if (!idev)
+ continue;
+ for_primary_ifa(idev) {
+ if (n == maxbufs)
+ goto out;
+ bufs[n].address.s_addr = ifa->ifa_address;
+ bufs[n].netmask.s_addr = ifa->ifa_mask;
+ bufs[n].mtu = dev->mtu;
+ n++;
+ } endfor_ifa(idev)
+ }
+out:
+ rtnl_unlock();
+ return n;
+}
diff --git a/fs/afs/use-rtnetlink.c b/fs/afs/use-rtnetlink.c
deleted file mode 100644
index f8991c7..0000000
--- a/fs/afs/use-rtnetlink.c
+++ /dev/null
@@ -1,473 +0,0 @@
-/* RTNETLINK client
- *
- * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
- * Written by David Howells (dhowells@redhat.com)
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
- */
-#include <linux/netlink.h>
-#include <linux/rtnetlink.h>
-#include <linux/if_addr.h>
-#include <linux/if_arp.h>
-#include <linux/inetdevice.h>
-#include <net/netlink.h>
-#include "internal.h"
-
-struct afs_rtm_desc {
- struct socket *nlsock;
- struct afs_interface *bufs;
- u8 *mac;
- size_t nbufs;
- size_t maxbufs;
- void *data;
- ssize_t datalen;
- size_t datamax;
- int msg_seq;
- unsigned mac_index;
- bool wantloopback;
- int (*parse)(struct afs_rtm_desc *, struct nlmsghdr *);
-};
-
-/*
- * parse an RTM_GETADDR response
- */
-static int afs_rtm_getaddr_parse(struct afs_rtm_desc *desc,
- struct nlmsghdr *nlhdr)
-{
- struct afs_interface *this;
- struct ifaddrmsg *ifa;
- struct rtattr *rtattr;
- const char *name;
- size_t len;
-
- ifa = (struct ifaddrmsg *) NLMSG_DATA(nlhdr);
-
- _enter("{ix=%d,af=%d}", ifa->ifa_index, ifa->ifa_family);
-
- if (ifa->ifa_family != AF_INET) {
- _leave(" = 0 [family %d]", ifa->ifa_family);
- return 0;
- }
- if (desc->nbufs >= desc->maxbufs) {
- _leave(" = 0 [max %zu/%zu]", desc->nbufs, desc->maxbufs);
- return 0;
- }
-
- this = &desc->bufs[desc->nbufs];
-
- this->index = ifa->ifa_index;
- this->netmask.s_addr = inet_make_mask(ifa->ifa_prefixlen);
- this->mtu = 0;
-
- rtattr = NLMSG_DATA(nlhdr) + NLMSG_ALIGN(sizeof(struct ifaddrmsg));
- len = NLMSG_PAYLOAD(nlhdr, sizeof(struct ifaddrmsg));
-
- name = "unknown";
- for (; RTA_OK(rtattr, len); rtattr = RTA_NEXT(rtattr, len)) {
- switch (rtattr->rta_type) {
- case IFA_ADDRESS:
- memcpy(&this->address, RTA_DATA(rtattr), 4);
- break;
- case IFA_LABEL:
- name = RTA_DATA(rtattr);
- break;
- }
- }
-
- _debug("%s: "NIPQUAD_FMT"/"NIPQUAD_FMT,
- name, NIPQUAD(this->address), NIPQUAD(this->netmask));
-
- desc->nbufs++;
- _leave(" = 0");
- return 0;
-}
-
-/*
- * parse an RTM_GETLINK response for MTUs
- */
-static int afs_rtm_getlink_if_parse(struct afs_rtm_desc *desc,
- struct nlmsghdr *nlhdr)
-{
- struct afs_interface *this;
- struct ifinfomsg *ifi;
- struct rtattr *rtattr;
- const char *name;
- size_t len, loop;
-
- ifi = (struct ifinfomsg *) NLMSG_DATA(nlhdr);
-
- _enter("{ix=%d}", ifi->ifi_index);
-
- for (loop = 0; loop < desc->nbufs; loop++) {
- this = &desc->bufs[loop];
- if (this->index == ifi->ifi_index)
- goto found;
- }
-
- _leave(" = 0 [no match]");
- return 0;
-
-found:
- if (ifi->ifi_type == ARPHRD_LOOPBACK && !desc->wantloopback) {
- _leave(" = 0 [loopback]");
- return 0;
- }
-
- rtattr = NLMSG_DATA(nlhdr) + NLMSG_ALIGN(sizeof(struct ifinfomsg));
- len = NLMSG_PAYLOAD(nlhdr, sizeof(struct ifinfomsg));
-
- name = "unknown";
- for (; RTA_OK(rtattr, len); rtattr = RTA_NEXT(rtattr, len)) {
- switch (rtattr->rta_type) {
- case IFLA_MTU:
- memcpy(&this->mtu, RTA_DATA(rtattr), 4);
- break;
- case IFLA_IFNAME:
- name = RTA_DATA(rtattr);
- break;
- }
- }
-
- _debug("%s: "NIPQUAD_FMT"/"NIPQUAD_FMT" mtu %u",
- name, NIPQUAD(this->address), NIPQUAD(this->netmask),
- this->mtu);
-
- _leave(" = 0");
- return 0;
-}
-
-/*
- * parse an RTM_GETLINK response for the MAC address belonging to the lowest
- * non-internal interface
- */
-static int afs_rtm_getlink_mac_parse(struct afs_rtm_desc *desc,
- struct nlmsghdr *nlhdr)
-{
- struct ifinfomsg *ifi;
- struct rtattr *rtattr;
- const char *name;
- size_t remain, len;
- bool set;
-
- ifi = (struct ifinfomsg *) NLMSG_DATA(nlhdr);
-
- _enter("{ix=%d}", ifi->ifi_index);
-
- if (ifi->ifi_index >= desc->mac_index) {
- _leave(" = 0 [high]");
- return 0;
- }
- if (ifi->ifi_type == ARPHRD_LOOPBACK) {
- _leave(" = 0 [loopback]");
- return 0;
- }
-
- rtattr = NLMSG_DATA(nlhdr) + NLMSG_ALIGN(sizeof(struct ifinfomsg));
- remain = NLMSG_PAYLOAD(nlhdr, sizeof(struct ifinfomsg));
-
- name = "unknown";
- set = false;
- for (; RTA_OK(rtattr, remain); rtattr = RTA_NEXT(rtattr, remain)) {
- switch (rtattr->rta_type) {
- case IFLA_ADDRESS:
- len = RTA_PAYLOAD(rtattr);
- memcpy(desc->mac, RTA_DATA(rtattr),
- min_t(size_t, len, 6));
- desc->mac_index = ifi->ifi_index;
- set = true;
- break;
- case IFLA_IFNAME:
- name = RTA_DATA(rtattr);
- break;
- }
- }
-
- if (set)
- _debug("%s: %02x:%02x:%02x:%02x:%02x:%02x",
- name,
- desc->mac[0], desc->mac[1], desc->mac[2],
- desc->mac[3], desc->mac[4], desc->mac[5]);
-
- _leave(" = 0");
- return 0;
-}
-
-/*
- * read the rtnetlink response and pass to parsing routine
- */
-static int afs_read_rtm(struct afs_rtm_desc *desc)
-{
- struct nlmsghdr *nlhdr, tmphdr;
- struct msghdr msg;
- struct kvec iov[1];
- void *data;
- bool last = false;
- int len, ret, remain;
-
- _enter("");
-
- do {
- /* first of all peek to see how big the packet is */
- memset(&msg, 0, sizeof(msg));
- iov[0].iov_base = &tmphdr;
- iov[0].iov_len = sizeof(tmphdr);
- len = kernel_recvmsg(desc->nlsock, &msg, iov, 1,
- sizeof(tmphdr), MSG_PEEK | MSG_TRUNC);
- if (len < 0) {
- _leave(" = %d [peek]", len);
- return len;
- }
- if (len == 0)
- continue;
- if (len < sizeof(tmphdr) || len < NLMSG_PAYLOAD(&tmphdr, 0)) {
- _leave(" = -EMSGSIZE");
- return -EMSGSIZE;
- }
-
- if (desc->datamax < len) {
- kfree(desc->data);
- desc->data = NULL;
- data = kmalloc(len, GFP_KERNEL);
- if (!data)
- return -ENOMEM;
- desc->data = data;
- }
- desc->datamax = len;
-
- /* read all the data from this packet */
- iov[0].iov_base = desc->data;
- iov[0].iov_len = desc->datamax;
- desc->datalen = kernel_recvmsg(desc->nlsock, &msg, iov, 1,
- desc->datamax, 0);
- if (desc->datalen < 0) {
- _leave(" = %zd [recv]", desc->datalen);
- return desc->datalen;
- }
-
- nlhdr = desc->data;
-
- /* check if the header is valid */
- if (!NLMSG_OK(nlhdr, desc->datalen) ||
- nlhdr->nlmsg_type == NLMSG_ERROR) {
- _leave(" = -EIO");
- return -EIO;
- }
-
- /* see if this is the last message */
- if (nlhdr->nlmsg_type == NLMSG_DONE ||
- !(nlhdr->nlmsg_flags & NLM_F_MULTI))
- last = true;
-
- /* parse the bits we got this time */
- nlmsg_for_each_msg(nlhdr, desc->data, desc->datalen, remain) {
- ret = desc->parse(desc, nlhdr);
- if (ret < 0) {
- _leave(" = %d [parse]", ret);
- return ret;
- }
- }
-
- } while (!last);
-
- _leave(" = 0");
- return 0;
-}
-
-/*
- * list the interface bound addresses to get the address and netmask
- */
-static int afs_rtm_getaddr(struct afs_rtm_desc *desc)
-{
- struct msghdr msg;
- struct kvec iov[1];
- int ret;
-
- struct {
- struct nlmsghdr nl_msg __attribute__((aligned(NLMSG_ALIGNTO)));
- struct ifaddrmsg addr_msg __attribute__((aligned(NLMSG_ALIGNTO)));
- } request;
-
- _enter("");
-
- memset(&request, 0, sizeof(request));
-
- request.nl_msg.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifaddrmsg));
- request.nl_msg.nlmsg_type = RTM_GETADDR;
- request.nl_msg.nlmsg_flags = NLM_F_REQUEST | NLM_F_DUMP;
- request.nl_msg.nlmsg_seq = desc->msg_seq++;
- request.nl_msg.nlmsg_pid = 0;
-
- memset(&msg, 0, sizeof(msg));
- iov[0].iov_base = &request;
- iov[0].iov_len = sizeof(request);
-
- ret = kernel_sendmsg(desc->nlsock, &msg, iov, 1, iov[0].iov_len);
- _leave(" = %d", ret);
- return ret;
-}
-
-/*
- * list the interface link statuses to get the MTUs
- */
-static int afs_rtm_getlink(struct afs_rtm_desc *desc)
-{
- struct msghdr msg;
- struct kvec iov[1];
- int ret;
-
- struct {
- struct nlmsghdr nl_msg __attribute__((aligned(NLMSG_ALIGNTO)));
- struct ifinfomsg link_msg __attribute__((aligned(NLMSG_ALIGNTO)));
- } request;
-
- _enter("");
-
- memset(&request, 0, sizeof(request));
-
- request.nl_msg.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg));
- request.nl_msg.nlmsg_type = RTM_GETLINK;
- request.nl_msg.nlmsg_flags = NLM_F_REQUEST | NLM_F_ROOT;
- request.nl_msg.nlmsg_seq = desc->msg_seq++;
- request.nl_msg.nlmsg_pid = 0;
-
- memset(&msg, 0, sizeof(msg));
- iov[0].iov_base = &request;
- iov[0].iov_len = sizeof(request);
-
- ret = kernel_sendmsg(desc->nlsock, &msg, iov, 1, iov[0].iov_len);
- _leave(" = %d", ret);
- return ret;
-}
-
-/*
- * cull any interface records for which there isn't an MTU value
- */
-static void afs_cull_interfaces(struct afs_rtm_desc *desc)
-{
- struct afs_interface *bufs = desc->bufs;
- size_t nbufs = desc->nbufs;
- int loop, point = 0;
-
- _enter("{%zu}", nbufs);
-
- for (loop = 0; loop < nbufs; loop++) {
- if (desc->bufs[loop].mtu != 0) {
- if (loop != point) {
- ASSERTCMP(loop, >, point);
- bufs[point] = bufs[loop];
- }
- point++;
- }
- }
-
- desc->nbufs = point;
- _leave(" [%zu/%zu]", desc->nbufs, nbufs);
-}
-
-/*
- * get a list of this system's interface IPv4 addresses, netmasks and MTUs
- * - returns the number of interface records in the buffer
- */
-int afs_get_ipv4_interfaces(struct afs_interface *bufs, size_t maxbufs,
- bool wantloopback)
-{
- struct afs_rtm_desc desc;
- int ret, loop;
-
- _enter("");
-
- memset(&desc, 0, sizeof(desc));
- desc.bufs = bufs;
- desc.maxbufs = maxbufs;
- desc.wantloopback = wantloopback;
-
- ret = sock_create_kern(AF_NETLINK, SOCK_DGRAM, NETLINK_ROUTE,
- &desc.nlsock);
- if (ret < 0) {
- _leave(" = %d [sock]", ret);
- return ret;
- }
-
- /* issue RTM_GETADDR */
- desc.parse = afs_rtm_getaddr_parse;
- ret = afs_rtm_getaddr(&desc);
- if (ret < 0)
- goto error;
- ret = afs_read_rtm(&desc);
- if (ret < 0)
- goto error;
-
- /* issue RTM_GETLINK */
- desc.parse = afs_rtm_getlink_if_parse;
- ret = afs_rtm_getlink(&desc);
- if (ret < 0)
- goto error;
- ret = afs_read_rtm(&desc);
- if (ret < 0)
- goto error;
-
- afs_cull_interfaces(&desc);
- ret = desc.nbufs;
-
- for (loop = 0; loop < ret; loop++)
- _debug("[%d] "NIPQUAD_FMT"/"NIPQUAD_FMT" mtu %u",
- bufs[loop].index,
- NIPQUAD(bufs[loop].address),
- NIPQUAD(bufs[loop].netmask),
- bufs[loop].mtu);
-
-error:
- kfree(desc.data);
- sock_release(desc.nlsock);
- _leave(" = %d", ret);
- return ret;
-}
-
-/*
- * get a MAC address from a random ethernet interface that has a real one
- * - the buffer should be 6 bytes in size
- */
-int afs_get_MAC_address(u8 mac[6])
-{
- struct afs_rtm_desc desc;
- int ret;
-
- _enter("");
-
- memset(&desc, 0, sizeof(desc));
- desc.mac = mac;
- desc.mac_index = UINT_MAX;
-
- ret = sock_create_kern(AF_NETLINK, SOCK_DGRAM, NETLINK_ROUTE,
- &desc.nlsock);
- if (ret < 0) {
- _leave(" = %d [sock]", ret);
- return ret;
- }
-
- /* issue RTM_GETLINK */
- desc.parse = afs_rtm_getlink_mac_parse;
- ret = afs_rtm_getlink(&desc);
- if (ret < 0)
- goto error;
- ret = afs_read_rtm(&desc);
- if (ret < 0)
- goto error;
-
- if (desc.mac_index < UINT_MAX) {
- /* got a MAC address */
- _debug("[%d] %02x:%02x:%02x:%02x:%02x:%02x",
- desc.mac_index,
- mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
- } else {
- ret = -ENONET;
- }
-
-error:
- sock_release(desc.nlsock);
- _leave(" = %d", ret);
- return ret;
-}
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH 5/5] AFS: Adjust the new netdevice scanning code
2007-05-03 9:53 [PATCH 1/5] [NETLINK]: Fix use after free in netlink_recvmsg David Howells
` (2 preceding siblings ...)
2007-05-03 9:53 ` [PATCH 4/5] [AFS]: Replace rtnetlink client by direct dev_base walking David Howells
@ 2007-05-03 9:53 ` David Howells
2007-05-03 10:29 ` David Miller
2007-05-03 10:27 ` [PATCH 1/5] [NETLINK]: Fix use after free in netlink_recvmsg David Miller
4 siblings, 1 reply; 13+ messages in thread
From: David Howells @ 2007-05-03 9:53 UTC (permalink / raw)
To: akpm; +Cc: linux-kernel, linux-fsdevel, netdev, kaber, dhowells
Adjust the new netdevice scanning code provided by Patrick McHardy:
(1) Restore the function banner comments that were dropped.
(2) Rather than using an array size of 6 in some places and an array size of
ETH_ALEN in others, pass a pointer instead and pass the array size
through so that we can actually check it.
(3) Do the buffer fill count check before checking the for_primary_ifa
condition again. This permits us to skip that check should maxbufs be
reached before we run out of interfaces.
Signed-off-by: David Howells <dhowells@redhat.com>
---
fs/afs/internal.h | 2 +-
fs/afs/main.c | 2 +-
fs/afs/netdevices.c | 24 +++++++++++++++++++-----
3 files changed, 21 insertions(+), 7 deletions(-)
diff --git a/fs/afs/internal.h b/fs/afs/internal.h
index 551db89..d90c158 100644
--- a/fs/afs/internal.h
+++ b/fs/afs/internal.h
@@ -563,7 +563,7 @@ extern void afs_fs_exit(void);
* use-rtnetlink.c
*/
extern int afs_get_ipv4_interfaces(struct afs_interface *, size_t, bool);
-extern int afs_get_MAC_address(u8 [6]);
+extern int afs_get_MAC_address(u8 *, size_t);
/*
* vlclient.c
diff --git a/fs/afs/main.c b/fs/afs/main.c
index 40c2704..80ec6fd 100644
--- a/fs/afs/main.c
+++ b/fs/afs/main.c
@@ -54,7 +54,7 @@ static int __init afs_get_client_UUID(void)
/* read the MAC address of one of the external interfaces and construct
* a UUID from it */
- ret = afs_get_MAC_address(afs_uuid.node);
+ ret = afs_get_MAC_address(afs_uuid.node, sizeof(afs_uuid.node));
if (ret < 0)
return ret;
diff --git a/fs/afs/netdevices.c b/fs/afs/netdevices.c
index 2b30873..ce08977 100644
--- a/fs/afs/netdevices.c
+++ b/fs/afs/netdevices.c
@@ -10,21 +10,33 @@
#include <linux/if_arp.h>
#include "internal.h"
-int afs_get_MAC_address(u8 mac[ETH_ALEN])
+/*
+ * get a MAC address from a random ethernet interface that has a real one
+ * - the buffer will normally be 6 bytes in size
+ */
+int afs_get_MAC_address(u8 *mac, size_t maclen)
{
struct net_device *dev;
int ret = -ENODEV;
+ if (maclen != ETH_ALEN)
+ BUG();
+
rtnl_lock();
dev = __dev_getfirstbyhwtype(ARPHRD_ETHER);
if (dev) {
- memcpy(mac, dev->dev_addr, ETH_ALEN);
+ memcpy(mac, dev->dev_addr, maclen);
ret = 0;
}
rtnl_unlock();
return ret;
}
+/*
+ * get a list of this system's interface IPv4 addresses, netmasks and MTUs
+ * - maxbufs must be at least 1
+ * - returns the number of interface records in the buffer
+ */
int afs_get_ipv4_interfaces(struct afs_interface *bufs, size_t maxbufs,
bool wantloopback)
{
@@ -32,6 +44,8 @@ int afs_get_ipv4_interfaces(struct afs_interface *bufs, size_t maxbufs,
struct in_device *idev;
int n = 0;
+ ASSERT(maxbufs > 0);
+
rtnl_lock();
for (dev = dev_base; dev; dev = dev->next) {
if (dev->type == ARPHRD_LOOPBACK && !wantloopback)
@@ -40,13 +54,13 @@ int afs_get_ipv4_interfaces(struct afs_interface *bufs, size_t maxbufs,
if (!idev)
continue;
for_primary_ifa(idev) {
- if (n == maxbufs)
- goto out;
bufs[n].address.s_addr = ifa->ifa_address;
bufs[n].netmask.s_addr = ifa->ifa_mask;
bufs[n].mtu = dev->mtu;
n++;
- } endfor_ifa(idev)
+ if (n >= maxbufs)
+ goto out;
+ } endfor_ifa(idev);
}
out:
rtnl_unlock();
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH 1/5] [NETLINK]: Fix use after free in netlink_recvmsg
2007-05-03 9:53 [PATCH 1/5] [NETLINK]: Fix use after free in netlink_recvmsg David Howells
` (3 preceding siblings ...)
2007-05-03 9:53 ` [PATCH 5/5] AFS: Adjust the new netdevice scanning code David Howells
@ 2007-05-03 10:27 ` David Miller
2007-05-03 12:27 ` Marcel Holtmann
4 siblings, 1 reply; 13+ messages in thread
From: David Miller @ 2007-05-03 10:27 UTC (permalink / raw)
To: dhowells; +Cc: akpm, linux-kernel, linux-fsdevel, netdev, kaber
From: David Howells <dhowells@redhat.com>
Date: Thu, 03 May 2007 10:53:15 +0100
> When the user passes in MSG_TRUNC the skb is used after getting freed.
>
> Signed-off-by: Patrick McHardy <kaber@trash.net>
> Signed-off-by: David Howells <dhowells@redhat.com>
Ugh, good catch, applied :-)
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH 2/5] [AFS]: Fix memory leak in SRXAFSCB_GetCapabilities
2007-05-03 9:53 ` [PATCH 2/5] [AFS]: Fix memory leak in SRXAFSCB_GetCapabilities David Howells
@ 2007-05-03 10:27 ` David Miller
0 siblings, 0 replies; 13+ messages in thread
From: David Miller @ 2007-05-03 10:27 UTC (permalink / raw)
To: dhowells; +Cc: akpm, linux-kernel, linux-fsdevel, netdev, kaber
From: David Howells <dhowells@redhat.com>
Date: Thu, 03 May 2007 10:53:20 +0100
> The interface array is not freed on exit.
>
> Signed-off-by: Patrick McHardy <kaber@trash.net>
> Signed-off-by: David Howells <dhowells@redhat.com>
Applied, thanks.
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH 3/5] [NET]: Add __dev_getfirstbyhwtype
2007-05-03 9:53 ` [PATCH 3/5] [NET]: Add __dev_getfirstbyhwtype David Howells
@ 2007-05-03 10:28 ` David Miller
0 siblings, 0 replies; 13+ messages in thread
From: David Miller @ 2007-05-03 10:28 UTC (permalink / raw)
To: dhowells; +Cc: akpm, linux-kernel, linux-fsdevel, netdev, kaber
From: David Howells <dhowells@redhat.com>
Date: Thu, 03 May 2007 10:53:26 +0100
> Add __dev_getfirstbyhwtype for callers that don't want a reference but
> some data from the device and thus need to take the rtnl anyway.
>
> Signed-off-by: Patrick McHardy <kaber@trash.net>
> Signed-off-by: David Howells <dhowells@redhat.com>
Applied.
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH 4/5] [AFS]: Replace rtnetlink client by direct dev_base walking
2007-05-03 9:53 ` [PATCH 4/5] [AFS]: Replace rtnetlink client by direct dev_base walking David Howells
@ 2007-05-03 10:28 ` David Miller
0 siblings, 0 replies; 13+ messages in thread
From: David Miller @ 2007-05-03 10:28 UTC (permalink / raw)
To: dhowells; +Cc: akpm, linux-kernel, linux-fsdevel, netdev, kaber
From: David Howells <dhowells@redhat.com>
Date: Thu, 03 May 2007 10:53:31 +0100
> Replace the large and complicated rtnetlink client by two simple
> functions for getting the MAC address for the first ethernet device
> and building a list of IPv4 addresses.
>
> Signed-off-by: Patrick McHardy <kaber@trash.net>
> Signed-off-by: David Howells <dhowells@redhat.com>
Applied.
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH 5/5] AFS: Adjust the new netdevice scanning code
2007-05-03 9:53 ` [PATCH 5/5] AFS: Adjust the new netdevice scanning code David Howells
@ 2007-05-03 10:29 ` David Miller
0 siblings, 0 replies; 13+ messages in thread
From: David Miller @ 2007-05-03 10:29 UTC (permalink / raw)
To: dhowells; +Cc: akpm, linux-kernel, linux-fsdevel, netdev, kaber
From: David Howells <dhowells@redhat.com>
Date: Thu, 03 May 2007 10:53:36 +0100
> Adjust the new netdevice scanning code provided by Patrick McHardy:
>
> (1) Restore the function banner comments that were dropped.
>
> (2) Rather than using an array size of 6 in some places and an array size of
> ETH_ALEN in others, pass a pointer instead and pass the array size
> through so that we can actually check it.
>
> (3) Do the buffer fill count check before checking the for_primary_ifa
> condition again. This permits us to skip that check should maxbufs be
> reached before we run out of interfaces.
>
> Signed-off-by: David Howells <dhowells@redhat.com>
Applied, thanks.
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH 1/5] [NETLINK]: Fix use after free in netlink_recvmsg
2007-05-03 10:27 ` [PATCH 1/5] [NETLINK]: Fix use after free in netlink_recvmsg David Miller
@ 2007-05-03 12:27 ` Marcel Holtmann
2007-05-03 12:46 ` Patrick McHardy
2007-05-03 20:11 ` David Miller
0 siblings, 2 replies; 13+ messages in thread
From: Marcel Holtmann @ 2007-05-03 12:27 UTC (permalink / raw)
To: David Miller; +Cc: dhowells, akpm, linux-kernel, linux-fsdevel, netdev, kaber
Hi Dave,
> > When the user passes in MSG_TRUNC the skb is used after getting freed.
> >
> > Signed-off-by: Patrick McHardy <kaber@trash.net>
> > Signed-off-by: David Howells <dhowells@redhat.com>
>
> Ugh, good catch, applied :-)
it seems this could be easily exploited and is at least a local DoS. It
should be a candidate for the -stable kernel.
Regards
Marcel
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH 1/5] [NETLINK]: Fix use after free in netlink_recvmsg
2007-05-03 12:27 ` Marcel Holtmann
@ 2007-05-03 12:46 ` Patrick McHardy
2007-05-03 20:11 ` David Miller
1 sibling, 0 replies; 13+ messages in thread
From: Patrick McHardy @ 2007-05-03 12:46 UTC (permalink / raw)
To: Marcel Holtmann
Cc: David Miller, dhowells, akpm, linux-kernel, linux-fsdevel, netdev
Marcel Holtmann wrote:
> it seems this could be easily exploited and is at least a local DoS. It
> should be a candidate for the -stable kernel.
The bug got introduced in 2.6.21-git, so -stable is not affected.
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH 1/5] [NETLINK]: Fix use after free in netlink_recvmsg
2007-05-03 12:27 ` Marcel Holtmann
2007-05-03 12:46 ` Patrick McHardy
@ 2007-05-03 20:11 ` David Miller
1 sibling, 0 replies; 13+ messages in thread
From: David Miller @ 2007-05-03 20:11 UTC (permalink / raw)
To: marcel; +Cc: dhowells, akpm, linux-kernel, linux-fsdevel, netdev, kaber
From: Marcel Holtmann <marcel@holtmann.org>
Date: Thu, 03 May 2007 14:27:16 +0200
> Hi Dave,
>
> > > When the user passes in MSG_TRUNC the skb is used after getting freed.
> > >
> > > Signed-off-by: Patrick McHardy <kaber@trash.net>
> > > Signed-off-by: David Howells <dhowells@redhat.com>
> >
> > Ugh, good catch, applied :-)
>
> it seems this could be easily exploited and is at least a local DoS. It
> should be a candidate for the -stable kernel.
The MSG_TRUNC change is in 2.6.22 GIT only.
You might want to check such things before making such statements. :-/
^ permalink raw reply [flat|nested] 13+ messages in thread
end of thread, other threads:[~2007-05-03 20:11 UTC | newest]
Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2007-05-03 9:53 [PATCH 1/5] [NETLINK]: Fix use after free in netlink_recvmsg David Howells
2007-05-03 9:53 ` [PATCH 2/5] [AFS]: Fix memory leak in SRXAFSCB_GetCapabilities David Howells
2007-05-03 10:27 ` David Miller
2007-05-03 9:53 ` [PATCH 3/5] [NET]: Add __dev_getfirstbyhwtype David Howells
2007-05-03 10:28 ` David Miller
2007-05-03 9:53 ` [PATCH 4/5] [AFS]: Replace rtnetlink client by direct dev_base walking David Howells
2007-05-03 10:28 ` David Miller
2007-05-03 9:53 ` [PATCH 5/5] AFS: Adjust the new netdevice scanning code David Howells
2007-05-03 10:29 ` David Miller
2007-05-03 10:27 ` [PATCH 1/5] [NETLINK]: Fix use after free in netlink_recvmsg David Miller
2007-05-03 12:27 ` Marcel Holtmann
2007-05-03 12:46 ` Patrick McHardy
2007-05-03 20:11 ` David Miller
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).