* Write an audit record to a file, performed as the last stage after both * preselection and BSM conversion. Both space management and write failures * are handled in this function. * * No attempt is made to deal with possible failure to deliver a trigger to * the audit daemon, since the message is asynchronous anyway. */
| 136 | * the audit daemon, since the message is asynchronous anyway. |
| 137 | */ |
| 138 | static void |
| 139 | audit_record_write(struct vnode *vp, struct ucred *cred, void *data, |
| 140 | size_t len) |
| 141 | { |
| 142 | static struct timeval last_lowspace_trigger; |
| 143 | static struct timeval last_fail; |
| 144 | static int cur_lowspace_trigger; |
| 145 | struct statfs *mnt_stat; |
| 146 | struct mount *mp; |
| 147 | int error; |
| 148 | static int cur_fail; |
| 149 | long temp; |
| 150 | |
| 151 | AUDIT_WORKER_LOCK_ASSERT(); |
| 152 | |
| 153 | if (vp == NULL) |
| 154 | return; |
| 155 | |
| 156 | mp = vp->v_mount; |
| 157 | if (mp == NULL) { |
| 158 | error = EINVAL; |
| 159 | goto fail; |
| 160 | } |
| 161 | error = vfs_busy(mp, 0); |
| 162 | if (error != 0) { |
| 163 | mp = NULL; |
| 164 | goto fail; |
| 165 | } |
| 166 | mnt_stat = &mp->mnt_stat; |
| 167 | |
| 168 | /* |
| 169 | * First, gather statistics on the audit log file and file system so |
| 170 | * that we know how we're doing on space. Consider failure of these |
| 171 | * operations to indicate a future inability to write to the file. |
| 172 | */ |
| 173 | error = VFS_STATFS(mp, mnt_stat); |
| 174 | if (error != 0) |
| 175 | goto fail; |
| 176 | |
| 177 | /* |
| 178 | * We handle four different space-related limits: |
| 179 | * |
| 180 | * - A fixed (hard) limit on the minimum free blocks we require on |
| 181 | * the file system, and results in record loss, a trigger, and |
| 182 | * possible fail stop due to violating invariants. |
| 183 | * |
| 184 | * - An administrative (soft) limit, which when fallen below, results |
| 185 | * in the kernel notifying the audit daemon of low space. |
| 186 | * |
| 187 | * - An audit trail size limit, which when gone above, results in the |
| 188 | * kernel notifying the audit daemon that rotation is desired. |
| 189 | * |
| 190 | * - The total depth of the kernel audit record exceeding free space, |
| 191 | * which can lead to possible fail stop (with drain), in order to |
| 192 | * prevent violating invariants. Failure here doesn't halt |
| 193 | * immediately, but prevents new records from being generated. |
| 194 | * |
| 195 | * Possibly, the last of these should be handled differently, always |
no test coverage detected