• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * Copyright (c) 2017 Cyril Hrubis <chrubis@suse.cz>
4  */
5 
6 #define _GNU_SOURCE
7 #include <unistd.h>
8 #include <errno.h>
9 #include <sched.h>
10 #include <sys/ptrace.h>
11 #include "config.h"
12 #ifdef HAVE_SYS_FANOTIFY_H
13 # include <sys/fanotify.h>
14 #endif
15 #define TST_NO_DEFAULT_MAIN
16 #include "tst_test.h"
17 #include "lapi/setns.h"
18 #include "tst_safe_macros.h"
19 #include "lapi/personality.h"
20 
safe_setpgid(const char * file,const int lineno,pid_t pid,pid_t pgid)21 int safe_setpgid(const char *file, const int lineno, pid_t pid, pid_t pgid)
22 {
23 	int rval;
24 
25 	rval = setpgid(pid, pgid);
26 	if (rval) {
27 		tst_brk(TBROK | TERRNO,
28 		        "%s:%d: setpgid(%i, %i) failed",
29 			file, lineno, pid, pgid);
30 	}
31 
32 	return rval;
33 }
34 
safe_getpgid(const char * file,const int lineno,pid_t pid)35 pid_t safe_getpgid(const char *file, const int lineno, pid_t pid)
36 {
37 	pid_t pgid;
38 
39 	pgid = getpgid(pid);
40 	if (pgid == -1) {
41 		tst_brk(TBROK | TERRNO,
42 			"%s:%d: getpgid(%i) failed", file, lineno, pid);
43 	}
44 
45 	return pgid;
46 }
47 
safe_fanotify_init(const char * file,const int lineno,unsigned int flags,unsigned int event_f_flags)48 int safe_fanotify_init(const char *file, const int lineno,
49 	unsigned int flags, unsigned int event_f_flags)
50 {
51 	int rval;
52 
53 #ifdef HAVE_SYS_FANOTIFY_H
54 	rval = fanotify_init(flags, event_f_flags);
55 
56 	if (rval == -1) {
57 		if (errno == ENOSYS) {
58 			tst_brk(TCONF,
59 				"fanotify is not configured in this kernel.");
60 		}
61 		tst_brk(TBROK | TERRNO,
62 			"%s:%d: fanotify_init() failed", file, lineno);
63 	}
64 #else
65 	tst_brk(TCONF, "Header <sys/fanotify.h> is not present");
66 #endif /* HAVE_SYS_FANOTIFY_H */
67 
68 	return rval;
69 }
70 
safe_personality(const char * filename,unsigned int lineno,unsigned long persona)71 int safe_personality(const char *filename, unsigned int lineno,
72 		    unsigned long persona)
73 {
74 	int prev_persona = personality(persona);
75 
76 	if (prev_persona < 0) {
77 		tst_brk_(filename, lineno, TBROK | TERRNO,
78 			 "persona(%ld) failed", persona);
79 	}
80 
81 	return prev_persona;
82 }
83 
safe_setregid(const char * file,const int lineno,gid_t rgid,gid_t egid)84 int safe_setregid(const char *file, const int lineno,
85 		  gid_t rgid, gid_t egid)
86 {
87 	int rval;
88 
89 	rval = setregid(rgid, egid);
90 	if (rval == -1) {
91 		tst_brk_(file, lineno, TBROK | TERRNO,
92 			 "setregid(%li, %li) failed",
93 			 (long)rgid, (long)egid);
94 	}
95 
96 	return rval;
97 }
98 
99 
safe_setreuid(const char * file,const int lineno,uid_t ruid,uid_t euid)100 int safe_setreuid(const char *file, const int lineno,
101 		  uid_t ruid, uid_t euid)
102 {
103 	int rval;
104 
105 	rval = setreuid(ruid, euid);
106 	if (rval == -1) {
107 		tst_brk_(file, lineno, TBROK | TERRNO,
108 			 "setreuid(%li, %li) failed",
109 			 (long)ruid, (long)euid);
110 	}
111 
112 	return rval;
113 }
114 
115 
safe_sigaction(const char * file,const int lineno,int signum,const struct sigaction * act,struct sigaction * oldact)116 int safe_sigaction(const char *file, const int lineno,
117                    int signum, const struct sigaction *act,
118                    struct sigaction *oldact)
119 {
120 	int rval;
121 
122 	rval = sigaction(signum, act, oldact);
123 
124 	if (rval == -1) {
125 		tst_brk_(file, lineno, TBROK | TERRNO,
126 			"sigaction(%s (%d), %p, %p) failed",
127 			tst_strsig(signum), signum, act, oldact);
128 	}
129 
130 	return rval;
131 }
132 
safe_getgrnam(const char * file,const int lineno,const char * name)133 struct group *safe_getgrnam(const char *file, const int lineno,
134 			    const char *name)
135 {
136 	struct group *rval;
137 
138 	errno = 0;
139 	rval = getgrnam(name);
140 	if (rval == NULL) {
141 		tst_brk_(file, lineno, TBROK | TERRNO,
142 			"getgrnam(%s) failed", name);
143 	}
144 
145 	return rval;
146 }
147 
safe_getgrnam_fallback(const char * file,const int lineno,const char * name,const char * fallback)148 struct group *safe_getgrnam_fallback(const char *file, const int lineno,
149 				     const char *name, const char *fallback)
150 {
151 	struct group *rval;
152 
153 	errno = 0;
154 	rval = getgrnam(name);
155 	if (rval == NULL) {
156 		tst_res_(file, lineno, TINFO,
157 			 "getgrnam(%s) failed - try fallback %s",
158 			 name, fallback);
159 		rval = safe_getgrnam(file, lineno, fallback);
160 	}
161 
162 	return rval;
163 }
164 
safe_getgrgid(const char * file,const int lineno,gid_t gid)165 struct group *safe_getgrgid(const char *file, const int lineno, gid_t gid)
166 {
167 	struct group *rval;
168 
169 	errno = 0;
170 	rval = getgrgid(gid);
171 	if (rval == NULL) {
172 		tst_brk_(file, lineno, TBROK | TERRNO,
173 			"getgrgid(%li) failed", (long)gid);
174 	}
175 
176 	return rval;
177 }
178 
safe_chroot(const char * file,const int lineno,const char * path)179 int safe_chroot(const char *file, const int lineno, const char *path)
180 {
181 	int rval;
182 
183 	rval = chroot(path);
184 	if (rval == -1) {
185 		tst_brk_(file, lineno, TBROK | TERRNO,
186 			 "chroot(%s) failed", path);
187 	}
188 
189 	return rval;
190 }
191 
safe_unshare(const char * file,const int lineno,int flags)192 void safe_unshare(const char *file, const int lineno, int flags)
193 {
194 	int res;
195 
196 	res = unshare(flags);
197 	if (res == -1) {
198 		if (errno == EINVAL) {
199 			tst_brk_(file, lineno, TCONF | TERRNO,
200 				 "unshare(%d) unsupported", flags);
201 		} else {
202 			tst_brk_(file, lineno, TBROK | TERRNO,
203 				 "unshare(%d) failed", flags);
204 		}
205 	}
206 }
207 
safe_setns(const char * file,const int lineno,int fd,int nstype)208 void safe_setns(const char *file, const int lineno, int fd, int nstype)
209 {
210 	int ret;
211 
212 	ret = setns(fd, nstype);
213 	if (ret == -1) {
214 		tst_brk_(file, lineno, TBROK | TERRNO, "setns(%i, %i) failed",
215 		         fd, nstype);
216 	}
217 }
218 
tst_safe_ptrace(const char * file,const int lineno,int req,pid_t pid,void * addr,void * data)219 long tst_safe_ptrace(const char *file, const int lineno, int req, pid_t pid,
220 	void *addr, void *data)
221 {
222 	long ret;
223 
224 	errno = 0;
225 	ret = ptrace(req, pid, addr, data);
226 
227 	if (ret == -1) {
228 		tst_brk_(file, lineno, TBROK | TERRNO, "ptrace() failed");
229 	} else if (ret) {
230 		tst_brk_(file, lineno, TBROK | TERRNO,
231 			"Invalid ptrace() return value %ld", ret);
232 	}
233 
234 	return ret;
235 }
236 
safe_pipe2(const char * file,const int lineno,int fildes[2],int flags)237 int safe_pipe2(const char *file, const int lineno, int fildes[2], int flags)
238 {
239 	int ret;
240 
241 	ret = pipe2(fildes, flags);
242 	if (ret == -1) {
243 		tst_brk_(file, lineno, TBROK | TERRNO,
244 			"pipe2({%d,%d}) failed with flag(%d)",
245 			fildes[0], fildes[1], flags);
246 	}
247 
248 	return ret;
249 }
250