[PATCH] IPVS: Replace several unchecked strcpy() with strncpy() (PaX team)
Linux Kernel Mailing List <[email protected]> Tue, 31 May 2005 11:32:10 +0000
| Newsgroups | gmane.linux.kernel.commits.2-4 |
|---|---|
| Message-ID | <[email protected]> |
ChangeSet 1.1564, 2005/05/31 08:32:10-03:00, [email protected] [PATCH] IPVS: Replace several unchecked strcpy() with strncpy() (PaX team) strcpy() is exploitable from the root but we can expect some user interface running with root privileges which pass user information to the kernel and exploit the bug. ip_vs_ctl.c | 21 ++++++++++++++------- ip_vs_sched.c | 2 +- ip_vs_sync.c | 6 ++++-- 3 files changed, 19 insertions(+), 10 deletions(-) diff -Nru a/net/ipv4/ipvs/ip_vs_ctl.c b/net/ipv4/ipvs/ip_vs_ctl.c --- a/net/ipv4/ipvs/ip_vs_ctl.c 2005-05-31 13:01:46 -07:00 +++ b/net/ipv4/ipvs/ip_vs_ctl.c 2005-05-31 13:01:46 -07:00 @@ -1842,7 +1842,8 @@ entry.addr = svc->addr; entry.port = svc->port; entry.fwmark = svc->fwmark; - strcpy(entry.sched_name, svc->scheduler->name); + strncpy(entry.sched_name, svc->scheduler->name, sizeof(entry.sched_name)); + entry.sched_name[sizeof(entry.sched_name) - 1] = 0; entry.flags = svc->flags; entry.timeout = svc->timeout / HZ; entry.netmask = svc->netmask; @@ -1866,7 +1867,8 @@ entry.addr = svc->addr; entry.port = svc->port; entry.fwmark = svc->fwmark; - strcpy(entry.sched_name, svc->scheduler->name); + strncpy(entry.sched_name, svc->scheduler->name, sizeof(entry.sched_name)); + entry.sched_name[sizeof(entry.sched_name) - 1] = 0; entry.flags = svc->flags; entry.timeout = svc->timeout / HZ; entry.netmask = svc->netmask; @@ -2020,7 +2022,8 @@ svc = __ip_vs_service_get(get.protocol, get.addr, get.port); if (svc) { - strcpy(get.sched_name, svc->scheduler->name); + strncpy(get.sched_name, svc->scheduler->name, sizeof(get.sched_name)); + get.sched_name[sizeof(get.sched_name) - 1] = 0; get.flags = svc->flags; get.timeout = svc->timeout / HZ; get.netmask = svc->netmask; @@ -2083,10 +2086,14 @@ goto out; } u.state = ip_vs_sync_state; - if (ip_vs_sync_state & IP_VS_STATE_MASTER) - strcpy(u.mcast_master_ifn, ip_vs_mcast_master_ifn); - if (ip_vs_sync_state & IP_VS_STATE_BACKUP) - strcpy(u.mcast_backup_ifn, ip_vs_mcast_backup_ifn); + if (ip_vs_sync_state & IP_VS_STATE_MASTER) { + strncpy(u.mcast_master_ifn, ip_vs_mcast_master_ifn, sizeof(u.mcast_master_ifn)); + u.mcast_master_ifn[sizeof(u.mcast_master_ifn) - 1] = 0; + } + if (ip_vs_sync_state & IP_VS_STATE_BACKUP) { + strncpy(u.mcast_backup_ifn, ip_vs_mcast_backup_ifn, sizeof(u.mcast_backup_ifn)); + u.mcast_backup_ifn[sizeof(u.mcast_backup_ifn) - 1] = 0; + } if (copy_to_user(user, &u, sizeof(u)) != 0) ret = -EFAULT; } diff -Nru a/net/ipv4/ipvs/ip_vs_sched.c b/net/ipv4/ipvs/ip_vs_sched.c --- a/net/ipv4/ipvs/ip_vs_sched.c 2005-05-31 13:01:46 -07:00 +++ b/net/ipv4/ipvs/ip_vs_sched.c 2005-05-31 13:01:46 -07:00 @@ -156,7 +156,7 @@ */ if (sched == NULL) { char module_name[IP_VS_SCHEDNAME_MAXLEN+8]; - sprintf(module_name,"ip_vs_%s", sched_name); + snprintf(module_name, sizeof(module_name), "ip_vs_%s", sched_name); request_module(module_name); sched = ip_vs_sched_getbyname(sched_name); } diff -Nru a/net/ipv4/ipvs/ip_vs_sync.c b/net/ipv4/ipvs/ip_vs_sync.c --- a/net/ipv4/ipvs/ip_vs_sync.c 2005-05-31 13:01:46 -07:00 +++ b/net/ipv4/ipvs/ip_vs_sync.c 2005-05-31 13:01:46 -07:00 @@ -808,10 +808,12 @@ ip_vs_sync_state |= state; if (state == IP_VS_STATE_MASTER) { - strcpy(ip_vs_mcast_master_ifn, mcast_ifn); + strncpy(ip_vs_mcast_master_ifn, mcast_ifn, sizeof(ip_vs_mcast_master_ifn)); + ip_vs_mcast_master_ifn[sizeof(ip_vs_mcast_master_ifn) - 1] = 0; ip_vs_master_syncid = syncid; } else { - strcpy(ip_vs_mcast_backup_ifn, mcast_ifn); + strncpy(ip_vs_mcast_backup_ifn, mcast_ifn, sizeof(ip_vs_mcast_backup_ifn)); + ip_vs_mcast_backup_ifn[sizeof(ip_vs_mcast_backup_ifn) - 1] = 0; ip_vs_backup_syncid = syncid; }