diff options
author | Richard Cochran <richardcochran@gmail.com> | 2012-11-26 01:44:35 +0000 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2012-11-26 17:22:14 -0500 |
commit | c3484c275db5abe88e01a7e1a80932112c9bbf69 (patch) | |
tree | 0113d9e291e5fcf3d3ba7bd70d7c8ccf9b885e30 | |
parent | c7ec0badcc54508d3ab052bb425cc677521a89be (diff) | |
download | linux-stable-c3484c275db5abe88e01a7e1a80932112c9bbf69.tar.gz linux-stable-c3484c275db5abe88e01a7e1a80932112c9bbf69.tar.bz2 linux-stable-c3484c275db5abe88e01a7e1a80932112c9bbf69.zip |
ptp: reduce stack usage when measuring the system time offset
This patch removes the large buffer from the stack of the system
offset ioctl and replaces it with a kmalloced buffer.
Signed-off-by: Richard Cochran <richardcochran@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | drivers/ptp/ptp_chardev.c | 21 |
1 files changed, 14 insertions, 7 deletions
diff --git a/drivers/ptp/ptp_chardev.c b/drivers/ptp/ptp_chardev.c index 9d7542efb175..34a0c607318e 100644 --- a/drivers/ptp/ptp_chardev.c +++ b/drivers/ptp/ptp_chardev.c @@ -34,7 +34,7 @@ long ptp_ioctl(struct posix_clock *pc, unsigned int cmd, unsigned long arg) { struct ptp_clock_caps caps; struct ptp_clock_request req; - struct ptp_sys_offset sysoff; + struct ptp_sys_offset *sysoff = NULL; struct ptp_clock *ptp = container_of(pc, struct ptp_clock, clock); struct ptp_clock_info *ops = ptp->info; struct ptp_clock_time *pct; @@ -94,17 +94,22 @@ long ptp_ioctl(struct posix_clock *pc, unsigned int cmd, unsigned long arg) break; case PTP_SYS_OFFSET: - if (copy_from_user(&sysoff, (void __user *)arg, - sizeof(sysoff))) { + sysoff = kmalloc(sizeof(*sysoff), GFP_KERNEL); + if (!sysoff) { + err = -ENOMEM; + break; + } + if (copy_from_user(sysoff, (void __user *)arg, + sizeof(*sysoff))) { err = -EFAULT; break; } - if (sysoff.n_samples > PTP_MAX_SAMPLES) { + if (sysoff->n_samples > PTP_MAX_SAMPLES) { err = -EINVAL; break; } - pct = &sysoff.ts[0]; - for (i = 0; i < sysoff.n_samples; i++) { + pct = &sysoff->ts[0]; + for (i = 0; i < sysoff->n_samples; i++) { getnstimeofday(&ts); pct->sec = ts.tv_sec; pct->nsec = ts.tv_nsec; @@ -117,7 +122,7 @@ long ptp_ioctl(struct posix_clock *pc, unsigned int cmd, unsigned long arg) getnstimeofday(&ts); pct->sec = ts.tv_sec; pct->nsec = ts.tv_nsec; - if (copy_to_user((void __user *)arg, &sysoff, sizeof(sysoff))) + if (copy_to_user((void __user *)arg, sysoff, sizeof(*sysoff))) err = -EFAULT; break; @@ -125,6 +130,8 @@ long ptp_ioctl(struct posix_clock *pc, unsigned int cmd, unsigned long arg) err = -ENOTTY; break; } + + kfree(sysoff); return err; } |