aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEric W. Biederman <ebiederm@xmission.com>2009-08-27 06:20:04 -0400
committerEric Paris <eparis@redhat.com>2009-08-27 08:02:10 -0400
commit0db501bd0610ee0c0aca84d927f90bcccd09e2bd (patch)
tree108756b2460edff75bb7bc6c778e1a2c0ff50167
parentdead537dd8a1c9495322c1d6f7c780697f474af0 (diff)
inotify: Ensure we alwasy write the terminating NULL.
Before the rewrite copy_event_to_user always wrote a terqminating '\0' byte to user space after the filename. Since the rewrite that terminating byte was skipped if your filename is exactly a multiple of event_size. Ouch! So add one byte to name_size before we round up and use clear_user to set userspace to zero like /dev/zero does instead of copying the strange nul_inotify_event. I can't quite convince myself len_to_zero will never exceed 16 and even if it doesn't clear_user should be more efficient and a more accurate reflection of what the code is trying to do. Signed-off-by: Eric W. Biederman <ebiederm@aristanetworks.com> Signed-off-by: Eric Paris <eparis@redhat.com>
-rw-r--r--fs/notify/inotify/inotify_user.c13
1 files changed, 6 insertions, 7 deletions
diff --git a/fs/notify/inotify/inotify_user.c b/fs/notify/inotify/inotify_user.c
index ce1f5823e2c2..0e781bc88d1e 100644
--- a/fs/notify/inotify/inotify_user.c
+++ b/fs/notify/inotify/inotify_user.c
@@ -47,9 +47,6 @@
47 47
48static struct vfsmount *inotify_mnt __read_mostly; 48static struct vfsmount *inotify_mnt __read_mostly;
49 49
50/* this just sits here and wastes global memory. used to just pad userspace messages with zeros */
51static struct inotify_event nul_inotify_event;
52
53/* these are configurable via /proc/sys/fs/inotify/ */ 50/* these are configurable via /proc/sys/fs/inotify/ */
54static int inotify_max_user_instances __read_mostly; 51static int inotify_max_user_instances __read_mostly;
55static int inotify_max_queued_events __read_mostly; 52static int inotify_max_queued_events __read_mostly;
@@ -199,8 +196,10 @@ static ssize_t copy_event_to_user(struct fsnotify_group *group,
199 inotify_free_event_priv(fsn_priv); 196 inotify_free_event_priv(fsn_priv);
200 } 197 }
201 198
202 /* round up event->name_len so it is a multiple of event_size */ 199 /* round up event->name_len so it is a multiple of event_size
203 name_len = roundup(event->name_len, event_size); 200 * plus an extra byte for the terminating '\0'.
201 */
202 name_len = roundup(event->name_len + 1, event_size);
204 inotify_event.len = name_len; 203 inotify_event.len = name_len;
205 204
206 inotify_event.mask = inotify_mask_to_arg(event->mask); 205 inotify_event.mask = inotify_mask_to_arg(event->mask);
@@ -224,8 +223,8 @@ static ssize_t copy_event_to_user(struct fsnotify_group *group,
224 return -EFAULT; 223 return -EFAULT;
225 buf += event->name_len; 224 buf += event->name_len;
226 225
227 /* fill userspace with 0's from nul_inotify_event */ 226 /* fill userspace with 0's */
228 if (copy_to_user(buf, &nul_inotify_event, len_to_zero)) 227 if (clear_user(buf, len_to_zero))
229 return -EFAULT; 228 return -EFAULT;
230 buf += len_to_zero; 229 buf += len_to_zero;
231 event_size += name_len; 230 event_size += name_len;