Bug Summary

File:trigger.c
Location:line 142, column 20
Description:Array access (from variable 'args') results in a null pointer dereference

Annotated Source Code

1/*-
2 * Copyright (c) 2007 Aaron L. Meihm
3 * Copyright (c) 2007 Christian S.J. Peron
4 * All rights reserved.
5 *
6 * $Id: trigger.c,v 1.7 2007/02/27 17:41:18 csjp Exp $
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 *
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
22 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28 * SUCH DAMAGE.
29 */
30#include "includes.h"
31
32static const struct _exptab {
33 char *str;
34 int val;
35} exptab[] = {
36 { "subject", EXP_USER },
37 { "object", EXP_OBJECT },
38 { "esubject", EXP_EUSER },
39 { NULL((void *)0), 0 }
40};
41
42char *
43bsm_expand_trigger(struct bsm_record_data *bd, struct bsm_state *bm)
44{
45 char *p0, *p1, *ret, token[2048], *tptr;
46 const struct _exptab *expptr;
47 struct passwd *pw;
48 size_t allocated;
49
50 /* This is a reasonable starting point. */
51 allocated = strlen(bm->bm_trig) + 1024;
52 if ((p1 = ret = calloc(1, allocated)) == NULL((void *)0))
53 return (NULL((void *)0));
54 for (p0 = bm->bm_trig; *p0 != '\0';) {
55 if (*p0 == '$') {
56 /* Look ahead for expansion. */
57 tptr = token;
58 while (isalpha(*(++p0))__sbistype((*(++p0)), 0x00000100L))
59 *(tptr++) = *p0;
60 *tptr = '\0';
61 for (expptr = exptab; expptr->str != NULL((void *)0); expptr++)
62 if (strcmp(expptr->str, token) == 0)
63 break;
64 if (expptr->str == NULL((void *)0)) {
65 /* Expansion failed as an invalid variable
66 * identifier was specified. We should
67 * probably check for this while loading
68 * the configuration file and report on it
69 * at that point. */
70 free(ret);
71 return (NULL((void *)0));
72 }
73 switch (expptr->val) {
74 case EXP_USER:
75 if ((pw = getpwuid(bd->br_auid)) == NULL((void *)0))
76 (void) strlcpy(token, "non-attributable",
77 sizeof(token));
78 else
79 (void) strlcpy(token, pw->pw_name,
80 sizeof(token));
81 break;
82 case EXP_EUSER:
83 if ((pw = getpwuid(bd->br_euid)) == NULL((void *)0))
84 (void) strlcpy(token, "non-attributable",
85 sizeof(token));
86 else
87 (void) strlcpy(token, pw->pw_name,
88 sizeof(token));
89 break;
90 case EXP_OBJECT:
91 if (bd->br_path != NULL((void *)0))
92 (void) strlcpy(token, bd->br_path,
93 sizeof(token));
94 else {
95 free(ret);
96 return (NULL((void *)0));
97 }
98 break;
99 default:
100 assert(0)((0) ? (void)0 : __assert(__func__, "trigger.c", 100, "0"));
101 }
102 (void) strlcat(ret, token, allocated);
103 p1 = ret + strlen(ret);
104 } else
105 *(p1++) = *(p0++);
106 if (p1 >= (ret + allocated)) {
107 free(ret);
108 return (NULL((void *)0));
109 }
110 }
111 return (ret);
112}
113
114void
115bsm_run_trigger(struct bsm_record_data *bd, struct bsm_state *bm)
116{
117 char *cmd, *ptr;
118 char **args;
119 int ret, n;
120
121 assert((bd != NULL) && (bm != NULL))(((bd != ((void *)0)) && (bm != ((void *)0))) ? (void
)0 : __assert(__func__, "trigger.c", 121, "(bd != NULL) && (bm != NULL)"
))
;
122 if (bm->bm_trig[0] == '\0')
1
Taking false branch
123 return;
124 cmd = bsm_expand_trigger(bd, bm);
125 if (cmd != NULL((void *)0)) {
2
Assuming 'cmd' is not equal to null
3
Taking true branch
126 /*
127 * XXX should the failure to execute a trigger be a fatal?
128 */
129 ret = fork();
130 if (ret < 0)
4
Assuming 'ret' is >= 0
5
Taking false branch
131 bsmtrace_error(1, "%s: fork failed", __func__);
132 if (ret == 0) {
6
Assuming 'ret' is equal to 0
7
Taking true branch
133 n = 0;
134 args = calloc(1, sizeof(char *) * TRIGGER_ARGS_MAX64);
8
Value assigned to 'args'
135 if (args == NULL((void *)0))
9
Assuming 'args' is equal to null
10
Taking true branch
136 bsmtrace_error(1, "%s: calloc failed",
137 __func__);
138 dprintf("executing trigger: '%s'\n", cmd);
139 while ((ptr = strsep(&cmd, " ")) != NULL((void *)0)) {
11
Loop condition is true. Entering loop body
140 if (*ptr == '\0')
12
Taking false branch
141 continue;
142 if ((args[n++] = strdup(ptr)) == NULL((void *)0))
13
Array access (from variable 'args') results in a null pointer dereference
143 bsmtrace_error(1, "%s: strdup failed",
144 __func__);
145 }
146 (void) execve(args[0], args, NULL((void *)0));
147 bsmtrace_error(1, "execve: %s", strerror(errno(* __error())));
148 }
149 free(cmd);
150 } else /* XXX Report expansion failure here */
151 bsmtrace_error(0, "%s: expansion failed", bm->bm_trig);
152}