DF-3112 / fix_combined_for_validation.diff
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 | --- a/sys/vfs/hammer/hammer_ioctl.c +++ b/sys/vfs/hammer/hammer_ioctl.c @@ -84,8 +84,10 @@ } break; case HAMMERIOC_GETHISTORY: - error = hammer_ioc_gethistory(&trans, ip, + if (error == 0) { + error = hammer_ioc_gethistory(&trans, ip, (struct hammer_ioc_history *)data); + } break; case HAMMERIOC_REBLOCK: if (error == 0 && hmp->ronly) @@ -115,12 +117,16 @@ } break; case HAMMERIOC_SYNCTID: - error = hammer_ioc_synctid(&trans, ip, + if (error == 0) { + error = hammer_ioc_synctid(&trans, ip, (struct hammer_ioc_synctid *)data); + } break; case HAMMERIOC_GET_PSEUDOFS: - error = hammer_ioc_get_pseudofs(&trans, ip, + if (error == 0) { + error = hammer_ioc_get_pseudofs(&trans, ip, (struct hammer_ioc_pseudofs_rw *)data); + } break; case HAMMERIOC_SET_PSEUDOFS: if (error == 0 && hmp->ronly) @@ -175,12 +181,16 @@ } break; case HAMMERIOC_GET_VERSION: - error = hammer_ioc_get_version(&trans, ip, + if (error == 0) { + error = hammer_ioc_get_version(&trans, ip, (struct hammer_ioc_version *)data); + } break; case HAMMERIOC_GET_INFO: - error = hammer_ioc_get_info(&trans, + if (error == 0) { + error = hammer_ioc_get_info(&trans, (struct hammer_ioc_info *)data); + } break; case HAMMERIOC_SET_VERSION: if (error == 0 && hmp->ronly) @@ -211,8 +221,10 @@ } break; case HAMMERIOC_LIST_VOLUMES: - error = hammer_ioc_volume_list(&trans, ip, - (struct hammer_ioc_volume_list *)data); + if (error == 0) { + error = hammer_ioc_volume_list(&trans, ip, + (struct hammer_ioc_volume_list *)data); + } break; case HAMMERIOC_ADD_SNAPSHOT: if (error == 0 && hmp->ronly) @@ -231,12 +243,18 @@ } break; case HAMMERIOC_GET_SNAPSHOT: - error = hammer_ioc_get_snapshot( - &trans, ip, (struct hammer_ioc_snapshot *)data); + if (error == 0) { + error = hammer_ioc_get_snapshot( + &trans, ip, + (struct hammer_ioc_snapshot *)data); + } break; case HAMMERIOC_GET_CONFIG: - error = hammer_ioc_get_config( - &trans, ip, (struct hammer_ioc_config *)data); + if (error == 0) { + error = hammer_ioc_get_config( + &trans, ip, + (struct hammer_ioc_config *)data); + } break; case HAMMERIOC_SET_CONFIG: if (error == 0 && hmp->ronly) @@ -261,8 +279,11 @@ } break; case HAMMERIOC_SCAN_PSEUDOFS: - error = hammer_ioc_scan_pseudofs( - &trans, ip, (struct hammer_ioc_pseudofs_rw *)data); + if (error == 0) { + error = hammer_ioc_scan_pseudofs( + &trans, ip, + (struct hammer_ioc_pseudofs_rw *)data); + } break; default: error = EOPNOTSUPP; @@ -296,6 +317,12 @@ if (hist->head.flags & HAMMER_IOC_HISTORY_ATKEY) { if (hist->key > hist->nxt_key) return(EINVAL); + /* + * Reject the boundary: the REGFILE scan below increments + * key_beg.key and would overflow int64 at HAMMER_MAX_KEY. + */ + if (hist->key >= HAMMER_MAX_KEY) + return(EINVAL); } hist->obj_id = ip->obj_id; @@ -383,6 +410,15 @@ HAMMER_LOCALIZE_INODE; } + /* + * Honor any validation error from the ATKEY switch() above + * (e.g. unsupported object type) instead of overwriting it. + */ + if (error) { + hammer_done_cursor(&cursor); + return(error); + } + error = hammer_btree_first(&cursor); while (error == 0) { elm = &cursor.node->ondisk->elms[cursor.index]; |