Skip to content

Commit 4da62fc

Browse files
pageexecdavem330
pageexec
authored andcommitted
[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>
1 parent d470e3b commit 4da62fc

File tree

2 files changed

+7
-5
lines changed

2 files changed

+7
-5
lines changed

net/ipv4/ipvs/ip_vs_ctl.c

+5-3
Original file line numberDiff line numberDiff line change
@@ -2059,7 +2059,7 @@ ip_vs_copy_service(struct ip_vs_service_entry *dst, struct ip_vs_service *src)
20592059
dst->addr = src->addr;
20602060
dst->port = src->port;
20612061
dst->fwmark = src->fwmark;
2062-
strcpy(dst->sched_name, src->scheduler->name);
2062+
strlcpy(dst->sched_name, src->scheduler->name, sizeof(dst->sched_name));
20632063
dst->flags = src->flags;
20642064
dst->timeout = src->timeout / HZ;
20652065
dst->netmask = src->netmask;
@@ -2080,6 +2080,7 @@ __ip_vs_get_service_entries(const struct ip_vs_get_services *get,
20802080
list_for_each_entry(svc, &ip_vs_svc_table[idx], s_list) {
20812081
if (count >= get->num_services)
20822082
goto out;
2083+
memset(&entry, 0, sizeof(entry));
20832084
ip_vs_copy_service(&entry, svc);
20842085
if (copy_to_user(&uptr->entrytable[count],
20852086
&entry, sizeof(entry))) {
@@ -2094,6 +2095,7 @@ __ip_vs_get_service_entries(const struct ip_vs_get_services *get,
20942095
list_for_each_entry(svc, &ip_vs_svc_fwm_table[idx], f_list) {
20952096
if (count >= get->num_services)
20962097
goto out;
2098+
memset(&entry, 0, sizeof(entry));
20972099
ip_vs_copy_service(&entry, svc);
20982100
if (copy_to_user(&uptr->entrytable[count],
20992101
&entry, sizeof(entry))) {
@@ -2304,12 +2306,12 @@ do_ip_vs_get_ctl(struct sock *sk, int cmd, void __user *user, int *len)
23042306
memset(&d, 0, sizeof(d));
23052307
if (ip_vs_sync_state & IP_VS_STATE_MASTER) {
23062308
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));
23082310
d[0].syncid = ip_vs_master_syncid;
23092311
}
23102312
if (ip_vs_sync_state & IP_VS_STATE_BACKUP) {
23112313
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));
23132315
d[1].syncid = ip_vs_backup_syncid;
23142316
}
23152317
if (copy_to_user(user, &d, sizeof(d)) != 0)

net/ipv4/ipvs/ip_vs_sync.c

+2-2
Original file line numberDiff line numberDiff line change
@@ -839,10 +839,10 @@ int start_sync_thread(int state, char *mcast_ifn, __u8 syncid)
839839

840840
ip_vs_sync_state |= state;
841841
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));
843843
ip_vs_master_syncid = syncid;
844844
} 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));
846846
ip_vs_backup_syncid = syncid;
847847
}
848848

0 commit comments

Comments
 (0)