aboutsummaryrefslogtreecommitdiffstats
path: root/fs/notify
diff options
context:
space:
mode:
authorJan Kara <jack@suse.cz>2014-01-21 18:48:13 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2014-01-21 19:19:41 -0500
commite9fe69045bd648d75d8d8099b8658a4ee005a8e5 (patch)
tree9c3e81c861c50df65e3337cbb85af6420a2df47d /fs/notify
parent0abdd7a81b7e3fd781d7fabcca49501852bba17e (diff)
inotify: provide function for name length rounding
Rounding of name length when passing it to userspace was done in several places. Provide a function to do it and use it in all places. Signed-off-by: Jan Kara <jack@suse.cz> Reviewed-by: Christoph Hellwig <hch@lst.de> Cc: Eric Paris <eparis@parisplace.org> Cc: Al Viro <viro@zeniv.linux.org.uk> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'fs/notify')
-rw-r--r--fs/notify/inotify/inotify_user.c41
1 files changed, 21 insertions, 20 deletions
diff --git a/fs/notify/inotify/inotify_user.c b/fs/notify/inotify/inotify_user.c
index 60f954a891ab..1bb6dc8eaf1c 100644
--- a/fs/notify/inotify/inotify_user.c
+++ b/fs/notify/inotify/inotify_user.c
@@ -124,6 +124,13 @@ static unsigned int inotify_poll(struct file *file, poll_table *wait)
124 return ret; 124 return ret;
125} 125}
126 126
127static int round_event_name_len(struct fsnotify_event *event)
128{
129 if (!event->name_len)
130 return 0;
131 return roundup(event->name_len + 1, sizeof(struct inotify_event));
132}
133
127/* 134/*
128 * Get an inotify_kernel_event if one exists and is small 135 * Get an inotify_kernel_event if one exists and is small
129 * enough to fit in "count". Return an error pointer if 136 * enough to fit in "count". Return an error pointer if
@@ -144,9 +151,7 @@ static struct fsnotify_event *get_one_event(struct fsnotify_group *group,
144 151
145 pr_debug("%s: group=%p event=%p\n", __func__, group, event); 152 pr_debug("%s: group=%p event=%p\n", __func__, group, event);
146 153
147 if (event->name_len) 154 event_size += round_event_name_len(event);
148 event_size += roundup(event->name_len + 1, event_size);
149
150 if (event_size > count) 155 if (event_size > count)
151 return ERR_PTR(-EINVAL); 156 return ERR_PTR(-EINVAL);
152 157
@@ -171,7 +176,8 @@ static ssize_t copy_event_to_user(struct fsnotify_group *group,
171 struct fsnotify_event_private_data *fsn_priv; 176 struct fsnotify_event_private_data *fsn_priv;
172 struct inotify_event_private_data *priv; 177 struct inotify_event_private_data *priv;
173 size_t event_size = sizeof(struct inotify_event); 178 size_t event_size = sizeof(struct inotify_event);
174 size_t name_len = 0; 179 size_t name_len;
180 size_t pad_name_len;
175 181
176 pr_debug("%s: group=%p event=%p\n", __func__, group, event); 182 pr_debug("%s: group=%p event=%p\n", __func__, group, event);
177 183
@@ -189,14 +195,13 @@ static ssize_t copy_event_to_user(struct fsnotify_group *group,
189 inotify_free_event_priv(fsn_priv); 195 inotify_free_event_priv(fsn_priv);
190 } 196 }
191 197
198 name_len = event->name_len;
192 /* 199 /*
193 * round up event->name_len so it is a multiple of event_size 200 * round up name length so it is a multiple of event_size
194 * plus an extra byte for the terminating '\0'. 201 * plus an extra byte for the terminating '\0'.
195 */ 202 */
196 if (event->name_len) 203 pad_name_len = round_event_name_len(event);
197 name_len = roundup(event->name_len + 1, event_size); 204 inotify_event.len = pad_name_len;
198 inotify_event.len = name_len;
199
200 inotify_event.mask = inotify_mask_to_arg(event->mask); 205 inotify_event.mask = inotify_mask_to_arg(event->mask);
201 inotify_event.cookie = event->sync_cookie; 206 inotify_event.cookie = event->sync_cookie;
202 207
@@ -209,20 +214,18 @@ static ssize_t copy_event_to_user(struct fsnotify_group *group,
209 /* 214 /*
210 * fsnotify only stores the pathname, so here we have to send the pathname 215 * fsnotify only stores the pathname, so here we have to send the pathname
211 * and then pad that pathname out to a multiple of sizeof(inotify_event) 216 * and then pad that pathname out to a multiple of sizeof(inotify_event)
212 * with zeros. I get my zeros from the nul_inotify_event. 217 * with zeros.
213 */ 218 */
214 if (name_len) { 219 if (pad_name_len) {
215 unsigned int len_to_zero = name_len - event->name_len;
216 /* copy the path name */ 220 /* copy the path name */
217 if (copy_to_user(buf, event->file_name, event->name_len)) 221 if (copy_to_user(buf, event->file_name, name_len))
218 return -EFAULT; 222 return -EFAULT;
219 buf += event->name_len; 223 buf += name_len;
220 224
221 /* fill userspace with 0's */ 225 /* fill userspace with 0's */
222 if (clear_user(buf, len_to_zero)) 226 if (clear_user(buf, pad_name_len - name_len))
223 return -EFAULT; 227 return -EFAULT;
224 buf += len_to_zero; 228 event_size += pad_name_len;
225 event_size += name_len;
226 } 229 }
227 230
228 return event_size; 231 return event_size;
@@ -314,9 +317,7 @@ static long inotify_ioctl(struct file *file, unsigned int cmd,
314 list_for_each_entry(holder, &group->notification_list, event_list) { 317 list_for_each_entry(holder, &group->notification_list, event_list) {
315 event = holder->event; 318 event = holder->event;
316 send_len += sizeof(struct inotify_event); 319 send_len += sizeof(struct inotify_event);
317 if (event->name_len) 320 send_len += round_event_name_len(event);
318 send_len += roundup(event->name_len + 1,
319 sizeof(struct inotify_event));
320 } 321 }
321 mutex_unlock(&group->notification_mutex); 322 mutex_unlock(&group->notification_mutex);
322 ret = put_user(send_len, (int __user *) p); 323 ret = put_user(send_len, (int __user *) p);