clsync
Loading...
Searching...
No Matches
malloc.c
Go to the documentation of this file.
1/*
2 clsync - file tree sync utility based on inotify
3
4 Copyright (C) 2013 Dmitry Yu Okunev <dyokunev@ut.mephi.ru> 0x8E30679C
5
6 This program is free software: you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation, either version 3 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20#include "macros.h"
21
22#include <stdlib.h>
23#include <string.h>
24#ifdef CAPABILITIES_SUPPORT
25# include <unistd.h>
26# include <sys/mman.h>
27# ifdef SECCOMP_SUPPORT
28# include <sys/stat.h>
29# include <fcntl.h>
30# endif
31#endif
32
33#include <sys/ipc.h> // shmget()
34#include <sys/shm.h> // shmget()
35
36#include "malloc.h"
37#include "error.h"
38#include "configuration.h"
39
40#ifdef CAPABILITIES_SUPPORT
41long pagesize;
42# ifdef SECCOMP_SUPPORT
43int devzero_fd;
44# endif
45#endif
46
47void *xmalloc ( size_t size )
48{
49 debug ( 20, "(%li)", size );
50#ifdef PARANOID
51 size++; // Just in case
52#endif
53 void *ret = malloc ( size );
54
55 if ( unlikely(ret == NULL) )
56 critical ( "(%li): Cannot allocate memory.", size );
57
58#ifdef PARANOID
59 memset ( ret, 0, size );
60#endif
61 return ret;
62}
63
64void *xcalloc ( size_t nmemb, size_t size )
65{
66 debug ( 20, "(%li, %li)", nmemb, size );
67#ifdef PARANOID
68 nmemb++; // Just in case
69 size++; // Just in case
70#endif
71 void *ret = calloc ( nmemb, size );
72
73 if ( unlikely(ret == NULL) )
74 critical ( "(%li): Cannot allocate memory.", size );
75
76// memset(ret, 0, nmemb*size); // Just in case
77 return ret;
78}
79
80void *xrealloc ( void *oldptr, size_t size )
81{
82 debug ( 20, "(%p, %li)", oldptr, size );
83#ifdef PARANOID
84 size++; // Just in case
85#endif
86 void *ret = realloc ( oldptr, size );
87
88 if ( unlikely(ret == NULL) )
89 critical ( "(%p, %li): Cannot reallocate memory.", oldptr, size );
90
91 return ret;
92}
93
94char *xstrncpy ( char *dest, const char *src, size_t n )
95{
96 char *ret = strncpy ( dest, src, n - 1 );
97 if ( likely(n > 0) )
98 dest[n-1] = 0;
99 else
100 dest[0] = 0;
101
102 return ret;
103}
104
105#ifdef CAPABILITIES_SUPPORT
106void *malloc_align ( size_t size )
107{
108 size_t total_size;
109 void *ret = NULL;
110 debug ( 20, "(%li)", size );
111# ifdef PARANOID
112 size++; // Just in case
113# endif
114 total_size = size;
115 // Rounding total_size up to a number of times pagesize
116 total_size += pagesize - 1;
117 total_size /= pagesize;
118 total_size *= pagesize;
119
120 if ( unlikely ( posix_memalign ( &ret, pagesize, total_size ) ) )
121 critical ( "(%li): Cannot allocate memory.", size );
122
123# ifdef PARANOID
124
125 if ( unlikely ( ret == NULL ))
126 critical ( "(%li): ptr == NULL.", size );
127
128# endif
129// memset(ret, 0, nmemb*size); // Just in case
130 return ret;
131}
132
133void *calloc_align ( size_t nmemb, size_t size )
134{
135 size_t total_size;
136 void *ret;
137 debug ( 20, "(%li, %li)", nmemb, size );
138# ifdef PARANOID
139 nmemb++; // Just in case
140 size++; // Just in case
141# endif
142 total_size = nmemb * size;
143 ret = malloc_align ( total_size );
144 memset ( ret, 0, total_size );
145 return ret;
146}
147
148char *strdup_protect ( const char *src, int prot )
149{
150 size_t len = strlen ( src ) + 1;
151 char *dst = malloc_align ( len );
152 strcpy ( dst, src );
153
154 if ( unlikely ( mprotect ( dst, len, prot ) ) )
155 critical ( "(%p, 0x%o): Got error from mprotect(%p, %lu, 0x%o)", src, prot, dst, len, prot );
156
157 return dst;
158}
159
160# ifdef SECCOMP_SUPPORT
161int is_protected ( void *addr )
162{
163 char *_addr = addr, t;
164 int is_protected;
165 t = *_addr;
166 is_protected = ( read ( devzero_fd, addr, 1 ) == -1 );
167
168 if ( !is_protected )
169 *_addr = t;
170
171 return is_protected;
172}
173# endif
174
175#endif
176
178{
179#ifdef CAPABILITIES_SUPPORT
180 pagesize = sysconf ( _SC_PAGE_SIZE );
181
182 if ( unlikely ( pagesize == -1 ) )
183 critical ( "Got error from sysconf(_SC_PAGE_SIZE)" );
184
185# ifdef SECCOMP_SUPPORT
186 devzero_fd = open ( DEVZERO, O_RDONLY );
187
188 if ( unlikely ( devzero_fd == -1 ) )
189 critical ( "Got error while open(\""DEVZERO"\", O_RDONLY)" );
190
191# endif
192#endif
193 return 0;
194}
195
196void *shm_malloc_try ( size_t size )
197{
198 void *ret;
199#ifdef PARANOID
200 size++;
201#endif
202 int privileged_shmid = shmget ( 0, size, IPC_PRIVATE | IPC_CREAT | 0600 );
203 struct shmid_ds shmid_ds;
204
205 if ( unlikely ( privileged_shmid == -1 ) ) return NULL;
206
207 ret = shmat ( privileged_shmid, NULL, 0 );
208
209 if ( unlikely ( ( long ) ret == -1 ) ) return NULL;
210
211 debug ( 15, "ret == %p", ret );
212 // Forbidding access for others to the pointer
213 shmctl ( privileged_shmid, IPC_STAT, &shmid_ds );
214 shmid_ds.shm_perm.mode = 0;
215 shmctl ( privileged_shmid, IPC_SET, &shmid_ds );
216 // Checking that nobody else attached to the shared memory before access forbidding
217 shmctl ( privileged_shmid, IPC_STAT, &shmid_ds );
218
219 if ( unlikely ( shmid_ds.shm_lpid != shmid_ds.shm_cpid ) ) {
220 error ( "A process (pid %u) attached to my shared memory. It's a security problem. Emergency exit." );
221 shmdt ( ret );
222 return NULL;
223 }
224
225 return ret;
226}
227
228void *shm_malloc ( size_t size )
229{
230 void *ret;
231 ret = shm_malloc_try ( size );
232 critical_on ( ret == NULL );
233 return ret;
234}
235
236void *shm_calloc ( size_t nmemb, size_t size )
237{
238 void *ret;
239 size_t total_size;
240#ifdef PARANOID
241 nmemb++;
242 size++;
243#endif
244 total_size = nmemb * size;
245 ret = shm_malloc ( total_size );
246 critical_on ( ret == NULL );
247 memset ( ret, 0, total_size );
248 return ret;
249}
250
251void shm_free ( void *ptr )
252{
253 debug ( 25, "(%p)", ptr );
254 shmdt ( ptr );
255}
256
#define DEVZERO
#define critical(...)
Definition error.h:32
#define error(...)
Definition error.h:36
#define debug(debug_level,...)
Definition error.h:50
#define critical_on(cond)
Definition error.h:33
#define likely(x)
Definition macros.h:26
#define unlikely(x)
Definition macros.h:29
int memory_init()
Definition malloc.c:177
void shm_free(void *ptr)
Definition malloc.c:251
void * shm_malloc(size_t size)
Definition malloc.c:228
void * shm_malloc_try(size_t size)
Definition malloc.c:196
void * shm_calloc(size_t nmemb, size_t size)
Definition malloc.c:236
char * xstrncpy(char *dest, const char *src, size_t n)
Definition malloc.c:94