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
|
#include <string.h>
#include "fs.h"
#include "file.h"
/*===========================================================================*
* do_gcov_flush *
*===========================================================================*/
int do_gcov_flush(void)
{
/* A userland tool has requested the gcov data from another
* process (possibly vfs itself). Grant the target process
* access to the supplied buffer, and perform the call that
* makes the target copy its buffer to the caller (incl vfs
* itself).
*/
char label[LABEL_MAX];
vir_bytes labeladdr, buf;
size_t labellen, size;
endpoint_t endpt;
cp_grant_id_t grantid;
int r;
message m;
/*
* Something as sensitive as system service coverage information must be
* call to the target service, and so it is not impossible to deadlock the
* system with this call.
*/
if (!super_user) return(EPERM);
labeladdr = job_m_in.m_lc_vfs_gcov.label;
labellen = job_m_in.m_lc_vfs_gcov.labellen;
buf = job_m_in.m_lc_vfs_gcov.buf;
size = job_m_in.m_lc_vfs_gcov.buflen;
/* Retrieve and look up the target label. */
if (labellen >= sizeof(label))
return EINVAL;
if ((r = sys_datacopy_wrapper(who_e, labeladdr, SELF, (vir_bytes)label,
labellen)) != OK)
return r;
label[labellen - 1] = '\0';
if ((r = ds_retrieve_label_endpt(label, &endpt)) != OK)
return r;
/* Hack: init is the only non-system process with a valid label. */
if (endpt == INIT_PROC_NR)
return ENOENT;
/* Grant target process to requestor's buffer. */
if ((grantid = cpf_grant_magic(endpt, who_e, buf, size, CPF_WRITE)) < 0) {
printf("VFS: gcov_flush: grant failed\n");
return(ENOMEM);
}
if (endpt == VFS_PROC_NR) {
/* Request is for VFS itself. */
r = gcov_flush(VFS_PROC_NR, grantid, size);
} else {
/* Perform generic GCOV request. */
memset(&m, 0, sizeof(m));
m.m_vfs_lsys_gcov.grant = grantid;
m.m_vfs_lsys_gcov.size = size;
r = _taskcall(endpt, COMMON_REQ_GCOV_DATA, &m);
}
cpf_revoke(grantid);
return(r);
}
|