Bug 54970 - emulators/linux_base Port Makefile "dangerous" for jails
Summary: emulators/linux_base Port Makefile "dangerous" for jails
Status: Closed FIXED
Alias: None
Product: Ports & Packages
Classification: Unclassified
Component: Individual Port(s) (show other bugs)
Version: Latest
Hardware: Any Any
: Normal Affects Only Me
Assignee: Trevor Johnson
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2003-07-28 10:00 UTC by stolz
Modified: 2005-11-26 01:06 UTC (History)
0 users

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description stolz 2003-07-28 10:00:20 UTC
The linux_base-port unconditionally unlinks the dev/null special device in
/compat/linux before it tries to create a new one with 'mknod'. If you are
doing this in a jail, you will not be able to create a new special device
for dev/null inside the jail without manual intervention of the admin of the
host providing the jail!

This especially means that it is dangerous to try to upgrade linux_base port
because you will have an incomplete installation or even none at all until the
admin provides you with a new dev/null from outside the jail.

Luckily, my hoster doesn't charge for this and is rather quick in responding to
such queries, but for others, this might cause maintenance nightmares and even
incur additional costs.

Fix: 

Several solutions come to mind.

1) Detect if running in jail and prompt a warning or skip the
  rm/mknod part, maybe check if the existing special device is usable.
  I'm not sure if it currently is possible to detect if you're running
  inside a jail (apart from some failing syscalls, that is).

2) Mark this port INTERACTIVE, prompt a warning and require a
    confirmation.

3) Don't remove the existing special device at all, but only
    create it when installing it for the first time.
How-To-Repeat: Inside a jail, try installing or upgrading linux_base. It will fail at the
point of invoking ${MKNOD}.
Comment 1 Trevor Johnson freebsd_committer freebsd_triage 2004-02-07 02:46:38 UTC
State Changed
From-To: open->patched

A patch was applied to the linux_base-7.1 port.  I'll look into 
doing something for the other linux_base ports. 


Comment 2 Trevor Johnson freebsd_committer freebsd_triage 2004-02-07 02:46:38 UTC
Responsible Changed
From-To: freebsd-ports-bugs->trevor

I'll take this one.
Comment 3 Alex Popa 2004-02-07 20:52:13 UTC
Version 1.84 of the Makefile does not act normally.  By this I mean that
in a non-jailed environment, when installing linux_base for the first
time, I still get prompted to run those commands in the jail.

The problem seems to arise from the non-usual interaction of the
following pieces of code in the Makefile:

> # Make sure we have a /dev/null in the chrooted environment.
> .if !defined(WITH_JAIL)
> 	@${MKDIR} ${LINUXBASE}/dev
> 	@${RM} -f ${LINUXBASE}/dev/null
> 	@mknod ${LINUXBASE}/dev/null c 2 2
> 	@${CHMOD} 666 ${LINUXBASE}/dev/null
> .endif
> .if !defined(BATCH) && !exists(${LINUXBASE}/dev/null)
> 	@${ECHO_MSG} ""
> 	@${ECHO_MSG} "You need to create the null device in your jailed Linux environment. Run this"
> 	@${ECHO_MSG} "outside the jail, then press enter:"
> 	@${ECHO_MSG} ""
> 	@${ECHO_MSG} "mkdir -m 0755 -p <Jail root dir>/dev"
> 	@${ECHO_MSG} "rm -f <Jail root dir>${LINUXBASE}/dev/null"
> 	@${ECHO_MSG} "mknod <Jail root dir>${LINUXBASE}/dev/null c 2 2"
> 	@${ECHO_MSG} "chmod 666 <Jail root dir>${LINUXBASE}/dev/null"
> 	@${ECHO_MSG} ""
> 	@${SH} -c "read line"
> .endif

It would seem normal that if WITH_JAIL is not defined, the part in the
first if would run and create the ${LINUXBASE}/dev/null file.

After that, it would seem normal that the next if will NOT execute,
since ${LINUXBASE}/dev/null just got created, and the condition includes
"!exists(${LINUXBASE}/dev/null)".  BUT the part in the second if DOES
get executed.

The problem arises from the fact that ".if" is not a run-time condition,
but rather a preprocessor condition.  So, if the null file does not
exist *at the moment the Makefile is read and preprocessed*, the second
if WILL have a true condition, and its lines will get included in the
code to be run.

Judging from the conditions and the commands in the first if, it seems
the second if was intended to run only if the first didn't, so I would
apply this patch to said Makefile:

--- Makefile.orig	Sat Feb  7 22:45:44 2004
+++ Makefile	Sat Feb  7 22:45:57 2004
@@ -139,8 +139,7 @@
 	@${RM} -f ${LINUXBASE}/dev/null
 	@mknod ${LINUXBASE}/dev/null c 2 2
 	@${CHMOD} 666 ${LINUXBASE}/dev/null
-.endif
-.if !defined(BATCH) && !exists(${LINUXBASE}/dev/null)
+.elif !defined(BATCH) && !exists(${LINUXBASE}/dev/null)
 	@${ECHO_MSG} ""
 	@${ECHO_MSG} "You need to create the null device in your jailed Linux environment. Run this"
 	@${ECHO_MSG} "outside the jail, then press enter:"

With this patch applied, installing on a clean system with no jail works
as expected, with no "confirmation" waits.


Alex

------------+-------------------------------------------------------
Alex Popa,  |  "Computer science is no more about computers than
razor@ldc.ro|     astronomy is about telescopes" -- E. W. Dijkstra
------------+-------------------------------------------------------
Comment 4 Pav Lucistnik freebsd_committer freebsd_triage 2005-11-26 01:05:50 UTC
State Changed
From-To: patched->closed

This seems to be fixed in existing linux_base port