Commit 4ceb5db
Linus Torvalds
Fix get_user_pages() race for write access
There's no real guarantee that handle_mm_fault() will always be able to
break a COW situation - if an update from another thread ends up
modifying the page table some way, handle_mm_fault() may end up
requiring us to re-try the operation.
That's normally fine, but get_user_pages() ended up re-trying it as a
read, and thus a write access could in theory end up losing the dirty
bit or be done on a page that had not been properly COW'ed.
This makes get_user_pages() always retry write accesses as write
accesses by making "follow_page()" require that a writable follow has
the dirty bit set. That simplifies the code and solves the race: if the
COW break fails for some reason, we'll just loop around and try again.
Signed-off-by: Linus Torvalds <[email protected]>1 parent 8d894c4 commit 4ceb5db
1 file changed
Lines changed: 4 additions & 17 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
811 | 811 | | |
812 | 812 | | |
813 | 813 | | |
814 | | - | |
| 814 | + | |
815 | 815 | | |
816 | 816 | | |
817 | 817 | | |
818 | 818 | | |
819 | 819 | | |
820 | 820 | | |
821 | | - | |
822 | | - | |
823 | | - | |
| 821 | + | |
824 | 822 | | |
825 | | - | |
826 | 823 | | |
827 | 824 | | |
828 | 825 | | |
| |||
941 | 938 | | |
942 | 939 | | |
943 | 940 | | |
944 | | - | |
945 | 941 | | |
946 | 942 | | |
947 | | - | |
| 943 | + | |
948 | 944 | | |
949 | 945 | | |
950 | 946 | | |
951 | 947 | | |
952 | 948 | | |
953 | 949 | | |
954 | 950 | | |
955 | | - | |
956 | | - | |
| 951 | + | |
957 | 952 | | |
958 | 953 | | |
959 | 954 | | |
| |||
972 | 967 | | |
973 | 968 | | |
974 | 969 | | |
975 | | - | |
976 | | - | |
977 | | - | |
978 | | - | |
979 | | - | |
980 | | - | |
981 | | - | |
982 | | - | |
983 | 970 | | |
984 | 971 | | |
985 | 972 | | |
| |||
0 commit comments