History

bpf: rcu lock must not be held when calling copy_to_user()

BUG: sleeping function called from invalid context at mm/memory.c:3732 in_atomic(): 0, irqs_disabled(): 0, pid: 671, name: test_maps 1 lock held by test_maps/671: #0: (rcu_read_lock){......}, at: [<0000000000264190>] map_lookup_elem+0xe8/0x260 Call Trace: ([<0000000000115b7e>] show_trace+0x12e/0x150) [<0000000000115c40>] show_stack+0xa0/0x100 [<00000000009b163c>] dump_stack+0x74/0xc8 [<000000000017424a>] ___might_sleep+0x23a/0x248 [<00000000002b58e8>] might_fault+0x70/0xe8 [<0000000000264230>] map_lookup_elem+0x188/0x260 [<0000000000264716>] SyS_bpf+0x20e/0x840 Fix it by allocating temporary buffer to store map element value.

Alexei Starovoitov committed 11 years ago

Commit 8ebe6671 parent 600ddd61 file · +17 −8Browse files

Showing the changes to kernel (1 of 1 file). Show all

Unified · Split

kernel/bpf/syscall.c+17−8
@@ -150,7 +150,7 @@ static int map_lookup_elem(union bpf_attr *attr) · 149 unmodified lines
150150 int ufd = attr->map_fd;
151151 struct fd f = fdget(ufd);
152152 struct bpf_map *map;
153− void *key, *value;
153+ void *key, *value, *ptr;
154154 int err;
155155
156156 if (CHECK_ATTR(BPF_MAP_LOOKUP_ELEM))
@@ -169,20 +169,29 @@ static int map_lookup_elem(union bpf_attr *attr) · 12 unmodified lines
169169 if (copy_from_user(key, ukey, map->key_size) != 0)
170170 goto free_key;
171171
172− err = -ENOENT;
173− rcu_read_lock();
174− value = map->ops->map_lookup_elem(map, key);
172+ err = -ENOMEM;
173+ value = kmalloc(map->value_size, GFP_USER);
175174 if (!value)
176− goto err_unlock;
175+ goto free_key;
176+
177+ rcu_read_lock();
178+ ptr = map->ops->map_lookup_elem(map, key);
179+ if (ptr)
180+ memcpy(value, ptr, map->value_size);
181+ rcu_read_unlock();
182+
183+ err = -ENOENT;
184+ if (!ptr)
185+ goto free_value;
177186
178187 err = -EFAULT;
179188 if (copy_to_user(uvalue, value, map->value_size) != 0)
180− goto err_unlock;
189+ goto free_value;
181190
182191 err = 0;
183192
184−err_unlock:
185− rcu_read_unlock();
193+free_value:
194+ kfree(value);
186195 free_key:
187196 kfree(key);
188197 err_put:

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t