Bug Summary

File:obj-scan-build/daemons/../../daemons/getty.c
Location:line 124, 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 "\r\n\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 for (s = load_banner (); *s; s++)
7
Calling 'load_banner'
15
Returned allocated memory
16
Loop condition is true. Entering loop body
119 {
120 for (t = s; *t && *t != '\\'; t++) /* nomnomnom */;
17
Loop condition is false. Execution continues on line 122
121
122 write (fd, s, t - s);
123 if (! *t)
18
Taking true branch
124 return;
19
Memory is never released; potential leak of memory pointed to by 't'
125
126 switch (*(t + 1))
127 {
128 case '\\':
129 expansion = "\\";
130 break;
131 case 's':
132 expansion = u.sysname;
133 break;
134 case 'r':
135 expansion = u.release;
136 break;
137 case 'n':
138 expansion = localhost () ?: "?";
139 break;
140 case 'l':
141 expansion = basename (ttyname);
142 break;
143 default:
144 expansion = "?";
145 }
146 write (fd, expansion, strlen (expansion));
147
148 s = t + 1;
149 }
150}
151
152int
153main (int argc, char **argv)
154{
155 char *linespec, *ttyname;
156 int tty;
157 struct ttyent *tt;
158 char *arg;
159
160 openlog ("getty", LOG_ODELAY0x04|LOG_CONS0x02|LOG_PID0x01, LOG_AUTH(4<<3));
161
162 /* Nothing to do .... */
163 if (argc != 3)
1
Assuming 'argc' is equal to 3
2
Taking false branch
164 {
165 syslog (LOG_ERR3, "Bad syntax");
166 closelog ();
167 exit (1);
168 }
169
170 /* Don't do anything with this for now. */
171 linespec = argv[1];
172
173 tt = getttynam (argv[2]);
174 asprintf (&ttyname, "%s/%s", _PATH_DEV"/dev/", argv[2]);
175
176 chown (ttyname, 0, 0);
177 chmod (ttyname, 0600);
178 revoke (ttyname);
179 sleep (2); /* leave DTR down for a bit */
180
181 do
4
Loop condition is false. Exiting loop
182 {
183 tty = open (ttyname, O_RDWR(0x0001|0x0002));
184 if (tty == -1)
3
Taking false branch
185 {
186 syslog (LOG_ERR3, "%s: %m", ttyname);
187 closelog ();
188 sleep (60);
189 }
190 }
191 while (tty == -1);
192
193 set_speed (tty, linespec);
194
195 print_banner (tty, ttyname);
5
Calling 'print_banner'
196
197 if (login_tty (tty) == -1)
198 syslog (LOG_ERR3, "cannot set controlling terminal to %s: %m", ttyname);
199
200 asprintf (&arg, "TERM=%s", tt ? tt->ty_type : "unknown");
201
202 if (tt && strcmp (tt->ty_type, "dialup") == 0)
203 /* Dialup lines time out (which is login's default). */
204 execl (_PATH_LOGIN"/bin/login", "login", "-e", arg, NULL((void*)0));
205 else
206 /* Hardwired lines don't. */
207 execl (_PATH_LOGIN"/bin/login", "login", "-e", arg, "-aNOAUTH_TIMEOUT", NULL((void*)0));
208
209 syslog (LOG_ERR3, "%s: %m", _PATH_LOGIN"/bin/login");
210
211 return 1;
212}