1/* 2 * Copyright (c) Wipro Technologies Ltd, 2002. All Rights Reserved. 3 * 4 * This program is free software; you can redistribute it and/or modify it 5 * under the terms of version 2 of the GNU General Public License as 6 * published by the Free Software Foundation. 7 * 8 * This program is distributed in the hope that it would be useful, but 9 * WITHOUT ANY WARRANTY; without even the implied warranty of 10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 11 * 12 * You should have received a copy of the GNU General Public License along 13 * with this program; if not, write the Free Software Foundation, Inc., 14 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 15 * 16 */ 17/********************************************************** 18 * 19 * TEST IDENTIFIER : syslog12 20 * 21 * EXECUTED BY : root / superuser 22 * 23 * TEST TITLE : Checking error conditions for syslog(2) 24 * 25 * TEST CASE TOTAL : 7 26 * 27 * AUTHOR : Madhu T L <madhu.tarikere@wipro.com> 28 * 29 * SIGNALS 30 * Uses SIGUSR1 to pause before test if option set. 31 * (See the parse_opts(3) man page). 32 * 33 * DESCRIPTION 34 * Verify that, 35 * 1. syslog(2) fails with EINVAL for invalid type/command 36 * 2. syslog(2) fails with EFAULT for buffer outside program's accessible 37 * address space. 38 * 3. syslog(2) fails with EINVAL for NULL buffer argument. 39 * 4. syslog(2) fails with EINVAL for length arg. set to negative value. 40 * 5. syslog(2) fails with EPERM for non-root user. 41 * 6. syslog(2) fails with EINVAL for console level less than 0. 42 * 7. syslog(2) fails with EINVAL for console level greater than 8. 43 * 44 * Setup: 45 * Setup signal handling. 46 * Test caller is superuser 47 * Check existence of user nobody 48 * Set expected errnos 49 * Pause for SIGUSR1 if option specified. 50 * 51 * Test: 52 * Loop if the proper options are given. 53 * Execute system call 54 * Check return value and errno, if matching, 55 * Issue PASS message 56 * Otherwise, 57 * Issue FAIL message 58 * 59 * Cleanup: 60 * Print errno log and/or timing stats if options given 61 * 62 * USAGE: <for command-line> 63 * syslog12 [-c n] [-e] [-f] [-h] [-i n] [-I x] [-p] [-P x] [-t] 64 * where, -c n : Run n copies concurrently. 65 * -e : Turn on errno logging. 66 * -f : Turn off functional testing 67 * -h : Show help screen 68 * -i n : Execute test n times. 69 * -I x : Execute test for x seconds. 70 * -p : Pause for SIGUSR1 before starting 71 * -P x : Pause for x seconds between iterations. 72 * -t : Turn on syscall timing. 73 * 74 ****************************************************************/ 75 76#include <errno.h> 77#include <pwd.h> 78#include <sys/types.h> 79#include <unistd.h> 80#include <signal.h> 81#include <linux/unistd.h> 82#include <sys/syscall.h> 83#include "test.h" 84 85#define EXP_RET_VAL -1 86 87struct test_case_t { /* test case structure */ 88 int type; /* 1st arg */ 89 char *buf; /* 2nd arg */ 90 int len; /* 3rd arg */ 91 int exp_errno; /* Expected errno */ 92 int (*setup) (void); /* Individual setup routine */ 93 void (*cleanup) (void); /* Individual cleanup routine */ 94 char *desc; /* Test description */ 95}; 96 97char *TCID = "syslog12"; 98static int testno; 99 100static char buf; 101static struct passwd *ltpuser; 102 103static void setup(void); 104static void cleanup(void); 105static int setup1(void); 106static void cleanup1(void); 107 108#define syslog(arg1, arg2, arg3) syscall(__NR_syslog, arg1, arg2, arg3) 109 110static struct test_case_t tdat[] = { 111 {100, &buf, 0, EINVAL, NULL, NULL, "invalid type/command"}, 112 {2, NULL, 0, EINVAL, NULL, NULL, "NULL buffer argument"}, 113 {3, &buf, -1, EINVAL, NULL, NULL, "negative length argument"}, 114 {2, &buf, 0, EPERM, setup1, cleanup1, "non-root user"}, 115 {8, &buf, -1, EINVAL, NULL, NULL, "console level less than 0"}, 116 {8, &buf, 9, EINVAL, NULL, NULL, "console level greater than 8"}, 117}; 118 119int TST_TOTAL = sizeof(tdat) / sizeof(tdat[0]); 120 121void timeout(int sig) 122{ 123 tst_resm(TWARN, "syslog() timeout after 1s" 124 " for %s", tdat[testno].desc); 125} 126 127int main(int argc, char **argv) 128{ 129 int lc; 130 struct sigaction sa; 131 int ret; 132 133 tst_parse_opts(argc, argv, NULL, NULL); 134 135 setup(); 136 137 memset(&sa, 0, sizeof(struct sigaction)); 138 sa.sa_handler = timeout; 139 sa.sa_flags = 0; 140 sigaction(SIGALRM, &sa, NULL); 141 142 for (lc = 0; TEST_LOOPING(lc); lc++) { 143 /* reset tst_count in case we are looping */ 144 tst_count = 0; 145 146 for (testno = 0; testno < TST_TOTAL; ++testno) { 147 148 if (tdat[testno].setup && tdat[testno].setup()) { 149 /* Setup failed, skip this testcase */ 150 continue; 151 } 152 153 alarm(1); 154 155 TEST(syslog(tdat[testno].type, tdat[testno].buf, 156 tdat[testno].len)); 157 158 alarm(0); 159 /* syslog returns an int, so we need to turn the long 160 * TEST_RETURN into an int to test with */ 161 ret = TEST_RETURN; 162 if ((ret == EXP_RET_VAL) && 163 (TEST_ERRNO == tdat[testno].exp_errno)) { 164 tst_resm(TPASS, "syslog() failed as expected" 165 " for %s : errno %d", 166 tdat[testno].desc, TEST_ERRNO); 167 } else { 168 tst_resm(TFAIL, "syslog() returned " 169 "unexpected results for %s ; returned" 170 " %d (expected %d), errno %d (expected" 171 " %d)", tdat[testno].desc, 172 ret, EXP_RET_VAL, TEST_ERRNO, 173 tdat[testno].exp_errno); 174 } 175 176 if (tdat[testno].cleanup) { 177 tdat[testno].cleanup(); 178 } 179 } 180 } 181 cleanup(); 182 183 tst_exit(); 184} 185 186int setup1(void) 187{ 188 /* Change effective user id to nodody */ 189 if (seteuid(ltpuser->pw_uid) == -1) { 190 tst_resm(TBROK, "seteuid failed to set the effective" 191 " uid to %d", ltpuser->pw_uid); 192 return 1; 193 } 194 return 0; 195} 196 197void cleanup1(void) 198{ 199 /* Change effective user id to root */ 200 if (seteuid(0) == -1) { 201 tst_brkm(TBROK, NULL, "seteuid failed to set the effective" 202 " uid to root"); 203 } 204} 205 206/* 207 * setup() 208 * performs all ONE TIME setup for this test 209 */ 210void setup(void) 211{ 212 tst_require_root(); 213 214 tst_sig(NOFORK, DEF_HANDLER, cleanup); 215 216 /* Check for nobody_uid user id */ 217 if ((ltpuser = getpwnam("nobody")) == NULL) { 218 tst_brkm(TBROK, NULL, "nobody user id doesn't exist"); 219 } 220 221 /* Pause if that option was specified 222 * TEST_PAUSE contains the code to fork the test with the -c option. 223 */ 224 TEST_PAUSE; 225} 226 227/* 228 * cleanup() 229 * performs all ONE TIME cleanup for this test at 230 * completion or premature exit 231 */ 232void cleanup(void) 233{ 234 235} 236