Commit Graph

59 Commits

Author SHA1 Message Date
bdrewery
872f2680d6 Avoid taking PROC_LOCK in syscalls if not being traced.
MFC after:	1 week
Sponsored by:	EMC / Isilon Storage Division
2016-08-12 16:05:53 +00:00
bdrewery
4d8712daf1 Cleanup COMPAT_FREEBSD32 support.
This is a NOP.

The COMPAT_IA32 was renamed in r205014 to COMPAT_FREEBSD32 and
COMPAT_ARCH32 does not seem to have existed.  Also remove some
leftovers from the sysent rework in r301404.  Include
freebsd32_util.h for the freebsd32_sysent prototype.

X-MFC-With:	r301404
Reported by:	kib
MFC after:	3 days
Sponsored by:	EMC / Isilon Storage Division
2016-06-05 18:16:33 +00:00
bdrewery
5c50060232 Fix build after r301404.
X-MFC-With:	r301404
MFC after:	1 week
2016-06-04 23:34:51 +00:00
bdrewery
c6f9d3eb6c Support all architectures by just using sysent.
PowerPC64 has two different ABIs, neither of which is elf64_freebsd_sysvec.
Using sysent and freebsd32_sysent achieves the same effect.

X-MFC-With:	r301130
MFC after:	1 week
Sponsored by:	EMC / Isilon Storage Division
2016-06-04 17:39:42 +00:00
bdrewery
b6afea100c Don't truncate existing error when writing the log.
Suggested by:	markj
MFC after:	2 weeks
Sponsored by:	EMC / Isilon Storage Division
2016-05-27 23:58:00 +00:00
bdrewery
607786b264 Rename function to be less generic.
MFC after:	2 weeks
Sponsored by:	EMC / Isilon Storage Division
2016-05-27 23:57:57 +00:00
bdrewery
a82abb5c46 Write to the log using the tracer's credentials.
MFC after:	2 weeks
Sponsored by:	EMC / Isilon Storage Division
2016-05-27 23:57:53 +00:00
bdrewery
30f6062748 exec: Cease tracing if credentials will change with the new image.
This also prevents tracing to a P_INEXEC process since it could race
with other processes attaching to it in filemon_event_process_exec() due
to the filemon_get_proc() race of incrementing ref and then locking the
filemon.  With the no-P_INEXEC invariant in place the p_filemon may only
be the same or NULL when trying to drop it in
filemon_event_process_exec().

MFC after:	2 weeks
Sponsored by:	EMC / Isilon Storage Division
Differential Revision:	https://reviews.freebsd.org/D6545
2016-05-27 23:57:43 +00:00
bdrewery
506c645640 filemon exec: Use imgp->execpath rather than vn_fullpath(9).
This will be more accurate as the actual name is provided if ran
from an absolute path in do_execve().

MFC after:	2 weeks
Sponsored by:	EMC / Isilon Storage Division
2016-05-26 23:27:08 +00:00
bdrewery
9a029bd5cd Remove unneeded return left from refactoring.
MFC after:	2 weeks
Sponsored by:	EMC / Isilon Storage Division
2016-03-25 00:14:56 +00:00
bdrewery
f16f170e15 Handle copyin failures.
Skip the log entry as there is nothing good to write out.  Don't fail
the syscall though since it already succeeded.  There's no reason
filemon's tracing failure should fail the already-succeeded syscall.

Record the error for later to return from close(2) on the filemon devfs
file descriptor.

Discussed with:	markj, sjg, kib (briefly with kib)
Reported by:	mjg
MFC after:	2 weeks
Sponsored by:	EMC / Isilon Storage Division
2016-03-22 22:41:14 +00:00
bdrewery
2ad8510bd2 Remove unused done argument to copyinstr(9).
MFC after:	2 weeks
Sponsored by:	EMC / Isilon Storage Division
2016-03-22 22:41:10 +00:00
bdrewery
fb1e803a58 Return any log write failure encountered when closing the filemon fd.
Discussed with:	sjg, markj
Reviewed by:	sjg
MFC after:	2 weeks
Sponsored by:	EMC / Isilon Storage Division
2016-03-22 22:41:07 +00:00
bdrewery
7b6de4a387 Follow-up r297156: Close the log in filemon_dtr rather than in the last reference.
If the tracer has decided to the close the log then it should be fully
written, not getting more entries, when close(2) returns.  This was
a regression in r297156 in that it allowed a traced process to continue
a traced syscall and add more entries to the log while the tracer had
already closed its fd or exited.  This was only really part of the
daemonized process case which is abnormal.

MFC after:	2 weeks
Sponsored by:	EMC / Isilon Storage Division
2016-03-22 22:41:03 +00:00
bdrewery
f66ef83cfe Consolidate common link(2) logic.
MFC after:	2 weeks
Sponsored by:	EMC / Isilon Storage Division
2016-03-21 23:22:19 +00:00
bdrewery
4af0b4cedb Attempt to use the namecache for openat(2) path resolution.
This finishes the work done in D2810.

MFC after:	2 weeks
Sponsored by:	EMC / Isilon Storage Division
2016-03-21 20:29:53 +00:00
bdrewery
c01705f92f Use curthread for vn_fullpath.
No functional change.

MFC after:	2 weeks
Sponsored by:	EMC / Isilon Storage Division
2016-03-21 20:29:46 +00:00
bdrewery
8905ec868c Consolidate open(2) and openat(2) code.
MFC after:	2 weeks
Sponsored by:	EMC / Isilon Storage Division
2016-03-21 20:29:43 +00:00
bdrewery
33d2b813c3 Stop tracking stat(2).
None of lstat(2), fstat(2), fstatat(2) were tracked either.

The other filemon implementations also do not track stat(2), nor
does bmake utilize it.  The act of opening a file for read should
be enough to decide that a file is a dependency.  There could be
rare cases where just having a file would cause a dependency but it
is unlikely.

MFC after:	2 weeks
Also noted by:	sjg
Sponsored by:	EMC / Isilon Storage Division
2016-03-21 20:29:39 +00:00
bdrewery
c059a9d249 Track filemon usage via a proc.p_filemon pointer rather than its own lists.
- proc.p_filemon is added which is protected by PROC_LOCK.  This improves
  performance and avoids double-fork issues, taking allproc_lock
  while in syscalls, and walking the process tree in syscalls.  A
  particular proc.p_filemon can only be changed to NULL or another
  filemon, or the filemon inherited, while the filemon->lock is held.
- Filemon are reference counted.  On the last reference the log will be closed.
- When closing the devfs file handle, the filemon will be detached from all
  processes and inheritance prevented.
- Disallow attaching to a process already being traced since filemon is
  typically intended to be used on children only.  This is allowed for
  curproc as bmake relies on this behavior for rare cases when combining
  .MAKE with .META.
- Detach any previously tracked process on ioctl(FILEMON_SET_PID).
- Handle error from devfs_set_cdevpriv() in filemon_open().
- The global filemon lock and lists are removed.
- A free list is no longer kept.  Previously this list was
  forever-expanding and never garbage cleaned.
- No longer loses track of double-forks.  If the process holding the filemon
  handle closes it will close the log rather than wait on a daemonized process,
  but it will log all activity until it closes its handle.  The filemon
  will be removed from the process and not inherited.
- A separate process count is kept only as an optimization for
  forced detachment to avoid taking allproc_lock and walking the entire
  process tree.
- struct filemon access is protected by sx(9) filemon->lock as it was before.
- Add more comments and KASSERTS.

MFC after:	2 weeks
Reviewed by:	kib, mjg, markj (all on previous versions)
Sponsored by:	EMC / Isilon Storage Division
Differential Revision:	https://reviews.freebsd.org/D5520
2016-03-21 20:29:27 +00:00
bdrewery
bce1a80ea1 FILEMON_SET_FD: Disallow changing the fd.
MFC after:	1 week
Suggested by:	mjg
Sponsored by:	EMC / Isilon Storage Division
2016-03-09 19:50:35 +00:00
bdrewery
064eabeacb Add missing break for r296472.
This was lost in git rebasing, though it has no functional change.

X-MFC-With:	r296472
MFC after:	1 week
2016-03-07 21:45:24 +00:00
bdrewery
a152941076 Require kldunload -f to unload.
Code may still be executing from the wrappers at unload time and thus is
not generally safe to unload.  Converting the wrappers to use
EVENTHANDLER(9) will allow this to safely drain on active threads in
hooks.  More work on EVENTHANDLER(9) is needed first.

MFC after:	1 week
Sponsored by:	EMC / Isilon Storage Division
2016-03-07 21:39:29 +00:00
bdrewery
b73517b7e1 Only call bwillwrite() for logging to vnodes, as other fo_write() calls do.
MFC after:	1 week
Sponsored by:	EMC / Isilon Storage Division
2016-03-07 21:10:19 +00:00
bdrewery
66c82759f6 Remove filemon->lock wrappers.
MFC after:	1 week
Sponsored by:	EMC / Isilon Storage Division
2016-03-02 00:13:13 +00:00
bdrewery
1241a93bc6 Remove old compatibility checks.
MFC after:	3 days
Sponsored by:	EMC / Isilon Storage Division
2016-02-27 21:08:27 +00:00
bdrewery
a7044f8900 Filemon: Fix panic when fork1() is called from kproc_create().
MFC after:	2 weeks
Sponsored by:	EMC / Isilon Storage Division
2016-02-16 02:14:25 +00:00
bdrewery
885522c5df filemon: Track the process pointer rather than a pid.
The process is not held since the process_exit hook is called after the
exithold.  There is no need to hold the process since the hook will
always see it exiting via the process_exit event.

MFC after:	2 weeks
Sponsored by:	EMC / Isilon Storage Division
2016-01-29 00:44:32 +00:00
bdrewery
ac9c98889c filemon_open: Don't record a process to trace here.
Only ioctl(FILEMON_SET_PID) should be setting the process-to-be-traced.

MFC after:	2 weeks
Sponsored by:	EMC / Isilon Storage Division
2016-01-29 00:44:28 +00:00
bdrewery
ecd8f7784d filemon: Use process_exec EVENTHANDLER to capture sys_execve.
MFC after:	2 weeks
Sponsored by:	EMC / Isilon Storage Division
2016-01-28 21:45:25 +00:00
bdrewery
3b41a901ce Follow-up r294967: Mark flags unused.
X-MFC-With:	r294967
MFC after:	2 weeks
Sponsored by:	EMC / Isilon Storage Division
2016-01-28 01:19:19 +00:00
bdrewery
f0449fbcaa filemon: Trace fork via process_fork event.
This avoids needing ugly hooks and needing both a vfork and fork
handler.

MFC after:	2 weeks
Sponsored by:	EMC / Isilon Storage Division
2016-01-28 01:17:55 +00:00
bdrewery
466bcd3bf3 filemon: Use process_exit EVENTHANDLER to capture process exit.
This fixes some cases where a process could exit without being untracked
by filemon.

Reported by:	mjg
MFC after:	2 weeks
Sponsored by:	EMC / Isilon Storage Division
2016-01-28 00:51:17 +00:00
bdrewery
10573611b4 filemon_dtr: Lock the associated filemon handle before writing to it.
Reported by:	mjg
MFC after:	2 weeks
Sponsored by:	EMC / Isilon Storage Division
2016-01-27 21:37:43 +00:00
bdrewery
36b5b4fdf8 filemon_comment has nothing to do with wrappers so move it out of filemon_wrapper.c.
It only prints the header from filemon_ioctl.  Keep the name though to stay
closer to other implementations.

MFC after:	2 weeks
Sponsored by:	EMC / Isilon Storage Division
2016-01-27 21:17:43 +00:00
bdrewery
7819d93d84 filemon_ioctl: Lock the associated filemon handle before writing to it.
Reported by:	mjg
MFC after:	2 weeks
Sponsored by:	EMC / Isilon Storage Division
2016-01-27 21:14:09 +00:00
bdrewery
25f4b65b5a filemon_ioctl: Handle error from devfs_get_cdevpriv(9).
MFC after:	2 weeks
Sponsored by:	EMC / Isilon Storage Division
2016-01-27 21:12:18 +00:00
bdrewery
4019d3df8f Drop any previous fd when setting a new one.
Reported by:	mjg
Sponsored by:	EMC / Isilon Storage Division
MFC after:	2 weeks
2016-01-27 19:11:11 +00:00
bdrewery
1243e7645a Remove unneeded mutex.h include, missed in r287155.
MFC after:	1 week
Sponsored by:	EMC / Isilon Storage Division
2015-11-04 22:49:34 +00:00
bdrewery
3d9be43e02 Remove unneeded NULL as this is initialized with M_ZERO.
MFC after:	2 weeks
Sponsored by:	EMC / Isilon Storage Division
2015-10-29 23:56:34 +00:00
bdrewery
db93f9ed63 Fix filemon locking races.
Convert filemon_lock and struct filemon* lock to sx(9), rather than a
self-rolled reader-writer lock, and hold it for the entire time needed.

At least filemon_lock_write() was not checking for active readers when
it would successfully return with the write lock "held".  This led to
a race with reading entries from filemon_inuse as they were removed.  This
could be seen with QUEUE_MACRO_DEBUG enabled, causing -1 to be read as an
entry rather than a valid struct filemon*.

Fixing filemon_lock_write() to check readers was insufficient to fix the
races.

sx(9) was used as the lock could be held while taking proctree_lock and sleeping
in fo_write.

Sponsored by:	EMC / Isilon Storage Division
MFC after:	2 weeks
2015-08-26 03:44:48 +00:00
bdrewery
f4fac05f94 Avoid taking proctree_lock and searching parents in wrappers if not needed.
This should help the case where filemon is loaded but not in use.

Sponsored by:	EMC / Isilon Storage Division
MFC after:	2 weeks
2015-08-26 03:37:18 +00:00
bdrewery
e71df7419e Remove unneeded inuse list locking in filemon_comment().
Sponsored by:	EMC / Isilon Storage Division
MFC after:	2 weeks
2015-08-26 03:33:34 +00:00
bdrewery
0d526595b8 Move common locking for filemon_inuse and struct filemon* to filemon_pid_check().
This keeps the lock for the filemon_inuse list held only while reading
the list.

Sponsored by:	EMC / Isilon Storage Division
MFC after:	2 weeks
2015-08-26 03:32:47 +00:00
sjg
3f96a9d528 sx_sunlock for sx_slock 2015-06-19 17:34:59 +00:00
sjg
a6e181dfe9 filemon_pid_check needs to hold proctree_lock
Reviewed by:	kib
MFC after:	few days
2015-06-19 17:19:20 +00:00
sjg
089462a20d Bump the version since we now handle openat 2015-06-16 23:03:15 +00:00
sjg
413d62ad57 Latest clang uses openat(2).
If the pathname is absolute or dirfd is AT_FDCWD we can
handle it exactly like open(2).
Otherwise we output an A record to indicate that the path of
an open directory needs to be used (earlier in the trace).

Differential Revision:	D2810
Reviewed by: jhb
MFC after: a bit
2015-06-14 16:31:06 +00:00
rwatson
33fdc14c0c Update kernel inclusions of capability.h to use capsicum.h instead; some
further refinement is required as some device drivers intended to be
portable over FreeBSD versions rely on __FreeBSD_version to decide whether
to include capability.h.

MFC after:	3 weeks
2014-03-16 10:55:57 +00:00
pjd
029a6f5d92 Change the cap_rights_t type from uint64_t to a structure that we can extend
in the future in a backward compatible (API and ABI) way.

The cap_rights_t represents capability rights. We used to use one bit to
represent one right, but we are running out of spare bits. Currently the new
structure provides place for 114 rights (so 50 more than the previous
cap_rights_t), but it is possible to grow the structure to hold at least 285
rights, although we can make it even larger if 285 rights won't be enough.

The structure definition looks like this:

	struct cap_rights {
		uint64_t	cr_rights[CAP_RIGHTS_VERSION + 2];
	};

The initial CAP_RIGHTS_VERSION is 0.

The top two bits in the first element of the cr_rights[] array contain total
number of elements in the array - 2. This means if those two bits are equal to
0, we have 2 array elements.

The top two bits in all remaining array elements should be 0.
The next five bits in all array elements contain array index. Only one bit is
used and bit position in this five-bits range defines array index. This means
there can be at most five array elements in the future.

To define new right the CAPRIGHT() macro must be used. The macro takes two
arguments - an array index and a bit to set, eg.

	#define	CAP_PDKILL	CAPRIGHT(1, 0x0000000000000800ULL)

We still support aliases that combine few rights, but the rights have to belong
to the same array element, eg:

	#define	CAP_LOOKUP	CAPRIGHT(0, 0x0000000000000400ULL)
	#define	CAP_FCHMOD	CAPRIGHT(0, 0x0000000000002000ULL)

	#define	CAP_FCHMODAT	(CAP_FCHMOD | CAP_LOOKUP)

There is new API to manage the new cap_rights_t structure:

	cap_rights_t *cap_rights_init(cap_rights_t *rights, ...);
	void cap_rights_set(cap_rights_t *rights, ...);
	void cap_rights_clear(cap_rights_t *rights, ...);
	bool cap_rights_is_set(const cap_rights_t *rights, ...);

	bool cap_rights_is_valid(const cap_rights_t *rights);
	void cap_rights_merge(cap_rights_t *dst, const cap_rights_t *src);
	void cap_rights_remove(cap_rights_t *dst, const cap_rights_t *src);
	bool cap_rights_contains(const cap_rights_t *big, const cap_rights_t *little);

Capability rights to the cap_rights_init(), cap_rights_set(),
cap_rights_clear() and cap_rights_is_set() functions are provided by
separating them with commas, eg:

	cap_rights_t rights;

	cap_rights_init(&rights, CAP_READ, CAP_WRITE, CAP_FSTAT);

There is no need to terminate the list of rights, as those functions are
actually macros that take care of the termination, eg:

	#define	cap_rights_set(rights, ...)				\
		__cap_rights_set((rights), __VA_ARGS__, 0ULL)
	void __cap_rights_set(cap_rights_t *rights, ...);

Thanks to using one bit as an array index we can assert in those functions that
there are no two rights belonging to different array elements provided
together. For example this is illegal and will be detected, because CAP_LOOKUP
belongs to element 0 and CAP_PDKILL to element 1:

	cap_rights_init(&rights, CAP_LOOKUP | CAP_PDKILL);

Providing several rights that belongs to the same array's element this way is
correct, but is not advised. It should only be used for aliases definition.

This commit also breaks compatibility with some existing Capsicum system calls,
but I see no other way to do that. This should be fine as Capsicum is still
experimental and this change is not going to 9.x.

Sponsored by:	The FreeBSD Foundation
2013-09-05 00:09:56 +00:00