Bug Summary

File:obj-scan-build/daemons/../../daemons/getty.c
Location:line 125, column 9
Description:Memory is never released; potential leak of memory pointed to by 't'

Annotated Source Code

1/* Stubby version of getty for Hurd
2
3 Copyright (C) 1996, 1998, 1999, 2007, 2014
4 Free Software Foundation, Inc.
5
6 Written by Michael I. Bushnell, p/BSG.
7
8 This file is part of the GNU Hurd.
9
10 The GNU Hurd is free software; you can redistribute it and/or
11 modify it under the terms of the GNU General Public License as
12 published by the Free Software Foundation; either version 2, or (at
13 your option) any later version.
14
15 The GNU Hurd is distributed in the hope that it will be useful, but
16 WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 General Public License for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. */
23
24#include <syslog.h>
25#include <unistd.h>
26#include <ttyent.h>
27#include <stdio.h>
28#include <fcntl.h>
29#include <sys/stat.h>
30#include <errno(*__errno_location ()).h>
31#include <error.h>
32#include <sys/utsname.h>
33#include <stdlib.h>
34#include <string.h>
35#include <utmp.h>
36#include <sys/ioctl.h>
37#include <termios.h>
38
39/* XXX */
40extern char *localhost ();
41
42#define _PATH_LOGIN"/bin/login" "/bin/login"
43#define _PATH_ISSUE"/etc/issue" "/etc/issue"
44
45/* Parse the terminal speed. */
46static void
47set_speed (int tty, char *speedstr)
48{
49 error_t err;
50 struct termios ttystat;
51 speed_t speed;
52 char *tail;
53
54 errno(*__errno_location ()) = 0;
55 speed = strtoul (speedstr, &tail, 0);
56 if (errno(*__errno_location ()) || *tail)
57 return;
58
59 err = tcgetattr (tty, &ttystat);
60 if (!err && !cfsetspeed (&ttystat, speed))
61 tcsetattr (tty, TCSAFLUSH2, &ttystat);
62}
63
64/* Load a banner from _PATH_ISSUE. If that fails, a built-in version
65 is provided. */
66static char *
67load_banner (void)
68{
69 char *buf = NULL((void*)0), *p;
70 struct stat st;
71 int fd;
72 ssize_t remaining, count;
73
74 fd = open (_PATH_ISSUE"/etc/issue", O_RDONLY0x0001);
75 if (fd == -1)
8
Taking false branch
76 goto out;
77
78 if (fstat (fd, &st) == -1)
9
Taking false branch
79 goto out;
80
81 buf = malloc (st.st_size + 1);
10
Memory is allocated
82 if (buf == NULL((void*)0))
11
Assuming 'buf' is not equal to null
12
Taking false branch
83 goto out;
84
85 remaining = st.st_size;
86 p = buf;
87 while (remaining > 0)
13
Assuming 'remaining' is <= 0
14
Loop condition is false. Execution continues on line 99
88 {
89 count = read (fd, p, remaining);
90 if (count == -1)
91 {
92 close (fd);
93 goto out;
94 }
95 p += count;
96 remaining -= count;
97 }
98
99 buf[st.st_size] = '\0';
100 close (fd);
101 return buf;
102
103 out:
104 free (buf);
105 return "\n\\s \\r (\\n) (\\l)\r\n\n";
106}
107
108/* Print a suitable welcome banner */
109static void
110print_banner (int fd, char *ttyname)
111{
112 char *s, *t, *expansion;
113 struct utsname u;
114
115 if (uname (&u))
6
Taking false branch
116 u.sysname[0] = u.release[0] = '\0';
117
118 write (fd, "\r\n", 2);
119 for (s = load_banner (); *s; s++)
7
Calling 'load_banner'
15
Returned allocated memory
16
Loop condition is true. Entering loop body
120 {
121 for (t = s; *t && *t != '\\'; t++) /* nomnomnom */;
17
Loop condition is false. Execution continues on line 123
122
123 write (fd, s, t - s);
124 if (! *t)
18
Taking true branch
125 return;
19
Memory is never released; potential leak of memory pointed to by 't'
126
127 switch (*(t + 1))
128 {
129 case '\\':
130 expansion = "\\";
131 break;
132 case 's':
133 expansion = u.sysname;
134 break;
135 case 'r':
136 expansion = u.release;
137 break;
138 case 'n':
139 expansion = localhost () ?: "?";
140 break;
141 case 'l':
142 expansion = basename (ttyname);
143 break;
144 default:
145 expansion = "?";
146 }
147 write (fd, expansion, strlen (expansion));
148
149 s = t + 1;
150 }
151}
152
153int
154main (int argc, char **argv)
155{
156 char *linespec, *ttyname;
157 int tty;
158 struct ttyent *tt;
159 char *arg;
160
161 openlog ("getty", LOG_ODELAY0x04|LOG_CONS0x02|LOG_PID0x01, LOG_AUTH(4<<3));
162
163 /* Nothing to do .... */
164 if (argc != 3)
1
Assuming 'argc' is equal to 3
2
Taking false branch
165 {
166 syslog (LOG_ERR3, "Bad syntax");
167 closelog ();
168 exit (1);
169 }
170
171 /* Don't do anything with this for now. */
172 linespec = argv[1];
173
174 tt = getttynam (argv[2]);
175 asprintf (&ttyname, "%s/%s", _PATH_DEV"/dev/", argv[2]);
176
177 chown (ttyname, 0, 0);
178 chmod (ttyname, 0600);
179 revoke (ttyname);
180 sleep (2); /* leave DTR down for a bit */
181
182 do
4
Loop condition is false. Exiting loop
183 {
184 tty = open (ttyname, O_RDWR(0x0001|0x0002));
185 if (tty == -1)
3
Taking false branch
186 {
187 syslog (LOG_ERR3, "%s: %m", ttyname);
188 closelog ();
189 sleep (60);
190 }
191 }
192 while (tty == -1);
193
194 set_speed (tty, linespec);
195
196 print_banner (tty, ttyname);
5
Calling 'print_banner'
197
198 if (login_tty (tty) == -1)
199 syslog (LOG_ERR3, "cannot set controlling terminal to %s: %m", ttyname);
200
201 asprintf (&arg, "TERM=%s", tt ? tt->ty_type : "unknown");
202
203 if (tt && strcmp (tt->ty_type, "dialup") == 0)
204 /* Dialup lines time out (which is login's default). */
205 execl (_PATH_LOGIN"/bin/login", "login", "-e", arg, NULL((void*)0));
206 else
207 /* Hardwired lines don't. */
208 execl (_PATH_LOGIN"/bin/login", "login", "-e", arg, "-aNOAUTH_TIMEOUT", NULL((void*)0));
209
210 syslog (LOG_ERR3, "%s: %m", _PATH_LOGIN"/bin/login");
211
212 return 1;
213}