@@ -1275,6 +1275,53 @@ static void check_unsafe_exec(struct linux_binprm *bprm)
12751275 spin_unlock (& p -> fs -> lock );
12761276}
12771277
1278+ static void bprm_fill_uid (struct linux_binprm * bprm )
1279+ {
1280+ struct inode * inode ;
1281+ unsigned int mode ;
1282+ kuid_t uid ;
1283+ kgid_t gid ;
1284+
1285+ /* clear any previous set[ug]id data from a previous binary */
1286+ bprm -> cred -> euid = current_euid ();
1287+ bprm -> cred -> egid = current_egid ();
1288+
1289+ if (bprm -> file -> f_path .mnt -> mnt_flags & MNT_NOSUID )
1290+ return ;
1291+
1292+ if (task_no_new_privs (current ))
1293+ return ;
1294+
1295+ inode = file_inode (bprm -> file );
1296+ mode = READ_ONCE (inode -> i_mode );
1297+ if (!(mode & (S_ISUID |S_ISGID )))
1298+ return ;
1299+
1300+ /* Be careful if suid/sgid is set */
1301+ mutex_lock (& inode -> i_mutex );
1302+
1303+ /* reload atomically mode/uid/gid now that lock held */
1304+ mode = inode -> i_mode ;
1305+ uid = inode -> i_uid ;
1306+ gid = inode -> i_gid ;
1307+ mutex_unlock (& inode -> i_mutex );
1308+
1309+ /* We ignore suid/sgid if there are no mappings for them in the ns */
1310+ if (!kuid_has_mapping (bprm -> cred -> user_ns , uid ) ||
1311+ !kgid_has_mapping (bprm -> cred -> user_ns , gid ))
1312+ return ;
1313+
1314+ if (mode & S_ISUID ) {
1315+ bprm -> per_clear |= PER_CLEAR_ON_SETID ;
1316+ bprm -> cred -> euid = uid ;
1317+ }
1318+
1319+ if ((mode & (S_ISGID | S_IXGRP )) == (S_ISGID | S_IXGRP )) {
1320+ bprm -> per_clear |= PER_CLEAR_ON_SETID ;
1321+ bprm -> cred -> egid = gid ;
1322+ }
1323+ }
1324+
12781325/*
12791326 * Fill the binprm structure from the inode.
12801327 * Check permissions, then read the first 128 (BINPRM_BUF_SIZE) bytes
@@ -1283,36 +1330,9 @@ static void check_unsafe_exec(struct linux_binprm *bprm)
12831330 */
12841331int prepare_binprm (struct linux_binprm * bprm )
12851332{
1286- struct inode * inode = file_inode (bprm -> file );
1287- umode_t mode = inode -> i_mode ;
12881333 int retval ;
12891334
1290-
1291- /* clear any previous set[ug]id data from a previous binary */
1292- bprm -> cred -> euid = current_euid ();
1293- bprm -> cred -> egid = current_egid ();
1294-
1295- if (!(bprm -> file -> f_path .mnt -> mnt_flags & MNT_NOSUID ) &&
1296- !task_no_new_privs (current ) &&
1297- kuid_has_mapping (bprm -> cred -> user_ns , inode -> i_uid ) &&
1298- kgid_has_mapping (bprm -> cred -> user_ns , inode -> i_gid )) {
1299- /* Set-uid? */
1300- if (mode & S_ISUID ) {
1301- bprm -> per_clear |= PER_CLEAR_ON_SETID ;
1302- bprm -> cred -> euid = inode -> i_uid ;
1303- }
1304-
1305- /* Set-gid? */
1306- /*
1307- * If setgid is set but no group execute bit then this
1308- * is a candidate for mandatory locking, not a setgid
1309- * executable.
1310- */
1311- if ((mode & (S_ISGID | S_IXGRP )) == (S_ISGID | S_IXGRP )) {
1312- bprm -> per_clear |= PER_CLEAR_ON_SETID ;
1313- bprm -> cred -> egid = inode -> i_gid ;
1314- }
1315- }
1335+ bprm_fill_uid (bprm );
13161336
13171337 /* fill in binprm security blob */
13181338 retval = security_bprm_set_creds (bprm );
0 commit comments