Skip to content

Commit 3ee9351

Browse files
author
Darrick J. Wong
committed
xfs: validate fsmap offsets specified in the query keys
Improve the validation of the fsmap offset fields in the query keys and move the validation to the top of the function now that we have pushed the low key adjustment code downwards. Also fix some indenting issues that aren't worth a separate patch. Signed-off-by: Darrick J. Wong <djwong@kernel.org> Reviewed-by: Dave Chinner <dchinner@redhat.com>
1 parent a949a1c commit 3ee9351

File tree

1 file changed

+19
-11
lines changed

1 file changed

+19
-11
lines changed

fs/xfs/xfs_fsmap.c

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -802,6 +802,19 @@ xfs_getfsmap_check_keys(
802802
struct xfs_fsmap *low_key,
803803
struct xfs_fsmap *high_key)
804804
{
805+
if (low_key->fmr_flags & (FMR_OF_SPECIAL_OWNER | FMR_OF_EXTENT_MAP)) {
806+
if (low_key->fmr_offset)
807+
return false;
808+
}
809+
if (high_key->fmr_flags != -1U &&
810+
(high_key->fmr_flags & (FMR_OF_SPECIAL_OWNER |
811+
FMR_OF_EXTENT_MAP))) {
812+
if (high_key->fmr_offset && high_key->fmr_offset != -1ULL)
813+
return false;
814+
}
815+
if (high_key->fmr_length && high_key->fmr_length != -1ULL)
816+
return false;
817+
805818
if (low_key->fmr_device > high_key->fmr_device)
806819
return false;
807820
if (low_key->fmr_device < high_key->fmr_device)
@@ -845,15 +858,15 @@ xfs_getfsmap_check_keys(
845858
* ----------------
846859
* There are multiple levels of keys and counters at work here:
847860
* xfs_fsmap_head.fmh_keys -- low and high fsmap keys passed in;
848-
* these reflect fs-wide sector addrs.
861+
* these reflect fs-wide sector addrs.
849862
* dkeys -- fmh_keys used to query each device;
850-
* these are fmh_keys but w/ the low key
851-
* bumped up by fmr_length.
863+
* these are fmh_keys but w/ the low key
864+
* bumped up by fmr_length.
852865
* xfs_getfsmap_info.next_daddr -- next disk addr we expect to see; this
853866
* is how we detect gaps in the fsmap
854867
records and report them.
855868
* xfs_getfsmap_info.low/high -- per-AG low/high keys computed from
856-
* dkeys; used to query the metadata.
869+
* dkeys; used to query the metadata.
857870
*/
858871
int
859872
xfs_getfsmap(
@@ -874,6 +887,8 @@ xfs_getfsmap(
874887
if (!xfs_getfsmap_is_valid_device(mp, &head->fmh_keys[0]) ||
875888
!xfs_getfsmap_is_valid_device(mp, &head->fmh_keys[1]))
876889
return -EINVAL;
890+
if (!xfs_getfsmap_check_keys(&head->fmh_keys[0], &head->fmh_keys[1]))
891+
return -EINVAL;
877892

878893
use_rmap = xfs_has_rmapbt(mp) &&
879894
has_capability_noaudit(current, CAP_SYS_ADMIN);
@@ -919,15 +934,8 @@ xfs_getfsmap(
919934
* other mapping for the same physical block range.
920935
*/
921936
dkeys[0] = head->fmh_keys[0];
922-
if (dkeys[0].fmr_flags & (FMR_OF_SPECIAL_OWNER | FMR_OF_EXTENT_MAP)) {
923-
if (dkeys[0].fmr_offset)
924-
return -EINVAL;
925-
}
926937
memset(&dkeys[1], 0xFF, sizeof(struct xfs_fsmap));
927938

928-
if (!xfs_getfsmap_check_keys(dkeys, &head->fmh_keys[1]))
929-
return -EINVAL;
930-
931939
info.next_daddr = head->fmh_keys[0].fmr_physical +
932940
head->fmh_keys[0].fmr_length;
933941
info.fsmap_recs = fsmap_recs;

0 commit comments

Comments
 (0)