blob: 3c7666fc202177852a7c6de183c7efbbd6930447 [file] [log] [blame]
Dmitry V. Levin5e7987b2014-12-03 20:30:15 +00001#include "defs.h"
2
Dmitry V. Levinbf7fdfa2014-12-03 20:39:20 +00003enum {
4 CAP_CHOWN,
5 CAP_DAC_OVERRIDE,
6 CAP_DAC_READ_SEARCH,
7 CAP_FOWNER,
8 CAP_FSETID,
9 CAP_KILL,
10 CAP_SETGID,
11 CAP_SETUID,
12 CAP_SETPCAP,
13 CAP_LINUX_IMMUTABLE,
14 CAP_NET_BIND_SERVICE,
15 CAP_NET_BROADCAST,
16 CAP_NET_ADMIN,
17 CAP_NET_RAW,
18 CAP_IPC_LOCK,
19 CAP_IPC_OWNER,
20 CAP_SYS_MODULE,
21 CAP_SYS_RAWIO,
22 CAP_SYS_CHROOT,
23 CAP_SYS_PTRACE,
24 CAP_SYS_PACCT,
25 CAP_SYS_ADMIN,
26 CAP_SYS_BOOT,
27 CAP_SYS_NICE,
28 CAP_SYS_RESOURCE,
29 CAP_SYS_TIME,
30 CAP_SYS_TTY_CONFIG,
31 CAP_MKNOD,
32 CAP_LEASE,
33 CAP_AUDIT_WRITE,
34 CAP_AUDIT_CONTROL,
35 CAP_SETFCAP
36};
Dmitry V. Levin5e7987b2014-12-03 20:30:15 +000037
38#include "xlat/capabilities.h"
39
Dmitry V. Levinbf7fdfa2014-12-03 20:39:20 +000040enum {
41 _LINUX_CAPABILITY_VERSION_1 = 0x19980330,
42 _LINUX_CAPABILITY_VERSION_2 = 0x20071026,
43 _LINUX_CAPABILITY_VERSION_3 = 0x20080522
44};
Dmitry V. Levin5e7987b2014-12-03 20:30:15 +000045
46#include "xlat/cap_version.h"
47
Dmitry V. Levinbf7fdfa2014-12-03 20:39:20 +000048typedef struct user_cap_header_struct {
49 uint32_t version;
50 int pid;
51} *cap_user_header_t;
52
53typedef struct user_cap_data_struct {
54 uint32_t effective;
55 uint32_t permitted;
56 uint32_t inheritable;
57} *cap_user_data_t;
58
Dmitry V. Levin5e7987b2014-12-03 20:30:15 +000059static void
60print_cap_header(struct tcb *tcp, unsigned long addr)
61{
62 union { cap_user_header_t p; long *a; char *c; } arg;
63 long a[sizeof(*arg.p) / sizeof(long) + 1];
64 arg.a = a;
65
66 if (!addr)
67 tprints("NULL");
68 else if (!verbose(tcp) ||
69 umoven(tcp, addr, sizeof(*arg.p), arg.c) < 0)
70 tprintf("%#lx", addr);
71 else {
72 tprints("{");
73 printxval(cap_version, arg.p->version,
74 "_LINUX_CAPABILITY_VERSION_???");
75 tprintf(", %d}", arg.p->pid);
76 }
77}
78
79static void
80print_cap_data(struct tcb *tcp, unsigned long addr)
81{
82 union { cap_user_data_t p; long *a; char *c; } arg;
83 long a[sizeof(*arg.p) / sizeof(long) + 1];
84 arg.a = a;
85
86 if (!addr)
87 tprints("NULL");
88 else if (!verbose(tcp) ||
89 (exiting(tcp) && syserror(tcp)) ||
90 umoven(tcp, addr, sizeof(*arg.p), arg.c) < 0)
91 tprintf("%#lx", addr);
92 else {
93 tprints("{");
94 printflags(capabilities, arg.p->effective, "CAP_???");
95 tprints(", ");
96 printflags(capabilities, arg.p->permitted, "CAP_???");
97 tprints(", ");
98 printflags(capabilities, arg.p->inheritable, "CAP_???");
99 tprints("}");
100 }
101}
102
103int
104sys_capget(struct tcb *tcp)
105{
106 if (entering(tcp)) {
107 print_cap_header(tcp, tcp->u_arg[0]);
108 tprints(", ");
109 } else {
110 print_cap_data(tcp, tcp->u_arg[1]);
111 }
112 return 0;
113}
114
115int
116sys_capset(struct tcb *tcp)
117{
118 if (entering(tcp)) {
119 print_cap_header(tcp, tcp->u_arg[0]);
120 tprints(", ");
121 print_cap_data(tcp, tcp->u_arg[1]);
122 }
123 return 0;
124}