aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/ipvs
diff options
context:
space:
mode:
authorpageexec <pageexec@freemail.hu>2005-06-26 19:00:19 -0400
committerDavid S. Miller <davem@davemloft.net>2005-06-26 19:00:19 -0400
commit4da62fc70d7cbcf8fa606a8c806d9dc8faa0ceae (patch)
treec15f61c9c0a1b1e88990eab47ebc89a4a83b3a4e /net/ipv4/ipvs
parentd470e3b483dcf79c16463bc740738dca76a035a9 (diff)
[IPVS]: Fix for overflows
From: <pageexec@freemail.hu> $subject was fixed in 2.4 already, 2.6 needs it as well. The impact of the bugs is a kernel stack overflow and privilege escalation from CAP_NET_ADMIN via the IP_VS_SO_SET_STARTDAEMON/IP_VS_SO_GET_DAEMON ioctls. People running with 'root=all caps' (i.e., most users) are not really affected (there's nothing to escalate), but SELinux and similar users should take it seriously if they grant CAP_NET_ADMIN to other users. Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4/ipvs')
-rw-r--r--net/ipv4/ipvs/ip_vs_ctl.c8
-rw-r--r--net/ipv4/ipvs/ip_vs_sync.c4
2 files changed, 7 insertions, 5 deletions
diff --git a/net/ipv4/ipvs/ip_vs_ctl.c b/net/ipv4/ipvs/ip_vs_ctl.c
index 218d9701036e..12a82e91d22a 100644
--- a/net/ipv4/ipvs/ip_vs_ctl.c
+++ b/net/ipv4/ipvs/ip_vs_ctl.c
@@ -2059,7 +2059,7 @@ ip_vs_copy_service(struct ip_vs_service_entry *dst, struct ip_vs_service *src)
2059 dst->addr = src->addr; 2059 dst->addr = src->addr;
2060 dst->port = src->port; 2060 dst->port = src->port;
2061 dst->fwmark = src->fwmark; 2061 dst->fwmark = src->fwmark;
2062 strcpy(dst->sched_name, src->scheduler->name); 2062 strlcpy(dst->sched_name, src->scheduler->name, sizeof(dst->sched_name));
2063 dst->flags = src->flags; 2063 dst->flags = src->flags;
2064 dst->timeout = src->timeout / HZ; 2064 dst->timeout = src->timeout / HZ;
2065 dst->netmask = src->netmask; 2065 dst->netmask = src->netmask;
@@ -2080,6 +2080,7 @@ __ip_vs_get_service_entries(const struct ip_vs_get_services *get,
2080 list_for_each_entry(svc, &ip_vs_svc_table[idx], s_list) { 2080 list_for_each_entry(svc, &ip_vs_svc_table[idx], s_list) {
2081 if (count >= get->num_services) 2081 if (count >= get->num_services)
2082 goto out; 2082 goto out;
2083 memset(&entry, 0, sizeof(entry));
2083 ip_vs_copy_service(&entry, svc); 2084 ip_vs_copy_service(&entry, svc);
2084 if (copy_to_user(&uptr->entrytable[count], 2085 if (copy_to_user(&uptr->entrytable[count],
2085 &entry, sizeof(entry))) { 2086 &entry, sizeof(entry))) {
@@ -2094,6 +2095,7 @@ __ip_vs_get_service_entries(const struct ip_vs_get_services *get,
2094 list_for_each_entry(svc, &ip_vs_svc_fwm_table[idx], f_list) { 2095 list_for_each_entry(svc, &ip_vs_svc_fwm_table[idx], f_list) {
2095 if (count >= get->num_services) 2096 if (count >= get->num_services)
2096 goto out; 2097 goto out;
2098 memset(&entry, 0, sizeof(entry));
2097 ip_vs_copy_service(&entry, svc); 2099 ip_vs_copy_service(&entry, svc);
2098 if (copy_to_user(&uptr->entrytable[count], 2100 if (copy_to_user(&uptr->entrytable[count],
2099 &entry, sizeof(entry))) { 2101 &entry, sizeof(entry))) {
@@ -2304,12 +2306,12 @@ do_ip_vs_get_ctl(struct sock *sk, int cmd, void __user *user, int *len)
2304 memset(&d, 0, sizeof(d)); 2306 memset(&d, 0, sizeof(d));
2305 if (ip_vs_sync_state & IP_VS_STATE_MASTER) { 2307 if (ip_vs_sync_state & IP_VS_STATE_MASTER) {
2306 d[0].state = IP_VS_STATE_MASTER; 2308 d[0].state = IP_VS_STATE_MASTER;
2307 strcpy(d[0].mcast_ifn, ip_vs_master_mcast_ifn); 2309 strlcpy(d[0].mcast_ifn, ip_vs_master_mcast_ifn, sizeof(d[0].mcast_ifn));
2308 d[0].syncid = ip_vs_master_syncid; 2310 d[0].syncid = ip_vs_master_syncid;
2309 } 2311 }
2310 if (ip_vs_sync_state & IP_VS_STATE_BACKUP) { 2312 if (ip_vs_sync_state & IP_VS_STATE_BACKUP) {
2311 d[1].state = IP_VS_STATE_BACKUP; 2313 d[1].state = IP_VS_STATE_BACKUP;
2312 strcpy(d[1].mcast_ifn, ip_vs_backup_mcast_ifn); 2314 strlcpy(d[1].mcast_ifn, ip_vs_backup_mcast_ifn, sizeof(d[1].mcast_ifn));
2313 d[1].syncid = ip_vs_backup_syncid; 2315 d[1].syncid = ip_vs_backup_syncid;
2314 } 2316 }
2315 if (copy_to_user(user, &d, sizeof(d)) != 0) 2317 if (copy_to_user(user, &d, sizeof(d)) != 0)
diff --git a/net/ipv4/ipvs/ip_vs_sync.c b/net/ipv4/ipvs/ip_vs_sync.c
index 25c479550a32..574d1f509b46 100644
--- a/net/ipv4/ipvs/ip_vs_sync.c
+++ b/net/ipv4/ipvs/ip_vs_sync.c
@@ -839,10 +839,10 @@ int start_sync_thread(int state, char *mcast_ifn, __u8 syncid)
839 839
840 ip_vs_sync_state |= state; 840 ip_vs_sync_state |= state;
841 if (state == IP_VS_STATE_MASTER) { 841 if (state == IP_VS_STATE_MASTER) {
842 strcpy(ip_vs_master_mcast_ifn, mcast_ifn); 842 strlcpy(ip_vs_master_mcast_ifn, mcast_ifn, sizeof(ip_vs_master_mcast_ifn));
843 ip_vs_master_syncid = syncid; 843 ip_vs_master_syncid = syncid;
844 } else { 844 } else {
845 strcpy(ip_vs_backup_mcast_ifn, mcast_ifn); 845 strlcpy(ip_vs_backup_mcast_ifn, mcast_ifn, sizeof(ip_vs_backup_mcast_ifn));
846 ip_vs_backup_syncid = syncid; 846 ip_vs_backup_syncid = syncid;
847 } 847 }
848 848