1 /* This file contains some utility routines for MM.
2 *
3 * The entry points are:
4 * allowed: see if an access is permitted
5 * no_sys: this routine is called for invalid system call numbers
6 * panic: MM has run aground of a fatal error and cannot continue
7 * tell_fs: interface to FS
8 */
9
10 #include "mm.h"
11 #include <sys/stat.h>
12 #include <minix/callnr.h>
13 #include <minix/com.h>
14 #include <fcntl.h>
15 #include <signal.h> /* needed only because mproc.h needs it */
16 #include "mproc.h"
17
18 /*===========================================================================*
19 * allowed *
20 *===========================================================================*/
21 PUBLIC int allowed(name_buf, s_buf, mask)
22 char *name_buf; /* pointer to file name to be EXECed */
23 struct stat *s_buf; /* buffer for doing and returning stat struct*/
24 int mask; /* R_BIT, W_BIT, or X_BIT */
25 {
26 /* Check to see if file can be accessed. Return EACCES or ENOENT if the access
27 * is prohibited. If it is legal open the file and return a file descriptor.
28 */
29
30 int fd;
31 int save_errno;
32
33 /* Use the fact that mask for access() is the same as the permissions mask.
34 * E.g., X_BIT in <minix/const.h> is the same as X_OK in <unistd.h> and
35 * S_IXOTH in <sys/stat.h>. tell_fs(DO_CHDIR, ...) has set MM's real ids
36 * to the user's effective ids, so access() works right for setuid programs.
37 */
38 if (access(name_buf, mask) < 0) return(-errno);
39
40 /* The file is accessible but might not be readable. Make it readable. */
41 tell_fs(SETUID, MM_PROC_NR, (int) SUPER_USER, (int) SUPER_USER);
42
43 /* Open the file and fstat it. Restore the ids early to handle errors. */
44 fd = open(name_buf, O_RDONLY);
45 save_errno = errno; /* open might fail, e.g. from ENFILE */
46 tell_fs(SETUID, MM_PROC_NR, (int) mp->mp_effuid, (int) mp->mp_effuid);
47 if (fd < 0) return(-save_errno);
48 if (fstat(fd, s_buf) < 0) panic("allowed: fstat failed", NO_NUM);
49
50 /* Only regular files can be executed. */
51 if (mask == X_BIT && (s_buf->st_mode & I_TYPE) != I_REGULAR) {
52 close(fd);
53 return(EACCES);
54 }
55 return(fd);
56 }
57
58
59 /*===========================================================================*
60 * no_sys *
61 *===========================================================================*/
62 PUBLIC int no_sys()
63 {
64 /* A system call number not implemented by MM has been requested. */
65
66 return(EINVAL);
67 }
68
69
70 /*===========================================================================*
71 * panic *
72 *===========================================================================*/
73 PUBLIC void panic(format, num)
74 char *format; /* format string */
75 int num; /* number to go with format string */
76 {
77 /* Something awful has happened. Panics are caused when an internal
78 * inconsistency is detected, e.g., a programming error or illegal value of a
79 * defined constant.
80 */
81
82 printf("Memory manager panic: %s ", format);
83 if (num != NO_NUM) printf("%d",num);
84 printf("\n");
85 tell_fs(SYNC, 0, 0, 0); /* flush the cache to the disk */
86 sys_abort(RBT_PANIC);
87 }
88
89
90 /*===========================================================================*
91 * tell_fs *
92 *===========================================================================*/
93 PUBLIC void tell_fs(what, p1, p2, p3)
94 int what, p1, p2, p3;
95 {
96 /* This routine is only used by MM to inform FS of certain events:
97 * tell_fs(CHDIR, slot, dir, 0)
98 * tell_fs(EXEC, proc, 0, 0)
99 * tell_fs(EXIT, proc, 0, 0)
100 * tell_fs(FORK, parent, child, pid)
101 * tell_fs(SETGID, proc, realgid, effgid)
102 * tell_fs(SETSID, proc, 0, 0)
103 * tell_fs(SETUID, proc, realuid, effuid)
104 * tell_fs(SYNC, 0, 0, 0)
105 * tell_fs(UNPAUSE, proc, signr, 0)
106 */
107
108 message m;
109
110 m.m1_i1 = p1;
111 m.m1_i2 = p2;
112 m.m1_i3 = p3;
113 _taskcall(FS_PROC_NR, what, &m);
114 }
115
This page was automatically generated by the
LXR engine.
Visit the LXR main site for more
information.